practice

Assumption Register

The record of the numeric assumptions a design was sized against, monitored so the architecture announces when its own premises expire.

constraintscapacitydriftdocumentationmonitoring

Every architecture is sized against numbers: requests per second, objects per tenant, items per session, fan-out per event, growth per quarter. Those numbers are usually stated once, in a document read during design, and then never checked again. An assumption register makes them first-class: recorded next to the decision they justified, and instrumented, so that when the number moves the architecture says so.

Why it matters

The most common cause of slow architectural failure is not a bad decision. It is a good decision whose premise expired quietly. No deploy is at fault, no dependency broke, no component is obviously slow — several numbers simply moved in the same direction and the design that fitted the old ones does not fit the new ones.

Because there is no incident to point at, teams respond by adding capacity, which works until it does not.

Implementation patterns

  • Assumption next to decision. "We run three regions because peak concurrent is X" ages far better than "we run three regions".
  • A dashboard per assumption, with an alert on the assumption itself rather than only on the symptom it eventually produces.
  • A review trigger, not a review calendar. "Revisit this partitioning when the largest tenant exceeds N" is checkable; "review annually" is theatre.
  • Compound assumptions get their own metric. Latency was fine until session length, candidate pool size and feature vector size all grew — the product of those numbers had no owner because it had no name.
  • Failed-assumption postmortems. When one expires, ask why the alarm did not exist, not why the number moved.

Industry example

Consider a short-video recommendation path sized when a median session pulled around twenty videos and feature computation took tens of milliseconds. Two years on, sessions pull an order of magnitude more, the candidate pool has grown tenfold, feature vectors are larger, and the user-feature cache hit rate has degraded precisely because sessions got longer.

Each change shipped with green dashboards. p99 latency tripled with no responsible component, because the cause was the product of five numbers that were each somebody's local success metric and nobody's architectural constraint.

The remedy is not a profiler. It is deciding which assumption to re-establish — bound the candidate pool, move feature computation off the request path, or batch the fan-out — and only then optimising. A register with alerts would have surfaced the choice two years earlier, when it was a design change rather than an emergency.

Failure scenarios

  • The register as a document. Written during design, never instrumented, discovered during the postmortem.
  • Monitoring the symptom only. Alerting on p99 latency tells you something is wrong; alerting on "items per session exceeded the design assumption by 5x" tells you what.
  • Unowned compound assumptions, where each input is individually healthy.
  • Register rot. Assumptions recorded for the original design and never added for subsequent ones, so the register describes an architecture that no longer exists.

Trade-offs

Maintaining a register costs discipline and adds metrics that mostly sit idle, and there is a real risk of alert fatigue if every assumption pages someone. The mitigation is that assumption alerts are almost never urgent — they belong in a weekly review, not on a pager. What you buy is the ability to meet architectural decay as a planned piece of work rather than as an unexplained incident.

Interview question

"A service's p99 latency has tripled over eighteen months. There is no bad deploy, no slow dependency, and profiling shows no single hot spot. How do you investigate, and what would you have put in place a year ago to make this investigation unnecessary?"