Lesson 056 · Phase 2, Mechanisms

Cost as a Design Constraint

Sort a bill into rent, meters and somebody's afternoon before you read the total, because a loop in a template can cost as much as the whole fleet underneath it.

21 min read

Lesson 56 · 67 published · 90 planned

On this page
The systems in this lessonUsed here: Marlow Books, Stagefront, and Galewatch.

Made up for this course and reused from lesson to lesson so their numbers become familiar. None of them exist. All three

Marlow Books · A small online bookshop
Four people, one server and one Postgres database. About 40 requests a second on a normal day and ten times that in the week before Christmas. The one box that the early lessons stress until it breaks.
Stagefront · An event ticketing service
Quiet most of the time, then a stadium show goes on sale at 10:00 and two hundred thousand people press the same button in the same minute. Oversold seats are a lawsuit, so correctness matters as much as speed.
Galewatch · Telemetry for wind farms
Nine hundred turbines, a reading every two seconds, over links that drop for hours in bad weather and come back with a backlog. Dashboards that lag by seconds, reports that scan a year.

Marlow Books is an online bookshop run by four people that exists only in this course, and on Saturday 1 August 2026 its founder shipped the best received change of the year in about three hours.

The feature was a strip at the bottom of every book page: six across, four rows, twenty four other covers shrunk down to thumbnails of about four kilobytes each, under the heading "customers also bought". People clicked it. Pages per session went up for the first time since spring. The strip loads below the fold, so the page itself got no slower, and the two application boxes lesson 005 left the shop on did not notice anything at all, because a thumbnail comes out of the object storage bucket lesson 016 moved the covers into and never goes near Postgres.

The bill for August arrived on the third of September. The object storage lines had gone from about $78 a month to about $1,496.

The founder read it three times. Then he opened the invoice properly, which he had never had a reason to do, and found two lines of the same size, to the dollar: $709 of requests and $709 of bytes leaving the bucket.

Work backwards from those. Lesson 016 priced object storage requests at forty cents a million, so $709 is 1,772 million requests in the month, which is 684 a second across the thirty day month this course has always priced. Lesson 016 also settled that Marlow serves about 38 book pages a second on an ordinary day, and every one of those pages now asks for twenty four thumbnails, which is 912 a second if no browser holds any of them. So 75 percent of the possible fetches actually happened. A customer arriving at a book page was turning up holding one strip slot in four.

That is the whole mechanism, and the uncomfortable part is in the comparison. A cover misses one time in ten, which is the figure lesson 016 used and the reason the cover line is four dollars rather than forty. A thumbnail in that strip is somebody else's book on somebody else's page, and most of them a customer meets exactly once, which is how a miss rate of three in four happens. Same bucket, same prices, same browsers. The difference is that the shop had accidentally invented a traffic pattern with almost no reuse in it, and the only place that showed up was a line item.

The egress line is arithmetic the founder did not need to do, because the two numbers were already equal. Lesson 044 found the crossover: a request costs four ten millionths of a dollar and a byte of egress costs a ten billionth, so a four thousand byte object is exactly the size at which a store charges you the same for the asking as for the sending. The thumbnails were four kilobytes. The invoice printed the crossover.

If I am wrong about the miss rate and a thumbnail really does behave like a cover, one fetch in ten, the line is $189, which is still two and a half times the entire object storage bill it joined. If browsers cached none of them at all it is $1,891. None of what follows turns on which of the three it was.

That Thursday evening the founder took the strip off, and pages per session went back down.

That was the wrong fix. It took a fortnight to find the right one. It kept the feature, it took the line under a hundred dollars a month, and the cheapest part of it was one word in a template, pointing at something the shop had already been paying for since February.

Rent, a meter and somebody's afternoon

Nearly every bill a system generates is one of three things, and the three behave so differently that the total is close to useless until you have sorted them.

Rent is what you pay for having a thing, per month, whether anybody comes or not. Boxes, replicas, balancers, a standby, a per node licence, a second environment, a second region. You change rent by signing something.

The purest rent in this course is the one lesson 054 described and never priced. Blue-green means a complete second environment, and what you are really renting is the idle half: at Marlow another $1,000 a month for two more application boxes, every month, so that a rollback is a switch rather than a deploy. Lesson 054 had already taken the shop's deploys to no visible downtime by doing one box at a time, and it also settled that the switch cannot reach the one Postgres on box A. So the rent buys a faster way back for the half of a release that was reversible anyway, which is impossible to argue with and easy to postpone.

A meter is what you pay per unit of use. Requests, bytes out, gigabyte months, calls to a managed service, time series kept, rows scanned. You change a meter by changing how many times your code does the thing.

Somebody's afternoon is the third, it never appears on an invoice, and it is usually the biggest. Nobody bills you for the fortnight the founder spent on a strip of thumbnails.

Lesson 026 already did this once without naming it, for instruments rather than for money: a log's cost follows traffic and a metric's cost follows cardinality, which is why adding an ISBN label took Marlow from 120 time series to 1.2 million without changing the traffic by a single request. Two instruments on the same dashboard, two completely different shapes of bill. The generalisation is the useful part.

Here is the consequence I would put on a wall. Rent is a number you can read off a page before you buy it. A meter is a number you have to derive, which is exactly why nobody does, and of the two things that reach an invoice it is the only one that is architecture. The fleet is two boxes because one box is a single point of failure, which lesson 055 showed is a floor set by the failure budget and not by the load, and no amount of cleverness moves it. The thumbnail line was a loop in a template with a twenty four in it.

The two also fail in opposite directions as a business grows. Rent punishes you for being small, because the floor does not shrink: lesson 055 priced Marlow's pair at around 15 percent loaded almost all the time and showed that the money a scaler could save is negative. A meter punishes you for being right. Every metered line in a system is a bet that the feature attached to it will not work too well, and the bet is settled by your product team rather than by your infrastructure.

One honest complication, because the taxonomy is not as clean as I just made it sound. Object storage charges per gigabyte month, which is a meter by its units and behaves like rent, since the quantity moves at the speed of the catalogue. That is most of why lesson 016's finding surprised people: the line everyone watches is the one that behaves like rent, and the two that behave like meters sit underneath it being thirty five times larger.

Marlow's bill, in full

The shop is small enough that the whole thing fits in a table, and the shape of it is the lesson.

Line A month Shape
Two application boxes, 005 $1,000 rent
A read replica, 011 $500 rent
A managed balancer, 006 $20 rent
A managed Redis, 008 never priced here rent
216 GB of covers, 016 $5.40 a meter that bills like rent
Origin requests after the CDN, 022 $1.58 a meter
Origin egress after the CDN, 022 $71 a meter
The CDN's own egress, 022 never priced here a meter

Two of those eight lines have never been given a price in fifty five lessons, and one of them is the content delivery network the founder bought in twenty minutes in lesson 022, which that lesson called the one thing in this whole course nobody argues about. Nobody is going back to fix that, because it is what a real bill looks like from the inside, and the pattern is worth naming: the lines you can see are the ones somebody had to sign for, and the ones you cannot see arrived attached to a good decision.

Of the $1,598 that is priced, $1,520 is rent. Ninety five percent. A design review at Marlow, held in July, would have spent its hour on the fleet, which is the line nobody is allowed to change.

Then August happened and the metered side went from $78 to $1,496, which is half of a $3,016 bill. Same architecture diagram. Same boxes, same balancer, same replica, same bucket. One strip of thumbnails.

Lesson 025 gave the method and the sentence that goes with it: the total is rarely the point, and what you want out of an envelope is which term dominates. Pointed at money, that has a sharp edge on it, because the dominant term moved from a line that is fixed by the failure budget to a line that is fixed by a number in a template, and nothing on any diagram in this course records the move.

Lesson 044 named the thing that hides it. Three lines, priced in three different units: per gigabyte month, per gigabyte out, per call, with the last one carrying no reference whatsoever to how big the object was. Nobody checks the units on a bill. They read down the column of dollars, find the biggest number, and spend the meeting on it.

When a bill is nearly all rent

Galewatch is a company that exists only in this course and collects a reading every two seconds from each wind turbine on the farms it monitors. Its bill leans the other way, and the reason is instructive.

Lesson 013 cut its database into shards and priced the result at $8,000 a month: thirty two machines, counting lesson 011's replica for each one, to hold four and a half terabytes that would sit happily on one volume. Lesson 013 said what the money bought, and it was not capacity. It was a smaller unit of failure and a shorter worst hour. Pure rent, bought deliberately, with the reason written down.

Then lesson 025 pointed the envelope at a sales conversation: a prospect with three thousand turbines, which is twenty one more machines at lesson 005's prices, $5,250 a month of new hardware. Also rent, and lesson 025's finding was that the money was not the interesting line at all. The machine count was, because a fleet that size stops being a thing anybody can hold in their head, and a salesperson can be told that on the phone.

A company whose bill is nearly all rent has a slow, boring, visible cost problem. A company whose bill is mostly meters has an invisible one that arrives in arrears.

The two lines move for different reasons

Back to the strip, because the fix is where the design content is.

A per call line and a per byte line are both metered and they respond to almost nothing in common. This is the table I wish somebody had drawn for me years ago.

Change Request line Egress line
Put it behind the CDN falls by the hit rate falls by the hit rate
Twenty four files become one falls twenty four times unchanged
Halve each thumbnail unchanged halves
A longer cache header falls falls

All four are things a team argues about as if they were interchangeable performance work. They stop being interchangeable the moment there is a price on each axis, and the one that looks most like real engineering is the one that leaves half the bill standing.

Take the rows in the order Marlow took them, and price each one against the original $1,418 rather than against the row above it, because stacking two hit rates nobody has measured is how you invent a number.

The CDN was already there and the strip was not using it. The reason is mundane and is why this happens to everybody: in lesson 022's February the founder changed the cover URLs on the book page template to the CDN's hostname, and six months later he wrote a new template that builds its URLs from the covers row, which holds a bucket key. New markup, old habit, no review. At lesson 022's measured 62 percent hit rate the line falls from $1,418 to about $539, and I would expect better than 62 percent here rather than worse, because lesson 022 settled that an edge cache's hit rate is your traffic's concentration divided by the number of edges, and a "customers also bought" strip is popularity by construction. There is no honest number to put on how much better. The point is that one hostname was worth the better part of a thousand dollars a month and nobody had to design anything.

Now the second row, which is the one with the real idea in it. Serve the strip as one image instead of twenty four. The request count divides by twenty four, $709 becomes $30, and the bytes do not move at all, because the pixels are the same pixels. So batching roughly halves the line, from $1,418 to $739, and a reader looking at the table would stop there and call it a disappointing trade.

It is not, and the table cannot show why.

Twenty four separate thumbnails are twenty four things a browser meets once. One combined image is one thing a browser meets with the book, and a customer who comes back to that book has it, at the same one fetch in ten that a cover gets. So the fetch rate falls from 684 a second to about four a second, the same rate as the covers. One image per book page at 96 kilobytes, missing one time in ten, is 9.9 million requests a month at $3.94 and 946 gigabytes of egress at $95. Ninety nine dollars.

Dividing the request count by twenty four is worth $679 a month. Changing what a browser caches is worth another $640. Almost exactly half each, and only the first one is anywhere in that table, because the table has a column for requests and a column for bytes and no column for reuse. Batching a metered call changes the cache unit, and that second effect is worth about as much as the division you did it for. I have watched teams make the change, watch the total halve instead of collapse, and conclude the bill was not fixable.

Two caveats, because the fix has a price and the price is in the third shape.

Something has to build 1.2 million strip images, and a strip is not immutable the way a cover is. Lesson 009 settled that an entry lives at the rate of its fastest changing ingredient, and the fastest changing ingredient in "customers also bought" is the shop's own sales. So the strip image needs lesson 009's versioned key, a new hashed name when the recommendations change, and a job that notices. That is a build step, an invalidation problem and an afternoon, traded for about $1,300 a month, which at Marlow is a trade worth making and at a shop with a thousandth of the traffic would not be.

And the modern objection, which is wrong in an interesting way. Combining files to save requests is a technique people stopped teaching, because lesson 004 showed HTTP/2 fixed the thing that made it necessary: many independent streams share one connection, so a page fetches sixty things over one pipe and pays the four round trips of setup once instead of six times. Correct, and it did nothing whatsoever to this bill. The protocol removed the latency reason to batch and left the billing reason exactly where it was, because the bucket charges per call and has never heard of your connection. A practice that became unfashionable for a good reason can still be load bearing for a different one.

What a nine costs in cash

Availability is the other currency this course keeps spending, and lesson 003 built the model: availability is mean time between failures over that plus mean time to recovery, so the lever is how often times how long.

Marlow breaks about once a month and takes three and a half hours to recover, which lesson 003 worked out as 99.52 percent and about 42 hours a year. Of those three and a half hours, thirty minutes were repair. The rest was not knowing, and then not being sure.

Two purchases, both from lesson 003, both already made.

Drive recovery from three and a half hours to twenty minutes with an alert that reaches a phone and a runbook naming four things to check, and 42 hours becomes 4. That is 38 hours a year removed. It cost a weekend of somebody's time and a rounding error of rent.

Put in a second application box behind a balancer, and lesson 003's 43.8 hours becomes 32. Eleven point eight hours removed. The box the shop actually bought is one of lesson 005's sixteen vCPU machines at $500, and lesson 006's balancer is $20, so $520 a month is $6,240 a year to delete 11.8 hours a year, about $530 an hour. The two baselines differ by 1.8 hours because 43.8 is the table value of the 99.5 percent lesson 001 assumed and 42 is what 003's own mean time arithmetic gives. Lesson 003 calls those near enough to each other, and nothing here turns on which you use.

Same shop. One purchase removed three times as many hours as the other for approximately nothing, and it is the one that does not appear on an architecture diagram anywhere.

The expensive end of the same market is worth seeing beside it. Galewatch's $8,000 a month bought a smaller unit of failure. Stagefront, an event ticketing service that exists only in this course where a stadium show goes on sale at ten and two hundred thousand people press the same button inside a minute, owns a second region, and lesson 050 did the arithmetic almost nobody does: the company is scored in 800 minutes of the year, a four hour outage touches one of those windows about two percent of the time, so a second region bought to protect the on-sale is a lottery ticket. Bought so an ordinary Tuesday does not cost a day of trading, it is the right purchase, and the design document has to say which, because the two want different runbooks.

Lesson 033 found the case where money buys less than nothing: a four machine cluster has the same failure tolerance as three and twice as many pairs that can lose you the quorum.

So an availability number has three prices, and they are the three shapes. Some nines are rent. Some are meters, because a copy in another region pays for every byte that crosses, on every write. And the cheapest nine in this entire course was bought with an afternoon.

The line that is not on the invoice

Marlow's priced bill is $1,598 a month, a little over nineteen thousand dollars a year, and four people run the shop.

I am not going to put a figure on their time, because a salary is not a number this course owns and it does not need one. Nothing a reader can buy for nineteen thousand dollars a year competes with a quarter of one person's attention.

Which is why the expensive mistakes in this course were all bought with complexity rather than with hardware.

Lesson 013's sharding ended with the disappointing part said out loud: you do not end up with no primary, you end up with sixteen of them, and nobody can hold the whole system in their head. The $8,000 was the cheap half. Lesson 040's replication slot keeps every write ahead log segment since its position until the disk fills and the database stops, and the remedy is one alert and one setting rather than a bigger volume. Lesson 041's unbounded queue ended with the out of memory killer. Lesson 047's hot key had one cache node being asked for 26.7 gigabits a second while its own dashboard showed a few thousand operations against a ceiling in the hundreds of thousands, and one multiplication found it after a week of looking somewhere else.

None of those was a shortage of money. Every one of them was a system somebody could no longer predict.

So the opinion I will defend. The cheapest architecture and the simplest architecture are the same thing far more often than a design review admits, and the exceptions are specific rather than general: they are the places where you pay rent for a peak you only meet for a week. Marlow's Christmas is one, four hundred requests a second against forty. Stagefront's forty on-sales a year are another. Lesson 055 named the answer for both, which is scheduled capacity rather than a cleverer system, and lesson 001's cache is what actually carries Marlow through December for an afternoon's work.

Practically, the move is small. Lesson 025 gave the four lines of an envelope, in the order bytes, writes, reads, money, each carrying its units. Add a column rather than a fifth line: for every number, say whether it is rent, a meter or an afternoon, and for anything metered write the multiplier beside it. Twenty four thumbnails a page. One key management call for every object lesson 053 wrapped. One time series per turbine per metric. That is the sentence that would have stopped August, and it belongs in the pull request, the way lesson 054 asked for a flag's removal date and lesson 055 asked for a scaling group's maximum to carry its derivation.

Gather the bill at the start, where it is a requirement, rather than at the end, where it is an apology.

Recap

Rent, a meter and somebody's afternoon. Rent is what you pay for having a thing, a meter is what you pay per unit of use, and the third never reaches an invoice. Sort the lines before you read the total, because a bill's shape tells you which lines you can do anything about.

Of the two lines that reach an invoice, the meter is the one that is architecture. You change rent by signing something, and Marlow's fleet is two boxes because of a failure budget rather than a load. You change a meter by changing how many times your code does the thing, which means a number in a template can move the dominant term on a bill without touching any diagram.

Rent punishes you for being small and a meter punishes you for being right. The floor does not shrink, so Marlow's pair sits at 15 percent loaded and a scaler would save negative money. Every metered line is a bet that the feature attached to it will not work too well, and the bet is settled by your product team.

A per call line and a per byte line move for different reasons. A cache header and a content delivery network move both. Batching moves only requests, smaller objects move only bytes. Four kilobytes is lesson 044's crossover, where a store charges the same for the asking as for the sending, and Marlow's invoice printed it.

Batching changes the cache unit, and that is worth as much as the division. Twenty four thumbnails became one image per book page. Dividing the requests saved $679 a month, and a browser now meeting one thing with the book rather than twenty four things once saved another $640, taking the fetch rate from 684 a second to about four.

A nine has three prices and the cheapest one in this course was an afternoon. Cutting Marlow's detection time removed 38 hours a year for a weekend of work; a second box removed 11.8 at about $530 an hour. Some nines are rent, some are metered on every byte that crosses a region, and a four machine quorum is the case where money buys less than nothing.

The expensive mistakes here were bought with complexity, not hardware. Sixteen primaries nobody can hold in their head, a forgotten replication slot, an unbounded queue, a hot key no dashboard showed. A system nobody can predict costs more than every line on its invoice put together, which is why the cheapest architecture and the simplest one are the same thing far more often than a design review admits.

Check your understanding

  1. A pull request adds one call to a managed service inside a loop that runs once per line of an order. It passes review, because the call is correct and it is fast. Say what you would ask for in the review, what you would want written into the description, and the one graph you would want to exist before it merges.

  2. You inherit a service whose bill is $14,000 a month across eleven lines, and nobody left can tell you what any of them do. Say how you would sort the lines before you look at a single dollar figure, which line you would try to change first, and why the largest line is usually the wrong place to start.

  3. Three purchases are on your desk for a service that breaks about once a month and takes three and a half hours to recover: a paging rotation with a runbook, a second application box, and a standby database in another region. Lesson 003 already made you choose between the first two; rank all three by hours of downtime removed per dollar, then say which part of your ranking changes if what the business is really selling is Stagefront's on-sale window rather than an ordinary year.

  4. Galewatch's dashboard team wants per turbine graphs instead of per farm graphs, which means adding a turbine id label to every metric the writer publishes. Say which of the three shapes that bill is, the arithmetic you would do for one farm before agreeing to it, and the version of the feature you would offer instead if the answer is too big.

  5. Your team runs blue-green deploys, so a complete second environment exists and serves real traffic for about ten minutes a month. Price it in each of the three shapes, say what you would have to give up to delete it, and name the one thing you would measure for a month before proposing that.

  6. A colleague proposes splitting one large API response into eight smaller endpoints, because a client usually needs only two of them. Say what that does to each metered line of your bill, what it does to what the client is able to cache, and the number that decides it.

  7. Two designs for the same feature cost the same money. One is a queue, a worker and somewhere for the failures to go; the other is a column on an existing table and a cron job. Say what each costs in the third shape, which you would pick for a four person team, and the growth figure that would flip your answer.

Next lesson

057 Security Boundaries: Trust, Zero Trust and Blast Radius. Today's sort turned on what it takes to change a line, a signature or a loop in a template; lesson 057 asks who is allowed to change things, and prices the damage when the honest answer turns out to be everybody.

Finished reading?

Marking a lesson done keeps your place on the course index. It is stored only in this browser.

Tip: use the ← and → keys to move between lessons.