2. Core Concepts
Every noun you'll meet in the portal, defined once. The pattern throughout is term → plain-English analogy → precise technical definition, because the fastest way to get lost in Azure Storage is to half-know what a "kind" is.
[Image Prompt: 2D minimalistic labelled hierarchy diagram showing an Azure subscription containing a resource group, containing a storage account, containing a blob service, containing containers, containing blobs with snapshots and versions, flat design, clean vector art style, white background]
The hierarchy
Everything scopes through this chain, and each level does a different job:
subscription
└── resource group
└── storage account ← the ARM resource: name, region, SKU, firewall, keys, redundancy
└── blob service ← service-level settings: soft delete, versioning, CORS, lifecycle
└── container ← a flat namespace + the RBAC/public-access boundary
└── blob ← the object itself
├── snapshot ← a read-only point-in-time copy you asked for
└── version ← a read-only copy the service made automatically
Resource groups and subscriptions are platform concepts — see the scope hierarchy rather than re-reading them here.
The primitives
| Term | Analogy | Technical definition |
|---|---|---|
| Storage account | The drive you rent, with its own lock, postcode, and speed rating | A regional Microsoft.Storage/storageAccounts ARM resource with a globally unique DNS name (3–24 chars, lowercase letters and digits only). It owns the four service endpoints, the redundancy setting, the network rules and firewall, the encryption configuration, the access keys, and most of the scale limits |
| Container | A named folder at the root of that drive | A flat namespace for blobs within one account, and the finest-grained scope at which you can assign a data-plane RBAC role or set public access. Names are lowercase, 3–63 chars |
| Blob | A file | An immutable-by-default sequence of bytes stored under a key, addressed at https://<account>.blob.core.windows.net/<container>/<key>. The key may contain /, which the portal renders as folders, but the namespace is flat unless HNS is on |
| Block blob | A file assembled from numbered chunks | The default type. Written as up to ~50,000 blocks that you stage and then commit atomically with Put Block List. This is what makes resumable, parallel uploads of very large files work |
| Append blob | A logbook you can only write at the end of | Optimised for append-only writes (Append Block). Used by logging frameworks and Azure diagnostic pipelines. Cannot be updated or reordered |
| Page blob | A raw disk | 512-byte-aligned pages supporting random reads and writes. The storage substrate behind unmanaged VHDs and, historically, managed disks |
| Blob type | — | Chosen at first write and immutable — you cannot convert a block blob to an append blob in place, only copy to a new blob |
| Access tier | How far back in the warehouse the box is stored | A per-blob (or account-default) setting — Hot / Cool / Cold / Archive — trading storage price against transaction price, retrieval cost, and access latency |
| Redundancy | How many copies, and how far apart | An account-level setting — LRS / ZRS / GRS / GZRS, plus read-access RA- variants — governing how many replicas exist and across what failure domains |
| Kind | The model of drive | StorageV2 (general purpose v2 — the default and correct answer), BlockBlobStorage (premium block blob only), plus the legacy Storage (v1), BlobStorage, and FileStorage |
| Performance tier | Spinning rust vs. flash | Standard (HDD-backed, all four access tiers, cheapest per GB) or Premium (SSD-backed, single-digit-ms latency, high transaction rates, no Archive tier, higher per-GB cost) |
| Snapshot | A photocopy you filed yourself | A read-only, point-in-time copy of a blob at a timestamped URL. You create them explicitly; you pay only for the differing blocks |
| Version | A photocopy the service filed for you | With blob versioning enabled, every overwrite or delete automatically creates a versioned copy with its own version ID. Powerful, and a silent cost multiplier without a lifecycle rule to expire them |
| Lease | Taking the key off the hook | An explicit, time-bound (15–60 s, or infinite) exclusive lock on a blob or container. This is what Terraform's azurerm backend uses for state locking |
| Metadata | Sticky notes on the box | Arbitrary user-defined name:value pairs on a blob or container, plus system properties like Content-Type and Cache-Control. Not indexed — see blob index tags below |
| Blob index tags | Sticky notes that are actually searchable | Key-value tags on a blob that the service does index, queryable with Find Blobs by Tags. A limited number per blob ⚠️ verify current maximum against current Azure docs. The nearest thing to a query, and still not a database |
| Immutability policy | A padlock with a legal document attached | A time-based retention or legal-hold policy at the container or version level that prevents deletion or modification — WORM storage for compliance regimes |
| SAS (shared access signature) | A ticket with an expiry, a seat number, and a signature | A signed URL query string granting scoped, time-limited access to a resource without sharing a credential |
| Storage access key | The master key to the whole building | One of two root credentials on the account granting full data-plane access, unscoped and non-expiring. Treat its existence as a liability |
| Hierarchical namespace (HNS) | Turning the flat drive into a real filesystem | The ADLS Gen2 flag that makes directories real objects, makes rename atomic, and adds POSIX-style ACLs and a second endpoint. Set at creation, irreversible |
The SKU axis, in detail
Azure services are defined by their SKU more than by anything else, and Blob Storage has three orthogonal axes people routinely conflate.
Axis 1 — performance tier (account level, set at creation)
| Standard | Premium block blob | |
|---|---|---|
| Media | HDD-backed | SSD-backed |
| Latency | Tens of ms, variable | Consistent single-digit ms |
| Transaction rate | Good | Very high — this is the real reason to pick it |
| Access tiers available | Hot, Cool, Cold, Archive | None — premium is its own tier, no Archive |
| Redundancy options | All | LRS and ZRS only ⚠️ verify current availability |
| Cost shape | Cheap per GB, cheap per op | Expensive per GB, cheap per op |
| Kind | StorageV2 |
BlockBlobStorage |
The trap: people reach for Premium for "performance" when their problem is throughput on large sequential reads, which Standard handles fine. Premium's win is small objects at high request rates with tight latency — interactive workloads, not data lakes. If you can't state your P99 latency requirement, you don't need Premium.
Axis 2 — redundancy (account level, mostly changeable in place)
| Setting | Copies | Protects against | Notes |
|---|---|---|---|
| LRS | 3, one datacentre | Disk, node, rack failure | Cheapest. A datacentre loss is a data loss |
| ZRS | 3, across availability zones in one region | Loss of a whole zone | The sensible default for production in any region that offers zones |
| GRS | 3 local + 3 in the paired region | Regional loss | Async replication → a recovery point objective greater than zero; the secondary is not readable unless you fail over |
| GZRS | ZRS primary + 3 in the paired region | Zone and region loss | The premium option for critical data |
| RA-GRS / RA-GZRS | Same, plus a readable secondary endpoint | The above, plus read-only DR and read scale-out | Adds -secondary endpoints; reads there may lag the primary |
Three things to internalise:
- Geo-replication is asynchronous. There is a "last sync time" metric, and everything written after it is lost in an unplanned failover. GRS is a disaster-recovery feature, not a zero-RPO one.
- Failover is account-wide and consequential. Customer-initiated failover promotes the secondary and (historically) leaves the account as LRS afterwards, which you must then re-upgrade. Practise it.
- Changing redundancy is not always a live conversion. Some transitions (LRS→ZRS in particular) may require a conversion process or a manual migration depending on region and account state ⚠️ verify the current supported conversion matrix against current Azure docs.
Axis 3 — access tier (per blob, or an account default)
| Tier | Storage cost | Transaction cost | Retrieval | Minimum retention | First-byte latency |
|---|---|---|---|---|---|
| Hot | Highest | Lowest | None | None | Milliseconds |
| Cool | Lower | Higher | Per-GB charge | ~30 days ⚠️ verify | Milliseconds |
| Cold | Lower still | Higher still | Per-GB charge | ~90 days ⚠️ verify | Milliseconds |
| Archive | Lowest by far | Highest | Significant per-GB charge | ~180 days ⚠️ verify | Hours — requires rehydration |
The arithmetic that matters: moving data to Cool halves the storage rate and roughly doubles-plus the transaction rate. Data read even moderately often costs more in Cool than in Hot. Tier on measured access frequency, never on age alone — and if you tier on age, use a lifecycle rule with an honest threshold rather than a guess.
Archive is offline. An archived blob cannot be read at all. You either rehydrate it in place (hours; standard or high priority) or copy it to a new blob in an online tier. Any design where a user request could hit an archived blob is broken.
Early deletion is a real charge. Delete, overwrite, or move a blob out of Cool/Cold/Archive before its minimum retention period elapses and you're billed pro-rata for the remainder. A lifecycle rule that moves data to Archive at 30 days and deletes it at 90 days is quietly paying an early-deletion penalty on every object.
Authentication — two worlds, and which one to live in
This is the highest-value section on the page, because the failure mode is a security incident rather than an error message.
| Mechanism | What it is | When it's right |
|---|---|---|
| Account key | One of two root credentials, full access, no expiry, no scope | Never, in a system you care about. Its existence is the problem |
| Service SAS / account SAS | A URL signed with the account key, scoped to a resource, permission set, and expiry | Legacy interop. Inherits the key's blast radius — revoking means rotating the key |
| Stored access policy | A named container-level policy a service SAS references | The one way to revoke an issued service SAS without rotating the key. Use it if you must use service SAS |
| User-delegation SAS | A SAS signed with a key obtained from Microsoft Entra ID, not the account key | ✅ The right answer for time-limited links. Bounded by the signing identity's RBAC permissions and by the delegation key's own expiry, and revocable by removing the role assignment |
| Entra ID + Azure RBAC | Bearer-token auth against Entra, authorised by data-plane role assignments | ✅ The right answer for service-to-service. Combine with a managed identity and there is no credential anywhere |
The roles you actually need (data plane, not control plane):
Storage Blob Data Reader— read and list blobs.Storage Blob Data Contributor— read, write, delete blobs.Storage Blob Data Owner— the above plus POSIX ACL management on HNS accounts.Storage Blob Delegator— required in addition to the above to mint a user-delegation SAS.
And the ones that do not grant data access: Owner, Contributor, Storage Account Contributor.
They manage the resource. They can, however, read the account keys — which is how a Contributor
effectively gets data access anyway, and precisely why allowSharedKeyAccess = false matters. See
Architecture for the full control-plane/data-plane story.
The hierarchical namespace (ADLS Gen2)
Turning on HNS changes the account from a flat key-value store into something with real directories.
What you gain:
- Atomic directory rename and delete. Renaming
raw/2026-07/is one metadata operation instead of copying and deleting every object beneath it. For analytics, where writing to a temp path and renaming on commit is the standard atomicity trick, this is the whole reason HNS exists. - POSIX-style ACLs on directories and files, layered beneath Azure RBAC — RBAC is evaluated first, and ACLs are checked only if RBAC doesn't already allow the operation.
- Better performance and lower cost for hierarchical access patterns, and native compatibility with the ABFS driver that Databricks, Synapse, and Fabric use.
- A second endpoint,
https://<account>.dfs.core.windows.net, speaking filesystem operations alongside the usual blob endpoint.
What it costs you:
- Irreversible.
is_hns_enabledis set at creation. Changing your mind means creating a new account and copying the data (AzCopy or Data Factory). - Feature lag. Some Blob features arrive on HNS accounts later, or behave differently ⚠️ verify the current HNS feature-support matrix against current Azure docs before depending on one.
- A slightly different mental model — the flat/hierarchical duality means some tools see directories and some see key prefixes for the same data.
The rule: if the account will ever hold a data lake, turn HNS on. If it's serving images to a website, don't. When genuinely unsure, turning it on is the lower-regret choice, because the migration in that direction is the one you can't do later.
Features you should know exist before you need them
| Feature | What it does | The catch |
|---|---|---|
| Soft delete (blob) | Deleted blobs are recoverable for N days | Off by default on older accounts; the retained bytes are billable |
| Soft delete (container) | Recovers a deleted container | Does not protect against a deleted account |
| Versioning | Auto-creates a version on every overwrite/delete | The most common runaway-cost feature. Always pair it with a lifecycle rule expiring old versions |
| Change feed | An ordered, durable, read-only log of all changes to blobs | Extra stored data; useful for audit and incremental ETL |
| Point-in-time restore | Restores a container to an earlier moment | Requires versioning and change feed and soft delete enabled first |
| Lifecycle management | Rules that tier or delete blobs by age, prefix, or index tag | Rules evaluate on a schedule (daily-ish), not instantly |
| Object replication | Async replication of blobs between accounts, by rule | Requires versioning and change feed on the source |
| Static website | Serves a $web container as a website with an index and error document |
No custom domain TLS on its own — front it with Front Door or CDN |
| SFTP support | An SFTP endpoint over the account | Requires HNS; has its own local-user identity model separate from Entra ⚠️ verify current status and limits |
| NFS 3.0 | Mount a container as NFS | Requires HNS; set at creation; incompatible with some other features |
| Immutable storage | Time-based retention and legal holds (WORM) | Once locked, a policy can be extended but not shortened — that's the point, and it will block your terraform destroy |
Next: Architecture →
← Back to the Blob Storage overview · ← Previous: What & Why