What Is an SLO? A Practical Guide for Solo Developers

Summary

What is an SLO? A service level objective is an internal reliability target for a measurable indicator, such as 99.9% of requests succeeding over 30 days. The gap between the target and 100% is your error budget, roughly 43 minutes a month at 99.9%. Solo devs should start at 99% to 99.5%, measure a real user path, alert on burn rate instead of single blips, and use the budget to decide whether to ship or fix.

Laptop on a dark desk showing a service uptime dashboard late at night

What is an SLO? It is a number you promise yourself about how often your service should work, measured over a fixed window. "99.9% of requests succeed over 30 days" is an SLO. It turns "the site feels fine" into something you can check, and it tells you when to stop shipping features and fix things instead.

You do not need a platform team for this. A solo dev with one API and a Postgres database can write a usable SLO in an afternoon. Here is what the term means, how to pick the number, and where it goes wrong.

It was 2 a.m. and nobody knew if the app was broken

Picture a side project with 400 weekly users. One night the checkout endpoint starts returning 500s for about 20 minutes. Nobody tweets, nobody emails. You find out three days later from a single support message.

Was that bad? Without a target, you cannot answer. With one, you can: if your SLO allows roughly 43 minutes of failure per month and you just burned 20, you know you have used almost half your allowance on one bad night. That is the entire point of an SLO. It replaces a feeling with a budget.

The three acronyms, without the glossary voice

People mix up SLI, SLO and SLA constantly, so here is the short version.

An SLI (service level indicator) is a measurement. "Share of HTTP requests that returned a non-5xx status in the last 30 days" is an SLI. It is a ratio of good events to total events.

An SLO (service level objective) is the target for that measurement. "That ratio must stay at or above 99.9%" is the SLO. It is internal. You set it, you can change it, nobody sues you over it.

An SLA (service level agreement) is a contract with consequences, usually refunds or credits. Most side projects have no SLA, and that is fine. You can still run SLOs without one. The Google SRE workbook chapter on implementing SLOs is the standard reference if you want the long version.

The order matters: pick the SLI first, then the SLO, and only think about an SLA if a paying customer demands one in writing.

Stopwatch and a notebook sketch of a partly filled bar representing an error budget

Error budgets: the part that changes how you work

An SLO of 99.9% also means 0.1% of events are allowed to fail. That allowance is your error budget, and it is the useful half of the idea.

Over a 30-day month, 99.9% availability leaves about 43 minutes of allowed downtime. The arithmetic is 30 days times 24 hours times 60 minutes, which is 43,200 minutes, times 0.001. A 99% target gives you about 7.2 hours. A 99.99% target gives you about 4.3 minutes.

Those last two numbers are why most small projects should not aim high. Four minutes a month means a bad deploy and a rollback already breaks the target. Here is what trips people up in practice: the higher you aim, the more your time goes to defending the number instead of building the product.

The budget also gives you a rule for deciding what to build next. Budget mostly intact: ship the risky feature. Budget burned: fix the flaky thing first. No meeting needed, just a number on a dashboard.

How to pick an SLI you can actually measure

Start with what a user would call "broken". For a web app that usually comes down to two questions: did the request succeed, and was it fast enough?

For most side projects, two SLIs cover 90% of the value:

Notice that latency is written as a share of requests under a threshold, not as an average. Averages hide the slow tail, and the slow tail is where users give up. Percentile thinking matters here: a 300 ms average can sit on top of a 4-second p99.

Measure at the edge of your system, as close to the user as you can. A health check that pings /healthz from inside the same VPC tells you the process is alive, not that users can log in. If you can only afford one measurement, probe a real user path, such as login or checkout, from outside.

Picking the number: start lower than feels right

The honest answer for a new project is 99% or 99.5%. Look at your last 30 days of data, work out what you actually delivered, set the SLO slightly below that, and tighten it later if users complain.

Here is a rough guide for a solo project:

Tested, not optimal, and worth doing anyway: an SLO you hit 100% of the time is a number set too low, and an SLO you miss every month is a number nobody trusts. Aim for missing it occasionally, because that is when the budget does its job.

Laptop in a Bangkok cafe showing a flat steady latency graph at dusk

Is an SLO just uptime monitoring with extra steps?

Not quite, though the two overlap. A ping monitor tells you the site answered at a given minute. An SLO tells you what share of real user requests worked over a month, and what that means for your next decision.

Picture two weeks where a ping monitor shows green every minute, yet one slow database query makes the dashboard page time out for 3% of logged-in users. The monitor says all is well. The SLI says you missed your latency target. Only one of them changes what you do on Monday.

Keep the ping monitor anyway. It is cheap and catches total outages fast. Just treat it as one input, not the definition of "working".

A tiny SLO you can write down today

You do not need a vendor to start. Write this in your repo, in a file called SLO.md:

service: checkout-api
window: 30d
slis:
  availability:
    good: http_status < 500
    total: all requests except /healthz
  latency:
    good: response_time < 500ms
    total: all requests except /healthz
objectives:
  availability: 99.5%
  latency: 95%
if_budget_burned:
  - freeze non-urgent features
  - fix the top error source first

If your stack already exports request counts, the availability SLI in Prometheus-style syntax is one line:

sum(rate(http_requests_total{status!~"5.."}[30d]))
  / sum(rate(http_requests_total[30d]))

That ratio, compared against your target, is your whole SLO dashboard. Everything else is polish. Three panels are enough: current SLI, budget remaining, and a burn rate line.

Alerting on burn rate, not on every blip

The mistake almost everyone makes: alerting whenever the error rate crosses a threshold. You get paged at 3 a.m. for a 90-second spike that cost you 0.2% of the month's budget.

Burn rate fixes that. It asks how fast you are consuming the budget compared to the pace that would use it up exactly at the end of the window. A burn rate of 1 means you will finish the month with an empty budget and no surprises. A burn rate of 10 means you will be empty in three days.

A sane setup for one person is two alerts. A fast one for something like a burn rate above 10 over an hour, which wakes you up. A slow one for a burn rate around 2 over a day, which becomes a ticket for the morning. The Google SRE book chapter on service level objectives covers the reasoning behind this, and the multi-window version is in the workbook linked above.

Phone on a bedside table lighting up with a night-time alert

Which tool to use when you are the entire ops team

You can run SLOs from a spreadsheet and a cron job for a month while you learn what you care about. Once the numbers matter, a tool earns its place. Three worth looking at, with the caveat that your stack decides more than the feature list does.

Grafana is the default for people who already export Prometheus metrics. The free tier is generous for a side project, and the SLO feature sits on top of data you probably already have. Skip it if you have no metrics pipeline yet and no appetite to build one.

New Relic has a free tier with 100 GB of data ingest a month and SLO tooling built into the platform. It suits you if you want agent-based setup with little configuration. The trade-off is that costs get less predictable once you pass the free allowance.

Datadog is the most complete option and the most expensive one, with infrastructure, APM and logs billed separately. Worth it if a team is growing around you. Skip it for a solo project unless someone else is paying.

Whatever you pick, resist the urge to define fifteen SLOs on day one. One availability SLO and one latency SLO per user-facing service is enough to learn from.

A worked month, with real arithmetic

Say your SLO is 99.5% availability over 30 days, and you serve about 600,000 requests a month. That target allows 0.5% failures, so 3,000 failed requests before the budget is empty.

On day 9 a bad migration returns 500s for 25 minutes and costs you 1,100 failed requests. You have used about 37% of the budget in one evening. On day 17 a third-party API times out and burns another 900. Now you are at roughly 67% spent with 13 days left.

That is the moment the budget earns its keep. You do not need to panic, but you also should not ship the risky refactor you had planned for day 20. You add a timeout and a fallback for that third-party call, you write the migration check you skipped, and you move the refactor to next month.

The takeaway is not that failures are bad. Failures are expected and priced in. What the number gives you is a calm, shared answer to "can we afford this risk right now?", even when the only person in the room is you.

When to revisit the number

Review each SLO once a quarter, or after any month where you badly missed or never touched the budget. Missing it twice in a row means either the system needs real work or the target was ambitious for the stage you are at. Both are useful facts.

If you gain paying customers, ask them what "broken" means to them. A customer who runs a weekly report cares about Monday morning, not about a Saturday-night blip, and your SLO can reflect that with a tighter target during their hours.

Three mistakes that make SLOs useless

Measuring what is easy instead of what users feel. CPU usage is not an SLI. Users do not care that your CPU is at 40%. They care that the page loaded.

Setting the target from ambition. "We want five nines" sounds serious and means nothing if your database is a single instance on a small VM. Set the SLO from observed reality, then improve the system, then tighten the number.

Never using the budget. If you finish every month with 98% of the budget left, you are shipping too slowly or the target is too loose. An unused budget is wasted risk-taking capacity.

What would you put under an SLO first?

Pick one endpoint users would notice if it broke. Write the SLI in plain English, set the target 0.5 points below what you delivered last month, and check it again in 30 days. If you want a side project that forces you to practice this, a small uptime-and-latency dashboard for your own apps is a decent weekend build. Which of your services would you trust the least right now?

Frequently asked questions

What is an SLO in simple terms?
An SLO is a target for how reliable your service should be, measured over a time window. For example, 99.9% of requests should succeed over 30 days. It is an internal goal, not a contract.
What is the difference between an SLI, an SLO and an SLA?
An SLI is the measurement, such as the share of non-5xx responses. An SLO is the target for that measurement. An SLA is a contract with penalties, such as credits, if you miss a promised level.
How much downtime does 99.9% allow per month?
About 43 minutes over a 30-day month. A 99% target allows about 7.2 hours, and 99.99% allows about 4.3 minutes.
What is an error budget?
It is the share of events allowed to fail under your SLO. At 99.9%, 0.1% of requests may fail. When the budget is nearly spent you pause risky releases and fix reliability first.
What SLO should a side project start with?
Start at 99% to 99.5%, set slightly below what you delivered over the last 30 days. Tighten it only when users or revenue justify the extra effort.
Do I need a paid tool to track SLOs?
No. A file in your repo, request counts from your app and a simple query are enough to start. Tools like Grafana or New Relic help once you want burn rate alerts and dashboards.
What is burn rate?
Burn rate is how fast you consume your error budget compared with the pace that would use it up exactly at the end of the window. A burn rate of 10 means the budget is gone in about three days of a 30-day window.