Cost per request and per tenant as design metrics, the egress bandwidth tax, spot and reserved capacity, storage tiering — and when scaling out is just buying past a design flaw.
What this module covers: Cost as a design constraint with the same standing as latency — because the architecture determines the bill and finance can only report it. Unit economics, since total spend is unactionable and cost per request or per tenant is not, plus the attribution work that makes those numbers exist at all. The egress tax, which has appeared as a warning in six earlier modules and gets its accounting here. The cost model and the single best lever for each resource class, including two line items that are routinely large and rarely understood — provisioned IOPS and NAT gateway data processing. Then the architectural levers ordered by size, ending on the question this course has been building towards: when is scaling out just buying your way past a design flaw, and what is the test that tells you. Finally governance that works — tagging enforced by policy, anomaly detection on daily spend, cost estimates in pull requests — and the honesty about trade-offs, including that premature cost optimisation has exactly the same shape as premature performance optimisation.
The Architecture Determines the Bill
A finance team can report spend, allocate it, and ask questions about it. It cannot change it, because almost every line on a cloud invoice is the direct consequence of a design decision made months earlier: where the data lives, how many round trips a request makes, whether a cache exists, what the retention policy is, how the keys are distributed.
Which means cost is an engineering property, and it deserves the same treatment as latency:
A system that costs three times more per request than it needs to is a defect, with the same status as one that is three times slower than it needs to be.
Not a moral failing and not an emergency — a measurable, attributable, fixable property. And like latency, it is cheap to influence at design time and expensive to retrofit.
Analogy: a building's running costs. Once the walls are up, the facilities manager can adjust the thermostat, negotiate the electricity tariff and turn lights off at night — worth doing, and bounded. The decisions that actually set the bill were made on paper: the insulation, the glazing, the orientation, whether the plant room is sized for the load. Nobody blames the facilities manager for a poorly-insulated building, and nobody expects them to fix it. The architect could have, for almost nothing, at the time.
Unit Economics: Total Spend Is Unactionable
"We spent £180,000 last month" supports no decision. Every useful cost conversation is about a unit:
Unit
Answers
Cost per request (per service)
is this endpoint's implementation efficient?
Cost per tenant
which customers are unprofitable?
Cost per order / per active user
do we make money at this price?
Cost per GB ingested / per million events
is this pipeline's design sane?
Three things follow from expressing cost this way.
Efficiency becomes trackable. Total spend rises with growth, which hides everything. Cost per request rising means the system is getting less efficient, and that is a signal you can act on. A deploy that doubles cost per request should be as visible as one that doubles p99 latency — and in most organisations it is not visible at all.
Gross margin becomes visible per plan. If cost per tenant on the £29 tier is £41, you are selling at a loss, and only unit economics reveals it. The distribution is usually extreme: a small number of tenants consume a large share of the cost, which is Module P-8's noisy-neighbour problem with prices attached, and Module P-18's per-tenant limits are what convert an unbounded cost into a bounded one.
And it requires attribution work, which is the part that must be set up in advance:
Mandatory tagging enforced by policy as code (Module O-3): owner, service, environment, cost centre. Untagged resources are unattributable, and a resource created untagged is very rarely tagged later.
Per-tenant metering for the usage that dominates — requests, storage, tokens, egress — which is the usage_events table from Module P-18 doing double duty.
A shared-cost allocation rule. A shared database or cluster serves everyone, and allocating it by headcount is arbitrary; allocate by measured usage (queries, bytes, CPU-seconds) even approximately, because an approximate measurement drives better decisions than an arbitrary split.
The Egress Tax
Six earlier modules flagged data transfer as a cost. Here is the accounting.
Ingress is generally free; egress is priced, and the price rises with distance:
text
The asymmetry is architectural rather than incidental. It means:
"Just point it at the other region's database" costs a cross-region round trip and a per-gigabyte charge on every query, forever (Module A-9).
Replicating every write to N regions is charged N−1 times, which is why Module A-14's rule — replicate the inputs and derive the outputs locally — is a cost decision as much as an architectural one. Replicating 240,000 derived timeline writes per second across regions is a very large bill for data you could compute.
Chatty service-to-service traffic across zones is billed per gigabyte, which makes topology-aware routing (Module A-5) a cost control and not merely a latency optimisation.
Serving object storage directly to users instead of through a CDN pays origin egress rates on every byte, every time (Module A-11).
Shipping all observability data to one central region moves a continuous, high-volume stream across a priced boundary (Modules O-1, A-9) — and the same pipeline is a residency problem, which is a rare case where the cheap fix and the compliant fix coincide.
And the mitigation nobody does first: measure egress by source. Most teams cannot say which service or which flow generates their data-transfer charges, which makes the line item unattackable. Cost-and-usage data broken down by transfer type is the prerequisite; after that the levers are a CDN, compression, zone-local routing, private endpoints, and deriving rather than replicating.
Cost Model and Best Lever, per Resource Class
Compute.
Lever
Typical saving
Applies to
Right-sizing (measure, then shrink)
20–50%
almost everything — most instances are over-provisioned
ARM instance families
20–40%
anything that compiles/runs on ARM, which is now most things
Spot capacity is the largest single discount available and it requires the engineering from Module P-19: checkpointing so a reclaimed instance costs one chunk rather than the whole job, and idempotency so a retried chunk is harmless. Transcoding is the canonical fit.
The idle problem deserves naming separately, because several earlier modules created it: a GPU costs the same whether it is inferring or not (Module A-12), a warm standby costs the same whether it is failing over or not (Module O-7), and a provisioned database replica costs full price at 2% utilisation. For these, utilisation is the only lever, and the honest comparison against a per-request managed service is a utilisation calculation rather than a preference.
Serverless versus provisioned has a computable crossover: per-invocation pricing wins decisively on spiky and low-volume workloads and loses badly on steady high volume. It is worth actually computing rather than arguing about, and the answer changes as a workload matures — which is a reason to keep the compute layer replaceable.
Storage. Tiering with the traps from Module A-11 (retrieval charges, minimum storage durations, per-object transition fees, minimum billable object sizes — so tier large cold objects and leave small ones alone). Then the three quiet accumulations:
Snapshot and volume sprawl — orphaned snapshots, and PersistentVolumeClaims deliberately retained when a StatefulSet scales down (Module O-3). Nobody deletes these because nobody owns them.
Log retention, which is frequently the largest observability line item and grows with traffic and with every developer who adds a log line (Module O-1).
"Keep everything forever" as a default, which is a decision made by omission and is also a compliance liability (Module O-9).
Database. Per gigabyte, this is the most expensive storage you own — replicated, backed up, on fast disks — which is the economic argument behind three earlier rules: do not put blobs in it (Module A-11), do not put logs in it, and partition old data so it can be dropped or tiered (Module P-9). Replicas cost full price, and analytics on the OLTP instance means paying OLTP prices for scan-heavy work (Module P-22).
And provisioned IOPS is a line item, which closes this course's first through-line. Module F-2 established that sequential access is dramatically cheaper than random. Module P-3 showed that random UUID primary keys destroy insert locality. Module F-13 showed that bloat multiplies the pages a query must touch. Every one of those is now literally an invoice: more IOPS provisioned, more I/O charged, a larger instance to hold a working set that should have been smaller. The physics from Phase 1 arrives as a monthly bill, and that is the most direct link between a low-level design decision and money in the entire curriculum.
Network. Load balancers charge per hour and per capacity unit, so a fleet of under-used balancers is pure overhead. And the item that is routinely large and rarely understood:
NAT gateway data processing. Traffic from a private subnet to the internet — including to object storage, to a managed service's public endpoint, and to a third-party API — is charged per gigabyte processed by the NAT gateway, on top of egress. A pipeline reading terabytes from S3 through a NAT gateway can produce a five-figure monthly charge that a VPC endpoint (gateway or interface) eliminates almost entirely. It is one configuration change, it is frequently one of the top five line items, and most teams have never looked at it.
Managed services and third parties. Per-request, per-seat, or per-token (Module A-12's LLM costs, where output tokens are several times input and an agentic loop is unbounded). The observability vendor belongs here too, priced on cardinality and volume (Module O-1). These are the line items that grow silently with usage and have no natural ceiling unless you impose one.
The Architectural Levers, Ordered by Size
Resource-level optimisation gets 20–50%. Design-level changes get 5–20×. In order:
1. Do not do the work at all. A cache hit is the cheapest possible request (Module F-12): no compute, no database, no egress if it is at a CDN. Everything in this category is the same idea — pre-aggregation instead of scanning (Module P-22), a CDN instead of origin serving (Module A-11), pagination limits instead of full result sets, conflation instead of every update (Module A-10), and a rollup table instead of a warehouse query per page load.
2. Do it later, and more cheaply. Asynchronous work on spot capacity, batch instead of streaming. And the question worth asking of every "real-time" requirement (Module P-22): what decision changes because this is fresh in seconds rather than in an hour? The honest answer is usually "none," and the cost difference between the two designs is large.
3. Do it once. Content-addressed storage deduplicates identical files (Module A-11); an embedding cache keyed on content hash removes repeated model calls (Module A-12); memoisation and request coalescing collapse a stampede into one fetch (Module P-12).
4. Do not store or ship what nobody reads. Unused metric series (Module O-1 notes most are never queried), logs at debug level in production, columns nobody selects, backups of derived data (Module O-7's tier 3), and traces retained for a year that nobody has ever opened past week two.
5. And the one this course has been building towards.
When scaling out is just buying your way past a design flaw
Symptom
The purchase
The actual fix
Rough ratio
Read replicas added to survive an N+1 query
3 replicas
one JOIN or a batch load (F-8)
100×
More instances because a hot row serialises writes
2× the fleet
append-only entries instead of a counter update (P-24)
50×
A bigger cache tier because the hit ratio fell
4× memory
fix the key distribution or the TTL (F-12, P-13)
20×
A larger database because queries got slow
next instance size
reclaim bloat; add the missing index (F-13)
10×
More workers because each job does 20 queries
5× workers
batch the queries (P-19)
20×
Cross-region replication of derived data
the egress bill
derive locally from replicated inputs (A-14)
large
A faster instance to absorb random-write I/O
provisioned IOPS
time-ordered keys (P-3)
10×
Each row is a real pattern, and in each the purchase works — capacity is genuinely added, the incident genuinely ends. That is what makes it seductive: buying capacity is fast, requires no code review, and can be done during an incident, while fixing the design takes a sprint and a migration.
The test that distinguishes them:
If cost per request rises as you scale, you are buying past something. Efficient scaling holds cost per unit roughly flat; paying to avoid a fix makes each unit more expensive, permanently.
That single metric, trended, is the most valuable thing in this module — because it turns an architectural judgement into an observation, and because the alternative is a bill that grows superlinearly with revenue while nobody can say why.
Governance That Actually Works
Enforce tagging with policy as code (Module O-3), so an untagged resource cannot be created. Retrofitting tags is an archaeology project.
Showback or chargeback per team, so the people who can change a design see its cost. Cost data that reaches only finance changes nothing.
Anomaly detection on daily spend. The failure this catches is a runaway loop — an agent without a step cap (Module A-12), a retry storm against a metered API, a job stuck re-processing, a debug flag left on. These produce five-figure surprises within days, and a daily anomaly alert catches them while a monthly review does not.
Budgets with alerts, per team and per service, so the conversation happens before the invoice.
Cost estimates in pull requests. Tooling that annotates an infrastructure change with its projected monthly delta (Infracost and similar) makes cost a design-time decision reviewed alongside the code — which is where it is cheapest to change.
A cost review on the same cadence as the capacity review (Module O-5), because they are the same conversation with different units: resource-per-request times traffic forecast, with prices attached.
The Trade-Offs, Honestly
Cost trades against things you also want, and pretending otherwise produces bad decisions in the other direction:
Cost versus reliability. Module O-7's standby tiers and Module O-2's nines both cost money by design. The right response to "the hot standby is expensive" is a stated RTO for that data class, not a cheaper standby chosen quietly.
Cost versus latency. Multi-region, CDNs and caches cost money to save milliseconds. The question is what those milliseconds are worth, which is a product question with a real answer.
Cost versus velocity. This is the one engineers get wrong most often: premature cost optimisation has exactly the same shape as premature performance optimisation. A team of six spending three weeks to save £400 a month has spent far more than it saved, and has added complexity that will slow every subsequent change.
Two rules that keep this proportionate. Measure before optimising — most teams guess wrong about where the money goes, and the actual answer is frequently egress, NAT processing, logs, or idle capacity rather than the compute everyone assumed. And optimise the top two or three line items and ignore the rest, because a 30% saving on 40% of the bill dwarfs a 90% saving on 2% of it.
Why this matters in production: the cost failures that happen are quiet and cumulative. A NAT gateway processing a pipeline's terabytes for a year. Incomplete multipart uploads billed since 2024 (Module A-11). Orphaned volumes from a StatefulSet scale-down. A log level left at debug after an incident. An LLM agent loop without a step cap. Cross-region replication of data that was derivable. Three read replicas standing in for a JOIN. None of them pages anyone, none appears in an incident review, and together they are frequently a third of the bill — which is why the useful practice is a trended cost-per-request metric and a daily anomaly alert rather than an annual optimisation project.
Where This Shows Up in Your Stack
PostgreSQL: the most expensive storage per gigabyte you operate, so keep blobs (Module A-11) and logs out of it, partition old data so it can be dropped or tiered (Module P-9), and keep scan-heavy analytics off the OLTP instance (Module P-22). Replicas cost full price. And provisioned IOPS is where Phase 1's physics becomes an invoice: random-insert keys (Module P-3) and table bloat (Module F-13) both raise the I/O you must pay for.
Redis: memory is the cost, so TTLs, eviction policy and what you choose to cache are cost controls (Module P-12). Do not replicate a cache cross-region — give each region its own and avoid the egress entirely (Module A-9).
Kafka: storage is retention × replication factor, so a 7-day retention at RF=3 is 21 days of disk; and cross-AZ replication traffic between brokers is billed, which is a known large and surprising line item. Decide retention per topic rather than globally (Module P-15).
Object storage: lifecycle rules to abort incomplete multipart uploads, tiering for large cold objects only, and a CDN in front so you pay CDN egress rather than origin egress (Module A-11).
NAT gateway and VPC endpoints: check the NAT data-processing line before anything else. A gateway endpoint for object storage and interface endpoints for the managed services you call heavily can remove a top-five line item with one change.
Observability: cardinality and volume are the price (Module O-1) — cardinality limits at the collector, tail-based sampling, retention tiers, and deleting the majority of series nothing queries.
LLM APIs: output tokens dominate, so cap max_tokens, trim context (which also improves quality), route easy requests to a small model, cache embeddings by content hash, and put hard step and token budgets on agentic loops (Module A-12).
Spot capacity: transcoding (Module A-11), embedding backfills, batch pipelines and CI — with the checkpointing from Module P-19 that makes an interruption cost one chunk.
Summary
The architecture determines the bill; finance can only report it. A system costing three times more per request than it needs to is a defect with the same standing as one that is three times slower — cheap to influence at design time, expensive to retrofit.
Total spend is unactionable; unit economics is not. Cost per request, per tenant, per order. Cost per request rising means the system is getting less efficient, and a deploy that doubles it should be as visible as one that doubles p99. Per-tenant cost is what reveals that a plan is sold at a loss, and the distribution is usually extreme — Module P-8's noisy neighbour with prices attached, bounded by Module P-18's per-tenant limits.
Attribution has to be set up in advance: tagging enforced by policy as code, per-tenant metering of the dominant units, and a shared-cost allocation rule based on measured usage — because an approximate measurement drives better decisions than an arbitrary split.
Egress is priced by distance and ingress generally is not, which makes several architectural shortcuts permanently expensive: querying another region's database, replicating writes N−1 times, chatty cross-AZ service calls, serving object storage without a CDN, and shipping all telemetry to one region. Measure egress by source first — most teams cannot attribute their transfer charges, which makes the line item unattackable.
Compute levers: right-sizing (most instances are over-provisioned), ARM families (20–40%), spot at 60–90% for interruptible work — which requires Module P-19's checkpointing and idempotency — reserved capacity for the baseline, and autoscaling to remove idle. Idle is its own problem: a GPU, a warm standby and an under-used replica all cost the same doing nothing, so utilisation is the only lever. Serverless-versus-provisioned has a computable crossover that moves as a workload matures.
Storage: tier large cold objects only (retrieval charges, minimum durations, per-object fees and minimum billable sizes make small-object tiering a loss), and watch the three quiet accumulations — snapshot and orphaned-volume sprawl, log retention, and "keep everything forever" as a decision made by omission.
The database is your most expensive storage per gigabyte, which is the economic argument behind keeping blobs and logs out of it, partitioning old data, and keeping analytics off the OLTP instance. Provisioned IOPS closes the course's first through-line: sequential-versus-random from Module F-2, random UUID keys from Module P-3, and bloat from Module F-13 all arrive here as a monthly bill.
Check the NAT gateway data-processing charge. Traffic from a private subnet to object storage or a managed service is billed per gigabyte through the NAT, and a VPC endpoint removes it — frequently a top-five line item fixed by one configuration change that most teams have never examined.
Design levers beat resource levers by an order of magnitude, in this order: do not do the work (a cache hit is the cheapest request; pre-aggregate, use a CDN, bound pagination, conflate); do it later and cheaper (async on spot, batch instead of streaming — and ask what decision actually changes if data is seconds fresh rather than an hour); do it once (content addressing, embedding caches, request coalescing); and do not store or ship what nobody reads.
Know when scaling out is buying past a design flaw: replicas standing in for a fixed N+1, instances standing in for a hot-row counter, memory standing in for a key distribution, a bigger database standing in for reclaiming bloat, workers standing in for batching, and IOPS standing in for time-ordered keys. The purchase always works, which is what makes it seductive. The test: if cost per request rises as you scale, you are buying past something — efficient scaling holds cost per unit roughly flat.
Governance that works: tagging enforced at creation, showback to the teams who can change designs, anomaly detection on daily spend (which catches the runaway agent loop, the retry storm against a metered API, and the debug flag left on — all of which produce five-figure surprises within days), budgets with alerts, cost estimates annotated on pull requests, and a cost review on the same cadence as the capacity review, since they are the same arithmetic with prices attached.
Be honest about the trade-offs: reliability and latency cost money by design, and premature cost optimisation has the same shape as premature performance optimisation — three weeks to save £400 a month is a loss. Measure before optimising, because the answer is usually egress, NAT processing, logs or idle rather than the compute everyone assumed, and optimise the top two or three line items only.
The next module, Compliance, Privacy, and Data Sovereignty, is the last constraint layer. It treats GDPR, HIPAA, CCPA and DPDP as design inputs rather than legal paperwork, covers PII tokenisation and vaulting, and resolves the problem that six earlier modules deferred to it: how a deletion request reaches an immutable Kafka log, an object-storage backup and a warehouse — for which the answer is to delete a key rather than a record.
Knowledge Check
A product's revenue grew 3× over a year and its cloud bill grew 7×. The team's proposed response is a cost-optimisation sprint focused on right-sizing instances and buying reserved capacity. What does the module say the numbers indicate, and what should be examined first?
A data pipeline running in private subnets reads roughly 40 TB per month from object storage and writes results back. The team is surprised by a large recurring charge they cannot attribute to compute, storage or internet egress. What does the module suggest they check, and why is it easy to miss?
A six-person team proposes a three-week project to migrate their batch transcoding pipeline to spot instances and rewrite their metrics to reduce cardinality, projecting savings of about £600 a month. Their bill is £22,000 a month, dominated by database instances and cross-region replication. What does the module advise?
Test your knowledge with more question sets
Sign in to access a wider variety of questions and get notified when new practice sets are added to this module.
within an availability zone often free
cross-AZ charged — and in some clouds in BOTH directions
cross-region more, per GB
to the internet most, per GB
from a CDN materially cheaper than from origin storage