Azure Blob Storage looks absurdly cheap - archive tier is under $0.002 per GB per month, which is $2 to store a terabyte for a year - and that number is what gets people into trouble. Storage capacity is rarely the largest line on a blob storage bill. Transactions are billed per ten thousand operations, egress is billed per gigabyte and is the single biggest cost for anything user-facing, and the cool and archive tiers carry early-deletion penalties that can make them more expensive than hot if you get the lifecycle wrong. Price the access pattern, not the bytes.
Table of contents
- The four tiers, and what they really cost
- Transactions are billed, and they add up
- Egress is the line that actually hurts
- Redundancy multiplies everything
- How to actually control the bill
- How this fits the rest of the stack
- FAQ
The four tiers, and what they really cost
Azure has four access tiers, and the trade-off is always the same: cheaper to store, more expensive to touch.
Hot - around $0.018/GB/month. Cheapest transactions. For data accessed regularly.
Cool - around $0.010/GB/month. Roughly 40% cheaper to store, but transactions cost several times more, plus a per-GB data-retrieval charge. 30-day minimum retention.
Cold - around $0.0036/GB/month. Cheaper again, higher retrieval costs. 90-day minimum.
Archive - around $0.002/GB/month. Almost free to store, and offline: you must rehydrate a blob before you can read it, which takes hours (up to 15 for standard priority) and costs a per-GB rehydration fee. 180-day minimum.
The minimum retention periods are where the money goes. Write a blob to Cool and delete it after 10 days, and you are charged for the remaining 20 days anyway. That is the early deletion penalty, and it is applied per blob.
So a lifecycle policy that moves objects to Cool after 7 days, on data that is typically deleted after 14, produces a bill higher than leaving everything in Hot. This is a genuinely common own-goal - the tiering felt like an optimisation and the penalty ate the saving.
Transactions are billed, and they add up
Every operation against blob storage is a transaction, and transactions cost money.
- Write operations (PUT, POST) - roughly $0.05 per 10,000 in Hot; several times that in Cool and Archive.
- Read operations (GET) - roughly $0.004 per 10,000 in Hot; much more in the colder tiers.
- Data retrieval - a per-GB charge in Cool, Cold, and Archive that does not exist in Hot.
The scenario that catches people: an application that writes millions of small objects - IoT telemetry, per-request logs, individual events. Ten million writes a month is roughly $50 in transaction charges alone, while the actual bytes stored might cost pennies. The bill is dominated by the number of operations, not the volume of data.
And in the colder tiers this inverts viciously. Data in Cool that gets read frequently pays elevated transaction costs plus per-GB retrieval, which can easily exceed what Hot would have charged for the same access pattern.
The rule: tier by access pattern, never by age alone. A 3-year-old file that is read every day belongs in Hot. A 3-day-old file that will never be read again belongs in Archive. Age is a proxy for access frequency, and it is often a bad one.
Egress is the line that actually hurts
Storage is cheap. Getting data out is not.
Azure egress to the internet is roughly $0.087/GB after the first 100GB per month free. Ingress is free.
Do the arithmetic on a real case. You store 100GB of images - that is about $1.80/month in Hot. Users download those images 50,000 times a month, averaging 2MB each, which is 100GB of egress. That is roughly $8.70/month.
The egress costs nearly five times more than the storage. And that ratio gets worse the more popular you are, because the storage line is fixed and the egress line scales with traffic.
This is why a CDN is not a performance nicety, it is a cost control. Azure CDN or Front Door caches at the edge, so repeated requests for the same object do not hit blob storage at all. Egress from the CDN is cheaper than egress from storage, and cached hits mean no storage transaction charge either.
If you are serving user-facing files directly from a blob container with no CDN in front of it, the CDN will very likely pay for itself, and the crossover point is lower than most people assume.
Redundancy multiplies everything
The redundancy option is a straight multiplier on the storage line, and it is chosen once and forgotten.
LRS (locally redundant) - three copies in one datacentre. The baseline price.
ZRS (zone redundant) - three copies across availability zones in one region. Roughly 25% more.
GRS (geo redundant) - LRS plus asynchronous replication to a paired region. Roughly double.
GZRS - ZRS plus geo-replication. The most expensive.
GRS doubles your storage bill, and the honest question is whether you need it. It protects against an entire Azure region being destroyed - a genuinely rare event - and the replication is asynchronous, so a regional failure can still lose the most recent writes.
For build artefacts, cached derivatives, thumbnails, and anything you can regenerate: LRS. Paying double to geo-replicate a thumbnail you could rebuild in 200ms is not risk management, it is a rounding error you inflicted on yourself twelve months ago and never revisited.
For source-of-truth data you cannot reconstruct: GRS or GZRS is a reasonable purchase.
The mistake is applying one redundancy setting to one storage account holding everything. Separate accounts, with redundancy matched to how replaceable the data is, is a five-minute change that can halve the line.
How to actually control the bill
Concrete, in order of impact.
1. Put a CDN in front of anything user-facing. Egress is usually the biggest line, and caching removes most of it. This is the single highest-leverage change.
2. Get the lifecycle policy right, and mind the minimums. Tier on access pattern, not age. And never move data to a tier whose minimum retention exceeds the data’s actual lifespan - the early-deletion penalty will exceed the saving.
Hot -> Cool after 30 days of no access
Cool -> Archive after 90 days of no access
Delete after 365 days
Note the of no access, not of existence. Azure supports last-accessed-time tracking for exactly this; turn it on.
3. Match redundancy to replaceability. LRS for anything regenerable. Do not pay double to geo-replicate a cache.
4. Batch small writes. Millions of tiny objects means millions of transactions. Aggregating telemetry into hourly files instead of per-event blobs can cut transaction costs by orders of magnitude.
5. Delete old versions and snapshots. If blob versioning is on, every overwrite keeps the old version, and every version is billed. This silently doubles or triples the storage line, and a lifecycle rule to expire old versions is usually missing.
The general shape of this - and it is true of S3 and every other object store too - is that the advertised per-GB price is the number you notice and the least important one on the bill.
How this fits the rest of the stack
Whatever you decide here, the cost of the decision only shows up as a bill. The RunxBuild hosting calculator is the right place to model that before committing: the compute, the database, the storage, the bandwidth, the worker - each one is a separate line item, and the real cost of a platform is the sum, not the headline number. The RunxBuild dashboard is where the team sees the actual usage once it is running.
Useful related references:
- CPU and Storage: How They Relate and Why It Matters for Sizing
- Budget Cloud Storage: How to Get S3-Class Storage at 1/5 the Cost
- Cloud Storage for Cold Archives: How to Get S3 for a Fraction of the Cost
- Storage on RunxBuild
- Services on RunxBuild
FAQ
Why is my Azure Blob Storage bill higher than expected?
Almost always egress or transactions rather than storage. Egress runs about $0.087/GB after 100GB free, so serving user-facing files without a CDN can cost several times more than storing them. Millions of small writes also generate transaction charges that dwarf the capacity line.
What is the cheapest Azure Blob Storage tier?
Archive, at around $0.002/GB/month - but it is offline, requires hours-long rehydration to read, charges a rehydration fee, and has a 180-day minimum retention. Delete a blob before that and you are billed for the remaining days anyway.
What is the Azure early deletion penalty?
Cool, Cold, and Archive have minimum retention periods of 30, 90, and 180 days. Delete a blob before the minimum and you are charged for the remaining days as though it were still there. A lifecycle policy that tiers data more aggressively than its real lifespan can therefore cost more than staying in Hot.
Should I use GRS or LRS?
LRS for anything you can regenerate - thumbnails, build artefacts, caches. GRS roughly doubles the storage price to protect against losing an entire region, which is rarely worth it for replaceable data. Use GRS only for source-of-truth data you cannot reconstruct.
Does a CDN reduce Azure storage costs?
Yes, significantly, for user-facing content. Cached requests never reach blob storage, so you avoid both the egress charge and the per-read transaction charge. For anything served repeatedly to users, the CDN typically pays for itself.