skip to content

Your mobile backend's servers are a small bill line while its datastore dominates — how do you find which pricing dimension drives that?

level: seniorimportance: should knowfreq 52%

answer

  1. decompose the line, not the service
  2. quantity times rate, per dimension
  3. the parts must rebuild the total
  4. rank, then find the design decision
  5. fewer units, smaller units, different unit

basics

~20 s

Split the service line into its charge units and multiply each quantity by its own rate. Rank the dimensions, then ask which design decision produces the top quantity — call count, retained volume, held capacity or elapsed time — and attack that one.

solid answer

~40 s

Do not reason about services; reason about **meters**. Pull the quantities behind the datastore line per dimension — requests handled, gigabyte-months held, provisioned throughput units held, gigabytes moved — multiply each by its own rate, and check the parts reconstruct the line. Rank them. On a mobile backend the usual winner is held capacity, because it bills continuously and is invisible in application metrics, with request volume second because clients are chatty. Then map the top quantity to the decision that produces it: a held level comes from a sizing choice, requests from client behaviour and retries, gigabyte-months from retention. The fix must move **that** quantity — resizing the application tier moves only the running-time dimension, which is already the small line.

code

json · 12 lines
json
{
  "billingPeriod": "one month",
  "note": "illustrative rates in arbitrary cost units, not a price list",
  "lines": [
    { "dimension": "instanceHoursRunning", "quantity": 1440, "ratePerUnit": 1.0, "amount": 1440 },
    { "dimension": "storeRequestsMillions", "quantity": 900, "ratePerUnit": 2.0, "amount": 1800 },
    { "dimension": "provisionedThroughputUnitHours", "quantity": 360000, "ratePerUnit": 0.02, "amount": 7200 },
    { "dimension": "storedGiBMonths", "quantity": 4000, "ratePerUnit": 0.25, "amount": 1000 },
    { "dimension": "giBMoved", "quantity": 3000, "ratePerUnit": 0.5, "amount": 1500 }
  ],
  "total": 12940
}

go deeper

for a junior

Recall that a bill line is the sum of several meters, so the first step is asking for the quantities behind it rather than the total.

for a middle

Do the decomposition: quantity times rate for each dimension, confirm the parts rebuild the line, and rank them by share.

for a senior

Connect the dominant quantity to the design decision that produces it, then choose a lever that actually moves that meter and quantify the saving before committing.

for a principal

Decide when the answer is a different metering shape rather than a better size, and set the expectation that cost reviews start from a decomposition, not a service name.

## Start from the meter, not the service The instinct when a bill is too high is to look for an expensive service. That instinct is usually wrong, because a service is not a price — it is a bundle of meters. Two systems can run the identical service at the identical rates and have completely different bills, because the quantities behind the meters come from different design decisions. So the first move is always the same: take the line that dominates and **decompose it into quantity times rate, one row per pricing dimension**. The check that the decomposition is real is arithmetic: the rows must add up to the line. If they do not, you are missing a dimension, and the missing one is frequently the answer. ## A worked decomposition Using invented rates in arbitrary cost units, one month of a mobile backend might decompose as follows: | Dimension | Quantity | Rate | Amount | Share | |---|---|---|---|---| | Instance hours running (app tier) | 1,440 | 1.0 | 1,440 | 11% | | Store requests (millions) | 900 | 2.0 | 1,800 | 14% | | Provisioned throughput unit-hours | 360,000 | 0.02 | 7,200 | 56% | | Stored gigabyte-months | 4,000 | 0.25 | 1,000 | 8% | | Gigabytes moved | 3,000 | 0.5 | 1,500 | 12% | | **Total** | | | **12,940** | | The store accounts for 10,000 of 12,940 — about 77% — and a single dimension, the throughput level held for every hour of the month, is 56% on its own. Note what the shape tells you. The app tier is the thing the team looks at daily and it is a ninth of the bill. The largest number is a capacity decision made once, which does not appear in any application dashboard and does not move when traffic does. ## Which quantity is elastic? Once ranked, sort the dimensions by how they respond to traffic, because that determines both the fix and what happens after it. - **Held capacity** is inelastic: it is unchanged by traffic within the level. Only a sizing action changes it, and the evidence for the action is measured utilisation over a representative period. - **Requests** are elastic and driven by client design: polling intervals, chattiness, retry policy, and whether reads are cached at the edge of the application. - **Stored gigabyte-months** are elastic only downward and slowly: the meter is volume times time, so a deletion changes the bill from the day it happens, not retrospectively. - **Running time** is elastic in unit count and largely a fleet-sizing decision. - **Gigabytes moved** follow payload size and copy count. ## The three ways to move a dimension 1. **Fewer units.** Batch requests, remove a poll, cache a read, delete data that is past its usefulness, stop instances nothing uses. 2. **Smaller units.** Shrink payloads, compress stored objects, lower the declared throughput level to match measured utilisation. 3. **A different unit.** Move the capability onto a different meter entirely — a consumption-metered mode instead of a held level, for example — which is the right answer when the duty cycle is low and no amount of sizing fixes the trough. The third lever is the one teams forget, and it is frequently the largest. A store held at a fixed level for a workload that is busy eight hours a day is paying for sixteen idle hours by construction, and no sizing exercise removes that; changing the metering shape does. ## What goes wrong The characteristic failure is fixing the visible thing. A team sees a large bill, resizes the application fleet, and moves 11% of the bill by a fraction of itself while the 56% line sits untouched. The second failure is fixing a real dimension in the wrong direction: reducing request count on a **provisioned** store changes nothing at all, because the meter never looked at the requests. That is not a subtle point, but it is regularly missed, and it is exactly why the decomposition has to come before the remedy. The third failure is estimating the saving without re-running the arithmetic. Every proposed change should be expressed as a change in a **quantity**, pushed back through the same table, and compared against the same total. A change that halves a quantity contributing 8% of the bill is a 4% saving, which is often not worth the engineering week it costs — and knowing that before the week is spent is the entire point of decomposing the line.

  • The team halves request volume and the store line barely moves. What does that tell you?
    That the dominant dimension is not requests. On a store billed mainly for a held throughput level, the meter never looked at the traffic, so the level is unchanged and so is most of the charge. The saving only appears once the declared level is lowered to match the new utilisation.
  • How do you judge whether a proposed saving is worth the work?
    Express the change as a change in one quantity, push it back through the same decomposition, and read the new total. Halving a quantity that contributes under a tenth of the bill is a few percent, which usually loses to the engineering time it costs.
  • Why is the app tier so often the smallest line on this shape of system?
    Because it is metered on running time and sized visibly, while the store is metered on several dimensions at once — held capacity, calls and retained volume — each modest-looking and none appearing in application dashboards. Invisible meters accumulate; visible ones get tuned.

saying these in an interview costs you the question

  • Hunts for an expensive service instead of decomposing the line
  • Resizes the application fleet when held capacity dominates the bill
  • Reduces request volume on a store billed for a declared capacity level
  • Never checks that the dimension amounts reconstruct the line total
  • Quotes a saving without re-running the arithmetic on a quantity change
  • Assumes the biggest number is the one the team already worries about