reliability
Service Level Objective: A Founder’s SLO Starter Guide
A service level objective gives a product team a shared reliability target. Start with user journeys, measurable indicators, and a response rule.

TL;DR — A service level objective (SLO) is a target for a user-facing measure over a period. Start with one journey customers care about, measure its success, set a realistic target, and decide what the team will do when it misses.
A service level objective turns “the product should be reliable” into a shared operating decision. An SLO is not a contractual promise by itself. It is an internal target, measured by a service level indicator (SLI), that helps a team judge when reliability needs more attention than new feature work.
Google’s SLO chapter defines an SLO as a target value or range for a service level measured by an SLI. The useful part for founders is the user focus: choose behavior people experience, rather than a server metric that may look healthy while checkout, login, or an API call is failing.
SLI vs SLO vs SLA
SLI: what we measure. For example, the share of eligible requests that return a successful response within a chosen time limit.
SLO: the target for that measure. For example, a hypothetical goal that at least 99.9% of eligible requests succeed within two seconds over 30 days.
SLA: the agreement with the customer. It specifies the service commitment and the consequences of missing it, such as a service credit. An internal release pause is a team response policy; it does not create a customer agreement. These distinctions follow Google’s service level terminology.
We prefer deciding which of those we mean before the incident. Acronyms make poor incident commanders.
Start with one user journey
Pick a journey that carries real customer or revenue consequence: sign in, save a record, complete checkout, receive a report, or call a public API. Define a successful event from the user’s point of view. For an account app, an SLI might be the proportion of valid sign-in attempts that complete within a chosen response threshold. For a data product, it might be the proportion of scheduled exports delivered by their agreed time.
Avoid measuring everything at once. An early SLO program with one honest signal is more useful than a dashboard full of proxies. The measure needs a denominator, a time window, a data source, and a rule for what counts as a failure. If those are unclear, the target will create arguments rather than resolve them.
Set a target and an error budget
The target is a product decision, not a universal reliability number. Higher reliability costs time, complexity, and sometimes delivery speed. The gap between the target and perfect success is the error budget: the amount of failure the team has agreed it can tolerate during the window.
Use an uptime calculator to understand the arithmetic, but do not begin with a number because another company uses it. A hypothetical target of 99.9% success over a 30-day window allows roughly 43 minutes of unsuccessful time if “availability” is the right measure; it says nothing about whether a 43-minute failure at peak billing time is acceptable. The customer journey and business context decide that.
A reproducible, hypothetical SLO calculation
This PostgreSQL example invents 10,000 eligible API requests in the window September 1, 2026, 00:00 UTC inclusive to October 1, 2026, 00:00 UTC exclusive. It is a teaching fixture, not our production telemetry. The denominator includes every eligible request, including errors and timeouts. Each attempt has one row; a retry is a separate attempt. In production, exclude only documented non-user traffic such as health checks, and record timeouts as failures instead of silently dropping them.
The numerator counts HTTP 2xx responses completed within 2,000 milliseconds. Missing status or latency does not count as success. The hypothetical SLO is at least 99.9% over this 30-day window. Run this self-contained query in PostgreSQL:
WITH requests AS (
SELECT
TIMESTAMPTZ '2026-09-15 12:00:00+00' AS occurred_at,
CASE WHEN n <= 9992 THEN 200 ELSE 503 END AS status_code,
250 AS latency_ms
FROM generate_series(1, 10000) AS sample(n)
), measured AS (
SELECT
COUNT(*) AS eligible_requests,
COUNT(*) FILTER (
WHERE status_code BETWEEN 200 AND 299 AND latency_ms <= 2000
) AS good_requests
FROM requests
WHERE occurred_at >= TIMESTAMPTZ '2026-09-01 00:00:00+00'
AND occurred_at < TIMESTAMPTZ '2026-10-01 00:00:00+00'
)
SELECT eligible_requests, good_requests,
ROUND(100.0 * good_requests / NULLIF(eligible_requests, 0), 3) AS success_pct
FROM measured;
Result: 10,000 eligible requests, 9,992 good requests, 99.920% success. The allowance is 10 bad requests: 10,000 × 0.001. Eight failed, so 80% of the budget is consumed and two failures remain before reaching the limit. At 10 failures the target is still met; 11 failures would miss it. An empty window returns a null percentage, not a reassuring 100%.
Our hypothetical response policy: at 80% consumed, the service owner investigates the failures and reviews the next risky release; if success drops below 99.9%, pause nonessential releases until the owner has verified a fix and explicitly approved resumption. A severe ongoing incident still gets an immediate response, even with budget remaining. This is an example policy to adapt, not a universal threshold.
To reproduce this synthetic fixture in the uptime calculator’s request-success mode, enter 10,000 eligible requests, eight failures and a 99.9% target. It reports the same 10-request allowance, two requests remaining and 80% consumed. Request counts must be integers from zero to one trillion, with a positive eligible count and failures no greater than eligibility; targets accept up to six decimal places. A fractional allowance does not permit an extra whole failure. The target check uses exact arithmetic before rounding the displayed success percentage; even a tiny negative remaining budget means the target was missed. At a 100% target, any failure misses and budget consumption is undefined because the allowance is zero.
Switch to downtime mode for the separate time-based budget: 30 × 24 × 60 × 0.001 = 43.2 minutes at 99.9%. Do not convert the eight failed requests above into minutes. Request success and elapsed downtime have different denominators. Shared links and CSV exports label the selected mode and budget units; older links without a mode still open as downtime.
Link an SLO to a response
An SLO without a response is a decorative metric. Define what happens as the budget burns: increase attention, pause risky releases, investigate the most common failure, or schedule a resilience improvement. Google’s error budget policy guidance shows how an agreed policy can make reliability tradeoffs less political.
Keep the response proportional. A single transient miss may need observation; repeated failures in a purchase flow may deserve an incident and a delivery change. The cost of downtime guide helps frame impact without inventing industry averages.
Review with product, not only operations
Review the SLO alongside customer feedback, support load, revenue events, and upcoming changes. An objective can be technically met while customers are still unhappy because it measures the wrong journey. Conversely, a target can be missed by low-impact events while the product remains useful. Adjust the indicator when evidence says it is misaligned; do not quietly redefine it just to make a chart green.
When a miss triggers a serious incident, capture the timeline and action items in a blameless postmortem. That completes the loop: customer experience sets the target, telemetry exposes the miss, and follow-up makes the system more dependable.
SLOs are valuable because they force an explicit choice about reliability. They give a growing team a common language for deciding when to ship, when to pause, and what customers actually need protected.
Start small and revise from evidence
Run the first objective for a full operating window, inspect missed events, and ask whether they matched customer pain. Change the indicator only with a recorded reason. This is how a young product develops reliability practice without copying a large company’s operational machinery.
Keep the initial measurement simple enough that the team can audit it during an incident. A target nobody can explain or reproduce will not improve a release decision when it matters.