Extracting Service Levels From a Service Level Agreement
10 min read · updated August 11, 2026
“99.9% uptime” is not a service level. It becomes one when you know the period it is measured over, what is excluded from the measurement, and what happens when it is missed. All three are in the document and only the first is usually extracted.
What makes an SLA hard
An SLA is one of the few commercial documents where the extracted number is not the answer — it is an input to arithmetic that the reader has to do. Nobody operating a service wants to know that the commitment is 99.95%. They want to know how many minutes of outage they can absorb this month before they owe a credit, and that figure depends on which month it is.
The second difficulty is that an SLA defines its own vocabulary and the definitions do the work. “Downtime”, “Monthly Uptime Percentage”, “Service Credit”, “Excluded Downtime” and “Eligible Period” are almost always capitalised defined terms, and two SLAs using identical percentages can mean materially different things because one measures per five-minute interval and the other per second. Extracting the percentage without the measurement interval extracts an opinion, and a schema built against one vendor’s wording will not survive the second.
From a percentage to allowed downtime
The conversion is simple arithmetic and it should be computed rather than looked up, because the period length is a variable. Allowed downtime equals the period length in minutes multiplied by (1 - availability).
A 30-day month is 30 × 24 × 60 = 43,200 minutes. A 31-day month is 44,640. February in a common year is 40,320. A 365-day year is 525,600 minutes. Those four denominators give:
allowed downtime = period_minutes x (1 - availability)
availability 30-day month 31-day month 28-day month 365-day year
------------ ------------ ------------ ------------ ------------
99% 432 min 446.4 min 403.2 min 5,256 min
(7h 12m) (7h 26m) (6h 43m) (87h 36m)
99.5% 216 min 223.2 min 201.6 min 2,628 min
(3h 36m) (3h 43m) (3h 22m) (43h 48m)
99.9% 43.2 min 44.64 min 40.32 min 525.6 min
(43m 12s) (44m 38s) (40m 19s) (8h 45m 36s)
99.95% 21.6 min 22.32 min 20.16 min 262.8 min
(21m 36s) (22m 19s) (20m 10s) (4h 22m 48s)
99.99% 4.32 min 4.464 min 4.032 min 52.56 min
(4m 19s) (4m 28s) (4m 2s) (52m 34s)Two things fall out of that table that matter more than the numbers themselves. First, a single 44-minute incident breaches a 99.9% monthly commitment in April and does not breach it in March, because April has 43,200 minutes and March has 44,640. If the SLA says “per calendar month” the denominator moves; if it says “per 30 days” it does not. That distinction is a field, and most extractions drop it.
Second, a monthly commitment is not an annual one. A vendor can meet 99.9% every single month and still be unavailable for 525.6 minutes across the year — the monthly allowances add up, and the annual figure is never stated. If your risk model needs an annual number, it is 12 × the monthly allowance, not the annual figure for the same percentage. For a 30-day month that is 518.4 minutes against the 525.6-minute annual figure, which are close enough to be confused and different enough to argue about.
Quarterly commitments appear in enterprise agreements and are worth computing too: a 91-day quarter is 131,040 minutes, so 99.9% allows 131.04 minutes. Quarterly measurement is materially friendlier to the vendor than monthly at the same percentage, because a bad month can be averaged against two good ones. When you extract the percentage, always extract the period alongside it in the same object — they are meaningless apart.
What an exclusion does to the denominator
Every SLA excludes something: scheduled maintenance in a stated window, force majeure, customer-caused outages, outages in beta services, problems in the customer’s own network. The intuition is that exclusions make the SLA looser. For scheduled maintenance, the opposite is often true, and it depends on a single drafting choice.
If excluded minutes are removed from the numerator only — that is, maintenance downtime is not counted as Downtime but the month is still 43,200 minutes — the allowance is unchanged and the vendor gains free outage time. If excluded minutes are removed from both numerator and denominator, which is how a careful SLA defines an Eligible Period, the maths tightens. A four-hour monthly maintenance window is 240 minutes, so the eligible period becomes 43,200 − 240 = 42,960 minutes, and a 99.9% commitment now allows 42.96 minutes rather than 43.2. The vendor has given up 0.24 minutes of allowance in exchange for the window.
The difference is small in this example and large when the excluded window is large. The point is that you cannot compute the allowance without knowing which convention the document uses, so exclusions_affect_denominator is a boolean field that has to be extracted, and it is usually determined by one preposition in a definition rather than by a clause you can find with a keyword search.
Extract the maintenance window itself as structured data too: day of week, local start time, duration, time zone, and the notice period required before an unscheduled emergency window. The time zone is the field most often lost, and a window stated in the vendor’s local time lands in the middle of the customer’s business day often enough that it is worth surfacing at review.
Credit tiers are intervals with sharp edges
Service credits are almost always a step function of achieved availability, and they are written as prose that describes half-open intervals:
Monthly Uptime Percentage Service Credit less than 99.9% but >= 99.0% 10% of monthly fee less than 99.0% but >= 95.0% 25% of monthly fee less than 95.0% 100% of monthly fee
The inclusivity is the whole tier. A month that lands exactly on 99.0% earns 10%, not 25%, and an extraction that stores the tier as the string “99.9% – 99.0%” has lost that. Store each tier as a lower bound, an upper bound, and a flag for each end: lower_inclusive: true, upper_inclusive: false. Then validate that the tiers are contiguous and non-overlapping, and that the top tier ends at the commitment. Gaps are real and appear in real documents; a tier table running to 99.0% under a 99.95% commitment leaves the band between 99.0% and 99.95% unaddressed.
Three more fields decide whether a credit is worth anything, and all three sit outside the tier table:
- The claim window. Credits are usually not automatic. The customer must request them, typically within 30 days of the end of the affected month, with supporting detail. Miss the window and the credit is gone regardless of the outage. This is the single highest-value field on the page for an operations team, and it is almost never in the tier table.
- The cap. Credits are commonly capped at the monthly fee, sometimes lower, and sometimes aggregated across a year.
- Sole and exclusive remedy. Most SLAs state that credits are the customer’s only remedy for a missed service level. Whether that phrase is present changes what a breach means, and it is a boolean worth extracting on its own.
A schema that survives the arithmetic
{
"commitments": [
{ "metric": "availability",
"target_pct": 99.95,
"period": { "kind": "calendar_month" },
"measurement_interval_seconds": 300,
"exclusions_affect_denominator": true,
"scheduled_maintenance": {
"window": "Sunday 02:00-06:00", "tz": "America/Los_Angeles",
"max_minutes_per_month": 240 },
"derived": { "allowed_downtime_minutes_30d": 21.6,
"allowed_downtime_minutes_31d": 22.32 } }
],
"credits": {
"tiers": [
{ "lower": 99.0, "lower_inclusive": true,
"upper": 99.9, "upper_inclusive": false, "credit_pct": 10 }
],
"claim_window_days": 30,
"cap_pct_of_monthly_fee": 100,
"sole_and_exclusive_remedy": true
}
}Keep the derived minutes in the record and label them as derived. They are the figures anybody will actually use, and recomputing them at read time in three different services is how three different answers appear. Do not store a single “allowed downtime” scalar: for a calendar-month period there is no single value, and a field that silently assumes 30 days will be wrong in seven months of the year.
Latency and support-response commitments live in the same document and have the same shape: a target, a period, a measurement method, and a consequence. Response-time SLAs additionally define severity levels, usually P1 to P4, with the severity definition doing the work — and a “response” is normally an acknowledgement, not a fix. Extract response and resolution as separate fields, since a document that commits to a fifteen-minute P1 response and no resolution target has committed to very little.