Azure Data Lake Storage Gen2 Overview
Azure Data Lake Storage Gen2 (ADLS Gen2) is Blob Storage with a hierarchical namespace enabled. It adds directory semantics, POSIX-compatible ACLs, and performance optimizations that make it the standard storage layer for big data analytics on Azure. This page covers what it is, how it differs from regular Blob Storage, and how to configure it.
What ADLS Gen2 adds to Blob Storage
Standard Azure Blob Storage is a flat namespace: files (blobs) are stored in containers, and “folders” are just a naming convention using forward slashes in blob names. There are no real directories. Moving 10,000 files from one “folder” to another requires copying and deleting each blob individually — an O(n) operation.
ADLS Gen2 introduces a hierarchical namespace — a real directory tree. Directories are first-class objects. Renaming or moving a directory is an atomic metadata operation regardless of how many files it contains — an O(1) operation. This makes ADLS Gen2 suitable for analytics workloads that move, rename, and reorganize data as part of processing pipelines.
The other major addition is POSIX-compatible ACLs. Standard Blob Storage access control is coarse-grained: you assign an Azure RBAC role to a principal and it applies to all blobs in a container or account. ADLS Gen2 ACLs can be applied to individual files and directories, with separate read, write, and execute permissions for owning user, owning group, named users, named groups, and an “other” category. This mirrors the Unix permission model that data engineering teams are familiar with.
Creating an ADLS Gen2 account
Enable the hierarchical namespace at account creation time with the —enable-hierarchical-namespace true flag. The account is otherwise created like any standard storage account.
# Create an ADLS Gen2 storage account
az storage account create \
--resource-group myResourceGroup \
--name myadlsaccount \
--location eastus \
--sku Standard_LRS \
--kind StorageV2 \
--enable-hierarchical-namespace true \
--access-tier Hot
# Verify hierarchical namespace is enabled
az storage account show \
--resource-group myResourceGroup \
--name myadlsaccount \
--query isHnsEnabledChoose the SKU based on your redundancy requirements. Standard_LRS is locally redundant within a single datacenter. For analytics data that is expensive to regenerate, use Standard_ZRS (zone-redundant) or Standard_GRS (geo-redundant). For high-throughput analytics workloads, consider Standard_RAGRS for read access from the secondary region.
Storage hierarchy: containers, directories, and files
ADLS Gen2 uses the same container concept as Blob Storage, but inside a container you have a real directory tree. The typical data lake organization follows a zone pattern:
| Zone | Typical directory path | Purpose |
|---|---|---|
| Raw / Bronze | /raw/source-system/yyyy/mm/dd/ | Unprocessed data as received from source |
| Cleansed / Silver | /cleansed/entity-name/yyyy/mm/dd/ | Validated, deduplicated, schema-enforced |
| Curated / Gold | /curated/domain/dataset-name/ | Business-ready aggregates and feature tables |
Create directories and files using the Azure CLI or the Data Lake Storage SDK:
# Get a connection string or use --account-name with identity
ACCOUNT_KEY=$(az storage account keys list \
--resource-group myResourceGroup \
--account-name myadlsaccount \
--query '[0].value' -o tsv)
# Create the raw container
az storage fs create \
--name raw \
--account-name myadlsaccount \
--account-key $ACCOUNT_KEY
# Create a directory path inside the container
az storage fs directory create \
--file-system raw \
--name "salesdata/2026/03/19" \
--account-name myadlsaccount \
--account-key $ACCOUNT_KEY
# Upload a file to a specific directory
az storage fs file upload \
--source ./sales-20260319.parquet \
--path "salesdata/2026/03/19/sales-20260319.parquet" \
--file-system raw \
--account-name myadlsaccount \
--account-key $ACCOUNT_KEYSetting ACLs with Azure CLI
ADLS Gen2 ACLs use the format user::rwx,group::r-x,other::--- for default POSIX permissions, plus named-user and named-group entries like user:<object-id>:r-x. There are two types of ACL per entry: access ACLs (apply to the current item) and default ACLs (inherited by new child items).
# Set ACL on a directory — give a service principal read+execute on a path
PRINCIPAL_ID="00000000-0000-0000-0000-aabbccddeeff"
az storage fs access set \
--acl "user:${PRINCIPAL_ID}:r-x" \
--path "salesdata/2026/03/19" \
--file-system raw \
--account-name myadlsaccount \
--account-key $ACCOUNT_KEY
# Set a default ACL so new files in a directory inherit permissions
az storage fs access set \
--acl "default:user:${PRINCIPAL_ID}:r-x" \
--path "salesdata" \
--file-system raw \
--account-name myadlsaccount \
--account-key $ACCOUNT_KEY
# Show the current ACL for a path
az storage fs access show \
--path "salesdata/2026/03/19" \
--file-system raw \
--account-name myadlsaccount \
--account-key $ACCOUNT_KEYACLs in ADLS Gen2 work alongside Azure RBAC, not instead of it. A principal needs both an Azure RBAC role (at minimum Storage Blob Data Reader) and the appropriate ACL entry on the specific path. Azure RBAC provides the “gate into the storage account” and ACLs provide the per-directory authorization within it.
Use the Storage Blob Data Contributor Azure RBAC role for service accounts that run pipelines, and apply restrictive ACLs at the directory level to control exactly which zones each pipeline can read from and write to. This prevents a bug in one pipeline from overwriting data owned by a different team.
Performance tier and optimization
ADLS Gen2 supports the same access tiers as Blob Storage: Hot, Cool, Cold, and Archive. For active analytics workloads, Hot is appropriate. Data that is queried weekly or monthly can be on Cool. Historical raw data that is retained for compliance but rarely queried should use Archive (with the understanding that retrieval takes hours).
For high-throughput analytics, use the premium performance tier (Premium block blobs) rather than Standard. Premium ADLS Gen2 uses SSD-backed storage with significantly lower latency and higher IOPS — important for interactive query engines like Azure Synapse Analytics and Azure Databricks when they read large Parquet files.
# Create a premium-tier ADLS Gen2 account (SSD-backed)
az storage account create \
--resource-group myResourceGroup \
--name myadlspremium \
--location eastus \
--sku Premium_LRS \
--kind BlockBlobStorage \
--enable-hierarchical-namespace truePremium storage accounts with hierarchical namespace only support LRS redundancy. If you need geo-redundancy on a premium account, you must implement application-level replication.
Integration with Azure Synapse and Databricks
ADLS Gen2 is the default storage layer for both Azure Synapse Analytics and Azure Databricks. When creating a Synapse workspace, you associate it with an ADLS Gen2 account that becomes the workspace’s primary storage. Notebooks, Spark pools, and SQL pools all read and write to this account.
For Databricks, mount the ADLS Gen2 container using a service principal or managed identity, or use the native ABFS (Azure Blob File System) driver which accesses ADLS Gen2 directly without mounting:
# Databricks: Access ADLS Gen2 with ABFS driver and managed identity
df = spark.read.parquet(
"abfss://raw@myadlsaccount.dfs.core.windows.net/salesdata/2026/"
)The abfss:// protocol (ABFS Secure) is the native driver for ADLS Gen2. It supports directory listing, rename, and delete operations at the directory level — operations that are slow or unsupported with the wasbs:// (Azure Blob File System) driver that works with flat-namespace accounts.
Common mistakes
- Using a flat-namespace Blob account for analytics and expecting directory-level operations to be efficient. Tools like Databricks and Synapse work with flat-namespace accounts, but rename and delete on “folders” require enumerating and operating on every blob individually. A rename of a 50,000-file directory that takes milliseconds on ADLS Gen2 takes minutes on a flat-namespace account. Always use hierarchical namespace for analytics workloads.
- Granting the Storage Blob Data Contributor role at the account level to all pipeline service principals. This gives every pipeline write access to every container in the account — a bug or a compromised pipeline can overwrite any data. Apply the Azure RBAC role at the container level, and further restrict with ACLs at the directory level so each pipeline can only write to its own zone.
- Storing small files without combining them first. Analytics engines read data most efficiently in files of 128 MB to 1 GB. Writing thousands of small files (under 1 MB each) from a streaming pipeline creates a “small files problem” where the overhead of reading file metadata dominates query time. Compact small files into larger ones using Databricks auto-optimize or a scheduled compaction job before making data available for analytics.
Summary
- ADLS Gen2 is Blob Storage with hierarchical namespace enabled — it adds real directories (enabling atomic rename/move), POSIX-style ACLs, and the ABFS driver for analytics engines.
- Enable hierarchical namespace at account creation time; it cannot be added to an existing account without migrating data.
- POSIX ACLs work with Azure RBAC, not instead of it — a principal needs both an RBAC role on the storage account and an ACL entry on the specific directory or file.
- Use the premium BlockBlobStorage tier for low-latency interactive analytics, and compact small files into 128 MB+ Parquet files before running queries on them.
Frequently asked questions
Is Azure Data Lake Storage Gen2 a separate service from Blob Storage?
No. ADLS Gen2 is Azure Blob Storage with the hierarchical namespace feature enabled. The same Storage Account resource is used; you enable the hierarchical namespace at account creation time. This means ADLS Gen2 inherits all Blob Storage features — lifecycle management, tiering, replication, and security — plus the additional directory semantics and POSIX-style ACLs.
Can I enable the hierarchical namespace on an existing Blob Storage account?
No. The hierarchical namespace must be enabled when the storage account is created. There is no in-place migration from a flat-namespace Blob account to an ADLS Gen2 account. If you need to convert existing data, you must create a new ADLS Gen2 account and copy the data using AzCopy or Azure Data Factory.
What is the difference between Blob ACLs and POSIX ACLs in ADLS Gen2?
Standard Blob Storage uses Azure RBAC for access control — you assign roles like Storage Blob Data Reader to identities, and they apply to all blobs in a container. ADLS Gen2 adds POSIX-style ACLs that can be applied to individual files and directories, with named-user, named-group, and other/mask permissions. This allows fine-grained per-directory access for analytics pipelines where different teams own different data zones.