1. What and Why
One sentence: Azure Blob Storage is a regional, managed object-storage service that keeps arbitrarily large sequences of bytes under string keys inside containers, addressable over HTTPS, billed by the gigabyte-month and by the request, with no capacity to provision.
The problem it kills
Storing files is easy until any one of five things becomes true: the files outgrow one disk, the disk must survive a failure, more than one machine must read them, the volume is unpredictable, or someone asks how much of it you'll need next year. Each of those, solved on your own hardware, adds a layer — RAID, then replication, then a NAS or a serving fleet, then a capacity forecast, then a person whose job is that forecast.
Object storage collapses all five into one design decision: give up the filesystem, and get everything else for free. No seeks, no partial writes, no locking, no directory tree, no mount. In exchange you get durability measured in eleven-plus nines, capacity you never provision, a URL for every object, and a bill that goes to nearly zero when the data goes cold.
Think of it as an infinite hard drive you rent by the gigabyte-month, where every file has a URL. That analogy is doing real work: infinite (no capacity planning), rented (you pay for what you keep, not what you might keep), and URL-addressed (the access mechanism is HTTP, not a filesystem call).
[Image Prompt: 2D minimalistic diagram of Azure Blob Storage sitting between upstream data sources such as applications, devices, and pipelines on the left and downstream consumers such as analytics engines, CDNs, and functions on the right, labelled boxes and arrows, flat design, clean vector art style, white background]
Two second-order consequences matter more than the storage itself:
Storage becomes an integration point. Because a blob has a URL and an event, "write a file" becomes a way for two systems to talk without knowing about each other. A device uploads, Event Grid fires, a Function runs, a pipeline picks it up. Half the reference architectures on Azure have Blob Storage in the middle for exactly this reason — see Integrations.
Cold data stops being a liability. On-premises, a seven-year retention policy means seven years of disks you keep spinning and replacing. With access tiers and a lifecycle policy, the same data drifts automatically to Archive at a fraction of the cost, and the decision costs you a YAML rule rather than a purchase order.
What you give up, stated plainly
The trade is real and worth naming before the enthusiasm sets in.
| You give up | Because | What you use instead |
|---|---|---|
| Partial in-place writes | A block blob is replaced, not edited | Page blobs (random write, VHDs), append blobs (log append) |
| Directory semantics | The namespace is flat; / is just a character in the key |
Enable the hierarchical namespace (ADLS Gen2) — but only at creation |
| Rename | Renaming means copy-then-delete across the whole object | Hierarchical namespace makes rename an atomic metadata operation |
| File locking | No leases in the POSIX sense | Blob leases (a coarse, explicit lock you take deliberately) |
| Query by content | There is no index over values | A database, or a metadata index you maintain yourself |
| Low, predictable single-read latency | Every read is an HTTPS round trip through a partition layer | Cache in Redis or a CDN; use Premium block blob if it's a latency problem, not a throughput one |
| Strong cross-object transactions | Consistency is per-blob | Design idempotently; use a database for the transactional part |
Where it sits in the catalogue
Azure sells four things that all sound like "storage", and the choice is nearly always obvious once you name the interface each one speaks.
| Service | The interface | Choose it when | The catch |
|---|---|---|---|
| Blob Storage | HTTPS REST, key → bytes | Data is large, read by key, or read by analytics | Not a filesystem, not queryable |
| Azure Files | SMB / NFS, mounted | An existing application expects a filesystem path | Costs more per GB, lower scale ceiling, per-share throughput limits |
| Managed Disks | Block device, attached to one VM | OS disks, database data files, anything needing block I/O | Single-attach (mostly), billed on provisioned size whether used or not |
| Azure NetApp Files | NFS / SMB, enterprise-grade | Sub-millisecond file workloads — SAP, HPC, EDA | Expensive, provisioned in capacity pools, a deliberate procurement decision |
| Azure Data Lake Storage Gen2 | Both — HTTPS and a filesystem-ish DFS endpoint | Analytics over hierarchical data at object-storage prices | It's a flag on a Blob account, irreversible, and a few Blob features lag behind on HNS accounts |
Two clarifications people find useful:
- ADLS Gen2 is not a separate product. It is a storage account with
isHnsEnabled = true. Same resource provider, same portal blade, same Terraform resource, plus a second endpoint (dfs.core.windows.net) that speaks directory operations. Treat it as a mode, not a migration target. - Queues and Tables live in the same account. A storage account is four services sharing a name, a firewall, a redundancy setting, and — importantly — some of the same account-level limits. Storage Queues are not Service Bus, and Table Storage is not Cosmos DB, though the Cosmos DB Table API is the upgrade path.
The AWS analogue, and where it breaks
Blob Storage is S3. That analogy is good and will carry you a long way: bucket ≈ container, object ≈ blob, storage class ≈ access tier, presigned URL ≈ SAS, S3 Event Notifications ≈ Event Grid, S3 Lifecycle ≈ lifecycle management, Glacier ≈ Archive tier. Five places it breaks, each costing someone a day:
- The storage account has no S3 equivalent. It is a real ARM resource between the subscription and the container, and it owns the redundancy, the firewall, the encryption key, the performance tier, the endpoints, and most of the scale limits. In S3, per-prefix scaling means you rarely think about the bucket; in Azure, the account is the throughput boundary and designing one giant account is a genuine architectural mistake. The account name is also globally unique across all of Azure, 3–24 characters, lowercase alphanumeric only — no hyphens.
- Redundancy is an account property, not a per-object storage class. In S3, One Zone-IA is a class you set per object. In Azure, LRS/ZRS/GRS/GZRS is set on the account and applies to everything in it. The per-object knob (Hot/Cool/Cold/Archive) controls tier only. Getting geo-redundancy for one container and not another means two accounts.
- There are three blob types, chosen at write time and immutable thereafter. Block (the default, for almost everything), append (log-style, append-only), and page (512-byte-aligned random access, what managed disks are built on). S3 has one object type. You cannot convert between them in place.
- Auth has two completely separate mechanisms. Shared keys and SAS tokens (Azure's own thing, no IAM involvement) sit alongside Microsoft Entra ID + Azure RBAC. The account key is a root credential with no scoping and no expiry, and it exists by default — an ownership burden IAM never handed you. The correct posture is to disable shared-key access entirely and use managed identities.
- Consistency and listing differ. Azure has always been strongly consistent for blob reads after
write, and listing is a strongly consistent, lexicographically-ordered, paged scan — S3 only reached
strong read-after-write consistency in 2020, and a lot of S3 folklore about eventual consistency
still floats around. Don't carry that folklore over; do carry over the habit of never treating
Listas cheap.
When NOT to use Blob Storage
The anti-patterns, stated honestly:
- You're using
Listas a query. Listing is a paged, lexicographic scan of a container that may hold billions of objects. If your code lists to find something, you need an index — a database table, a manifest blob, or Azure AI Search. This is the single most common performance failure in the topic. - You mounted it because the app wanted a path. BlobFuse2 and NFS 3.0 work, with caveats around caching, consistency, and file locking that will surface at the worst moment. If the app genuinely needs POSIX semantics, Azure Files is the honest answer.
- Small objects, high request rate. At millions of tiny objects, transaction cost and per-request latency dominate the storage cost entirely. Batch into larger files — this is exactly why parquet exists and why analytics engines hate small files.
- You put it in Archive "to save money" on data you'll read next month. Archive has a minimum retention period with an early-deletion charge, and reading requires a rehydration that takes hours. It's for data you're keeping because a regulator says so, not data you're deprioritising.
- You need a transaction across two blobs. There isn't one. Design so that a partial write is detectable and retryable, or keep the coordinating state in a database.
- One account for the whole company. The account is the throughput and firewall boundary. A shared account means an analytics job's 3 a.m. burst throttles the customer-facing API, and the diagnosis takes a week because the metric that shows it is off by default.
Where the money actually goes
Worth internalising before anything else, because it shapes every later decision:
- Storage — per GB-month, at a rate that drops sharply from Hot → Cool → Cold → Archive.
- Transactions — per 10,000 operations, at a rate that rises in the opposite direction. Cool and Cold data that gets read constantly can cost more than leaving it Hot. This inversion is the whole reason tiering requires a real access-pattern analysis rather than a blanket rule.
- Data retrieval and egress — Cool/Cold/Archive add a per-GB retrieval charge on top of transactions; egress out of Azure is billed separately again.
- Early deletion — deleting or re-tiering Cool, Cold, or Archive data before its minimum retention period bills you for the remainder as though you'd kept it.
- The features you turned on and forgot — versioning, soft delete, change feed, and snapshots all store additional bytes that you pay for at the full rate. Versioning with no lifecycle rule to expire old versions is a bill that grows forever with no visible cause.
The full treatment is in Production; the point here is that Blob Storage has at least five meters, and the cheap-looking tier is the one that turns the transaction meter up.
Next: Core Concepts →