Cruxly

Cruxly › System design › Reliability and Observability

SLAs, Availability Math and Error Budgets as Design Inputs

a target is a design input: it decides how many dependencies you may call, how many copies you run, and when releases stop

Open the interactive lesson

Reliable, Scalable, Maintainable: Measuring a System gave you the nines, the SLI and SLO vocabulary and the error-budget idea, and SLOs, Error Budgets, and Alerting on What Users Actually Experience and Designing for Observability cover the mechanics of measuring them. This lesson uses the numbers to design: how availability composes across the dependencies you call, why the SLO you run must be tighter than the SLA you sign, how multi-window burn-rate alerts are parameterised, what an error-budget policy must say, and which tier of a product deserves how many nines.

SLI, SLO and SLA: three documents for three audiences

An SLI is a measurement, an SLO is an engineering target, and an SLA is a contract with consequences; they have different owners and are allowed to disagree. The SRE book's Service Level Objectives chapter defines the SLA as an explicit or implicit contract with users that includes consequences of meeting or missing the SLOs it contains, and gives a test: ask what happens if the SLO is missed. With no explicit consequence, you are almost certainly looking at an SLO. The workbook's Implementing SLOs chapter puts the same point in business terms: an SLA is a business contract that takes effect when users are so unhappy that you have to compensate them.

DocumentAudienceWritten byIf you miss it
SLI (good events / total events)Engineers, dashboardsThe team that owns the serviceNothing; it is a number
SLO (target for the SLI over a window)The team, product, and the on-callProduct and engineering togetherThe error-budget policy applies (section 7)
SLA (contractual promise)Customers, legal, financeSales, legal and engineeringCredits, refunds or termination rights

The workbook recommends writing an SLI as the number of good events divided by the total number of events, for example successful HTTP requests over all HTTP requests. That form has a useful property: the error budget is 100% minus the SLO, so it is a count you can spend. Its worked case: a 99.9% SLO over 3 million requests in four weeks leaves 3,000 allowed errors, and one outage that causes 1,500 errors uses 50% of the budget.

The design consequence of the difference. Many internal services should have an SLO and no SLA, because nobody will pay you for missing it and the SLO is only a tool for deciding how to spend engineering time. An SLA is a liability: it should be signed only for the few request classes where a customer's money depends on you, and it should always sit behind a stricter SLO (section 5). Teams that skip the distinction either sign contracts that match their best month, or treat an internal target as if it were a legal promise and refuse to ship.

Why an SLO is a shared decision. The SRE book's Embracing Risk chapter describes the arrangement: product management sets the SLO, a neutral monitoring system measures actual availability, and the difference is the remaining budget. The same chapter states the economics. An incremental improvement in reliability may cost 100 times more than the previous increment, and the chapter's own example values a move from 99.9% to 99.99% on a service earning $1M at $900 (a 0.09% availability increase), so the improvement is worth doing only if it costs less than that. The number is a business input, so engineering cannot choose it alone.

What experts say in the room. "Who gets paid if we miss this?" splits SLO from SLA in one question. What a senior checks: that every SLA clause maps to a measured SLI with the same definition of a good event, the same measurement point and the same window, because a contract measured differently from your dashboard is a dispute waiting to happen. For monitoring mechanics see Designing for Observability.

Choosing SLIs per system type

The right SLI is the one that fails when a user of that kind of system is unhappy, so it depends on what the system does. The workbook's Implementing SLOs chapter groups them by system type, and the same list is a good template for a design review.

System typeSLIs the workbook listsWritten as
Request-driven (APIs, web)Availability, latency, qualityProportion of requests that succeeded; proportion faster than a threshold; proportion served undegraded
Pipeline (batch, streaming)Freshness, correctness, coverageProportion of data updated more recently than a threshold; proportion of input records giving correct output; proportion of jobs or records processed
StorageDurabilityProportion of written records that can be successfully read

The SRE book's Service Level Objectives chapter says the same by listing user-facing serving systems (availability, latency, throughput), storage systems (latency, availability, durability) and big-data systems (throughput, end-to-end latency), and adds that all systems should track correctness, though correctness is often a property of the data and not of the infrastructure.

Three habits that separate good SLIs from dashboards.

Pipelines need freshness, not uptime. A nightly job that always runs but loads yesterday's data twice is 100% available and wrong. Pick freshness and correctness for a pipeline, coverage for a batch job that can silently process only part of its input, and durability for a store whose failure mode is a read that returns nothing.

:::warn Counting what cannot happen A request that never reaches you cannot be counted as an error by you. If your SLI is computed from your own server logs, a total outage upstream of the logs reads as 100% good. Pair the server-side SLI with a probe or client-side measurement. :::

Do not set the target from today's performance. The SRE book says adopting current values without reflection can lock you into a system that needs heroic effort to meet its targets. Start loose and tighten, keep aggregations simple, and keep as few SLOs as possible: drop any SLO you could never use to win an argument about priorities.

What experts say in the room. "What is a good event for this request class, and where do we count it?" What a senior checks: one SLI per class that matters, a latency SLI with a threshold in the same sentence, a freshness or correctness SLI on every pipeline, and a second vantage point so the SLI cannot read perfect during an outage.

Serial dependencies multiply: the ceiling on what you can promise

If a request needs every one of its dependencies to succeed, its availability is the product of theirs, so the ceiling on your SLO is below your weakest dependency and gets lower with every extra hard dependency. This is arithmetic, not a source's figure: availabilities of independent components in series multiply.

Worked arithmetic. A checkout handler that hard-depends on five services, each at 99.9%, is available 0.999 to the fifth, which is 0.99501, or 99.5%. Over a 30-day month (43,200 minutes) that is 0.00499 x 43,200 = about 215.6 minutes of expected unavailability, nearly 3.6 hours, from services that each look excellent alone. Ten hard dependencies at 99.99% each give 0.9999 to the tenth = 99.90%, so a four-nines target has become three nines before your own code has failed once. Your own service sits in the product too: a 99.99% service in front of a 99.9% database cannot exceed 0.9999 x 0.999 = 99.89%.

Computed, the diagram's product is 0.9999 x 0.999 x 0.9999 x 0.999 x 0.999 = 0.9968 (worked arithmetic).

The ways to beat the product are design moves, not operations.

Dependency SLAs are not guarantees. A cloud provider's published SLA is a promise of compensation, and it is typically per service and per region. It tells you the number the provider is willing to be paid against, not what your composed system will achieve. Use measured availability of the dependency for your own maths, and the published number for your risk register.

What experts say in the room. "Draw the request path, circle every hard dependency, and multiply." The argument is whether a call may be taken off the path; the number is the product. What a senior checks: the dependency count on the critical path, which dependencies have a fallback, and whether the SLO is above the product of the hard ones, because if it is, the promise cannot be kept by operations alone.

Redundancy raises availability, until failures stop being independent

Parallel redundancy multiplies the unavailabilities, which is why it is the main tool, and why the independence assumption under it is the part that fails. The AWS whitepaper Availability and Beyond, in its section on availability with redundancy, gives the formula: a workload with two redundant subsystems is down only when both are down, so the probability of failure is the product of the two failure probabilities. Its example: two subsystems at 99% each fail together with probability 1% x 1% = 0.01%, giving 99.99%.

:::key Verified November 2026 AWS whitepaper, Availability and Beyond, "Availability with redundancy": a workload with s spares fails only when s + 1 subsystems fail; each spare costs as much as the original module, so cost grows at least linearly; with a 99.5% subsystem, two spares give about 99.9999875% (about 3.94 seconds of downtime a year) and ten spares are effectively zero downtime, "a 5X increase in the cost of sparing to achieve four seconds less downtime a year". The paper's conclusion: use the fewest spares needed, and beyond three spares the returns are negligible for almost all workloads. :::

The unit of failure decides what a spare is. The whitepaper's example: a workload needs 10 instances at peak. In one availability zone, adding more instances does not help against a zone failure, because the whole zone fails together. Two zones with 10 each, 20 instances, give one spare zone. Three zones with 5 each give 15 instances and still serve peak load after losing one zone, which is cheaper and tolerates the same event. So you count spares in units of the isolation boundary: instance, cell, zone, region.

The independence trap. The formula assumes failures happen independently. Real incidents are often common-mode: the same bad deploy goes to both copies, the same configuration push, the same expired certificate, the same shared control plane, the same traffic spike that overloads both. The AWS paper states the assumption directly (independent and redundant subsystems), and sparing applies to dependencies that fail independently, such as instances in different zones.

Worked arithmetic, not a source's figure. Take two replicas at 99% each. Assume 10% of each replica's downtime comes from a cause that hits both at once (a shared release), and the rest is independent. Joint unavailability is about 0.1 x 1% + (0.9 x 1%)^2 = 0.001 + 0.000081 = 0.001081, so the pair is 99.89%, not the 99.99% of the naive formula. One tenth of correlated failure took away a whole nine. Even at 99.9% replicas (the same split) the pair gives about 99.990% against the naive 99.9999%. The independent part is almost irrelevant; the correlated tenth dominates.

Moves that restore independence. Stagger rollouts across cells or zones so a bad release reaches one copy first. Keep a manual or separate control path for failover. Avoid putting the failover decision behind the thing that failed. Test the failover on a schedule, because an untested spare has an unknown probability of working, and the formula silently assumes it works.

What experts say in the room. "Two zones gives me the independent part of the maths; the shared deploy is what I need to design around." What a senior checks: which causes are common to both copies, how many spares are in units of the failure boundary, and when failover was last exercised.

Why your SLO must be tighter than the SLA you sign

The SLA is the line where you pay, the SLO is the line where you act, and the gap between them is the time you have to notice and fix a problem before it costs money. The SRE book's Service Level Objectives chapter lists a tighter internal SLO than the advertised one as a recommended tactic, so you can respond to chronic problems before users notice. The Embracing Risk chapter's example is a contract of 99.9% on a quarterly basis for an external product with a stronger internal target behind it.

Worked arithmetic, not a source's figure. Suppose a customer SLA promises 99.9% a month, which allows 43.2 minutes over 30 days. If the internal SLO is also 99.9%, a single 30-minute incident leaves 13 minutes, and an ordinary bad month breaches the contract. With an internal SLO of 99.95% the budget is 21.6 minutes, so the operating rule triggers (freeze, reliability work) after 21.6 minutes spent, which leaves 21.6 minutes between the SLO line and the SLA line. That slack pays for detection delay, a rollback that takes longer than planned, and a second incident in the same month.

SLA (contract)SLO (internal)What the gap buys
Target, 30 days99.9% (43.2 min)99.95% (21.6 min)21.6 min of reaction time
ReactionPay creditsFreeze releases, reliability workYou act before you pay
AudienceCustomerTeam

How to set both.

Do not overshoot either. The SRE book's Chubby example is the counter-argument to over-delivering: users come to depend on what a service delivers, not what it promises, so SRE ensures that global Chubby meets but does not significantly exceed its SLO, and in a quarter without real failure synthesises a controlled outage to expose unreasonable dependencies early. If you are running far above your SLO you are either overbuilt or accumulating hidden dependants.

:::warn A dependency SLA does not cover your SLA If you sign 99.9% to customers on top of a 99.9% provider, you have no margin: the product of the two is below what you signed, and the provider's remedy is usually a credit against its fee, not compensation for your customer's loss. :::

What experts say in the room. "Sign the SLA at the number we can defend, run the SLO above it, and alert on the SLO." What a senior checks: the gap between SLO and SLA in minutes (not percent), the window and exclusions in the contract text, and that the SLA is not above the composed ceiling.

Multi-window burn-rate alerts: the numbers and why each exists

A burn rate says how fast the error budget is being spent relative to the SLO, and alerting on it ties each page to a fixed share of the budget. The workbook's Alerting on SLOs chapter defines burn rate as how fast, relative to the SLO, a service consumes its error budget: a burn rate of 1 uses exactly the whole budget by the end of the window. The budget consumed by the time an alert fires is the burn rate times the alert window divided by the period. SLOs, Error Budgets, and Alerting on What Users Actually Experience shows the final recommendation; this section explains how the workbook gets there.

:::key Verified November 2026 Workbook, Alerting on SLOs, recommended parameters for a 99.9% SLO over 30 days: page at burn rate 14.4 with a 1-hour long window and a 5-minute short window (2% of budget consumed); page at 6 with 6 hours and 30 minutes (5%); ticket at 1 with 3 days and 6 hours (10%). Guideline: make the short window 1/12 of the long window. :::

Worked arithmetic on the table. A 30-day period is 720 hours. Budget consumed = burn rate x window / period: 14.4 x 1/720 = 2%; 6 x 6/720 = 5%; 1 x 72/720 = 10%. Time to empty the whole budget at that burn rate is 720 hours / burn rate: 50 hours at 14.4, 120 hours (5 days) at 6, and 30 days at 1. So the first page means "we will be out of budget in about two days", the second "in five days", the ticket "at the end of the month".

The strategies, in the order the chapter tries them, and the flaw of each.

StrategyWhat it doesFlaw (workbook)
Error rate over the SLO threshold, short windowAlerts when a 10-minute error rate reaches the SLO'sLow precision: a 0.1% error rate for 10 minutes uses only 0.02% of the monthly budget
Longer alert window (for example 36 hours)Same, over more timeReset time of 36 hours; long-window queries are expensive
Add a duration clause (for example the Prometheus for: clause)Wait until the condition has lastedPoor recall: a 100% outage alerts after the same delay as a 0.2% one, and the timer resets on a blip
Single burn rate, 1-hour window, threshold 36 x 0.001 (5% of budget)Page on rate relative to budgetLow recall: a 35x burn never alerts but empties the budget in about 20.5 hours (720 / 35 = 20.57)
Multiple burn ratesA page tier and a ticket tierMany parameters, and duplicate notifications need suppression
Multi-window, multi-burn-rateRequire long and short windows to both exceed the thresholdThe chapter's recommendation

Why two windows. The long window answers is this significant, because a burst of one minute at a huge rate is a rounding error against a month. The short window answers is it still happening, so the page clears about when the errors stop and not an hour later. The 1/12 guideline: the chapter's example is 15% errors for 10 minutes, where, with a 14.4 threshold (a 1.44% average over the hour), the long window crosses after about 6 minutes (1.44 / 15 x 60 = 5.8) and the alert clears about 5 minutes after the errors stop, when the short window drains.

Worked arithmetic on detection time. A total outage (error ratio 1) at a 14.4 threshold means the 1-hour window must average 14.4 x 0.001 = 1.44% errors. That takes 0.0144 x 3600 = about 52 seconds of full outage, which is the page latency for the worst case. A partial failure at 1.44% takes the whole hour to cross the line, and a 0.1% failure never pages and only reaches the ticket tier.

Where it breaks: low traffic. The workbook's example: with 10 requests an hour, one failed request is a 10% error rate for that hour. Its suggestions: generate artificial traffic for signal, combine related services into one monitored group, change the product or client (retries, fallbacks) so a single failure matters less, or lower the SLO or lengthen the window to match the real impact of one failed request. Arithmetic: against a 0.1% budget rate, a 10% hourly error is 100x, so one request would page if you did nothing.

What experts say in the room. "Page on budget velocity, not on a rate, and keep the ticket tier so slow burns do not wait for the month's end." What a senior checks: that each alert maps to a share of budget, that a 35x style gap does not exist, that a short window exists on every page, and that low-traffic services have a floor of events or synthetic probes. Cause-based alerts that predict exhaustion (a disk filling) remain, as the DevOps lesson says.

Error-budget policy: what happens when the budget is spent

An error budget has no force until a written policy says what changes when it runs out, agreed in advance by the people who can stop a release. The SRE book's Embracing Risk chapter describes the arrangement: the product and SRE teams jointly define a quarterly budget from the SLO, a neutral system measures real availability, and new releases may ship while measured availability stays above the SLO. When the budget runs low, releases can slow or halt until reliability improves. Its example: for a 99.999% SLO the budget is 0.001% of queries, and a problem failing 0.0002% of queries spends 20% of the quarterly budget.

What the policy must contain. The workbook's Implementing SLOs chapter lists the actions that can follow exhaustion: the development team gives top priority to reliability bugs from the past four weeks; the team focuses exclusively on reliability until the service is back within SLO; and a production freeze halts certain changes until there is enough budget to resume. A usable policy turns this into a table with owners and thresholds:

Budget stateExample action (choose and write yours)Who decides
HealthyShip on the normal cadence; spend budget on risk (experiments, migrations)The team
Burning faster than 1xReliability bugs from recent incidents move to the top of the queueTeam lead
ExhaustedFeature releases freeze; only fixes for reliability and security shipNamed in advance, with escalation to a director
Single incident over a stated shareA blameless review with a tracked actionThe on-call and the service owner

Worked incidents from the workbook. On a four-week budget of 109,897 errors (a 97% availability SLO over 3,663,253 requests), a bad API release causing 14,066 errors used about 13% of the budget (14,066 / 109,897 = 12.8%). A database server failure with 20 hours of restore time, causing about 72,000 errors, used about 65% (72,000 / 109,897 = 65.5%). The point of the numbers: one operational event can cost most of a period, so recovery time (restore, rollback) is a design input that sets how many such events the SLO can absorb.

The negotiation with product. Without a budget the argument is reliability against features with no shared unit. With one, the question becomes: do we want to spend the remaining minutes on this launch? The SRE book frames the budget as something to spend on innovation, and the rule that product sets the SLO means product has a lever: a looser SLO buys more change, and a tighter one costs release speed. Both sides see the same neutral measurement, so the debate is about the target, not about whose dashboard is right.

Failure modes of a policy.

What experts say in the room. "We spend the budget on purpose, and when it is gone, features stop." What a senior checks: that the policy is signed by product and engineering leaders, that the freeze condition is a number, and that the budget remaining is visible on the same dashboard as the release calendar.

Designing to a target: which tier gets how many nines, and what it costs

Targets belong per tier, not per company: assign each request class the fewest nines its failure actually costs, then pay for exactly that in architecture. The Embracing Risk chapter's cost rule (an increment may cost 100 times more than the last) and the AWS paper's rule (use the fewest spares needed) point at the same practice. The workbook's tiered examples set premium customers at 99.99% and free customers at 99.9%.

A way to assign tiers (a suggested starting point, not a sourced table). Ask what a failed request costs:

Request classWhat a failure costsReasonable starting targetWhat it forces in the design
Money movement, checkout, authLost revenue, trust, reconciliation99.95% to 99.99%Multi-zone, no single hard dependency without a fallback, idempotent retries, tested failover
Core read path (browse, feed)Lost engagement; recoverable by retry99.9%Multi-zone, cache and stale-while-error fallbacks
Background work (emails, exports)Delay, rarely loss99% on freshness (for example done within an hour)Queue and retry; no synchronous availability target
Internal tools, batch analyticsStaff inconvenience99% or looserSingle zone may be fine; backups matter more than redundancy

Worked arithmetic, not a source's figure. Allowed unavailability per 30 days: 99% = 432 minutes; 99.9% = 43.2; 99.95% = 21.6; 99.99% = 4.32; 99.999% = 0.43 (26 seconds). At 4.32 minutes a month, a single human-triggered rollback that takes 10 minutes breaches the target alone, so the design cannot rely on a person in the loop. Automated failover, canary and automatic rollback are not optional extras at that tier; they are what the budget physically requires. At 99.9%, a 43-minute budget tolerates one detected incident with a manual rollback.

What each extra nine adds to the bill.

:::warn The user's weakest link may not be you The Embracing Risk chapter's smartphone example: a user on a phone with 99% reliability cannot tell the difference between 99.99% and 99.999% service. If the client path, the radio network or a third-party SDK is worse than your target, spending on more nines is invisible. :::

Describing the trade-off in an interview. Start with the user-visible request classes, give each an SLI and a target, compose the ceilings from the hard dependencies, show the one or two design moves that lift the critical class (async hop, fallback, extra zone), and state what you are deliberately leaving lower. Then say how you would know: the SLI, the burn-rate alerts and the policy. That one chain, from target to architecture to alert to policy, is the shape of a staff-level answer.

What experts say in the room. "Four nines for checkout, three for browse, and the extra nine costs us an automatic rollback and a spare zone, which I will pay for." What a senior checks: per-tier targets with the minutes in the budget, whether any single human action fits inside the budget, the unit of failure for each spare, and whether the SLA signed to customers is below the composed ceiling.

Further reading. Site Reliability Engineering: How Google Runs Production Systems, edited by Betsy Beyer, Chris Jones, Jennifer Petoff and Niall Richard Murphy (free at sre.google), is this phase's book, and the SRE workbook that goes with it carries the alerting and policy material used here.

How to say it in the interview

"I would not pick a number first, I would pick the SLI per request class and then compose. If checkout hard-depends on five services at 99.9% each, the best I can promise is about 99.5%, roughly 3.6 hours a month, unless I mask a failure with a fallback or an async hop. Redundancy only helps for failures that are independent, and a shared deploy or config is not, so I give the SLA a margin: SLO 99.95% behind a 99.9% contract, with burn-rate alerts at 14.4 over an hour and 6 over six hours, and a written policy that freezes feature releases when the budget is gone."

Checklist

Practice this interactively
Share this lessonWhatsAppLinkedInX

Related lessons