Overview
The first dilemma many teams face when practicing SRE is: they know what an SLO is, but they don’t know how to set one. They either copy Google’s 99.99% or pick an arbitrary 99.9% — only to find that the number neither reflects user experience nor drives engineering decisions.
A good SLO isn’t plucked from thin air. It’s derived from business goals through a series of engineering methods: user journey analysis, metric selection, value calibration, multi-tier design, and regular review. This article systematically covers the complete methodology of SLO design, helping you build a complete mapping chain from “business goals” to “technical metrics.”
This article assumes readers understand the basic concepts of SLI/SLO. For a refresher, see Google SRE Workbook - Service Level Objectives and our SRE Core Concepts: SLI, SLO, and Error Budget.
1. The SLO Design Pyramid
SLO design is not an isolated technical activity but a top-down, layered derivation process:
┌─────────────┐
│ Business │ "How good does our service need to be?"
│ Goals │
└──────┬──────┘
│
┌──────▼──────┐
│ User │ "What do users care about?"
│ Experience │
└──────┬──────┘
│
┌──────▼──────┐
│ SLI │ "How do we measure user experience?"
│ Definition │
└──────┬──────┘
│
┌──────▼──────┐
│ SLO │ "What target should this metric hit?"
│ Target Value │
└──────┬──────┘
│
┌──────▼──────┐
│ Alerting │ "What happens when we miss the target?"
│ & Actions │
└─────────────┘
Layer 1: Business Goals
The starting point for all SLO design is business goals, not technical metrics. Business goals answer the question: what is this service’s value to the business?
| Business Type | Business Goal | Impact on SLO |
|---|---|---|
| E-commerce payment | Transaction success rate directly affects revenue | SLO must be very high (99.99%+) |
| Content recommendation | Latency affects user retention | Latency SLO takes priority over availability |
| Internal tools | Affects employee productivity | SLO can be more lenient (99.5%) |
| Compliance audit | Data must not be lost | Correctness SLO takes priority |
Layer 2: User Experience
From business goals, derive the experience dimensions that users care about. Users don’t care about your CPU utilization — they care about:
- Can I use the service? (Availability)
- Is the service fast? (Latency)
- Are the results correct? (Correctness)
- How much traffic can it handle? (Capacity/Throughput)
Layer 3: SLI Definition
Translate user experience into measurable technical metrics.
Layer 4: SLO Target Value
Set target values for each SLI and calculate error budgets.
Layer 5: Alerting and Actions
SLOs aren’t for display — they’re for driving action. Every SLO must have a corresponding alerting strategy and action plan.
2. Mapping User Journeys to SLIs
User Journey Analysis
The most critical step in SLO design is defining SLIs from the user’s perspective. Not “what is my service’s P99 latency,” but “what experience does the user perceive.”
User journey analysis method:
User Journey: E-commerce Checkout
Browse Products → Add to Cart → Submit Order → Pay → Confirm
Each step maps to one or more SLIs:
Browse Products:
- SLI: Product page load success rate > 99.95%
- SLI: Product page P95 load time < 500ms
Add to Cart:
- SLI: Cart operation success rate > 99.9%
- SLI: Cart operation P99 latency < 200ms
Submit Order:
- SLI: Order submission success rate > 99.99%
- SLI: Order submission P99 latency < 1s
Payment:
- SLI: Payment success rate > 99.99%
- SLI: Payment P99 latency < 2s
Critical User Journey (CUJ)
Not all user journeys need SLOs. Focus on Critical User Journeys — paths with the highest business value and greatest user sensitivity.
# CUJ priority matrix
user_journeys:
- name: "User Login"
business_value: "high" # Login failure → immediate user churn
user_sensitivity: "high" # Users have zero tolerance for login failures
priority: P0
needs_slo: true
- name: "Product Search"
business_value: "high" # Search affects conversion rate
user_sensitivity: "medium" # Slightly slower search is acceptable
priority: P1
needs_slo: true
- name: "View Order History"
business_value: "medium"
user_sensitivity: "low"
priority: P2
needs_slo: false # Can be covered by default SLO
SLI Specification
A good SLI definition needs to include five elements:
# SLI specification template
sli_spec:
name: "Payment Request Success Rate"
# 1. Measurement subject
subject: "payment-service"
# 2. Measurement dimension
metric: "success rate"
# 3. Calculation formula
formula: |
Successful requests / Total requests
Success definition: HTTP status code not in [500, 599] range
Excluded: Client errors (4xx), health check requests (/healthz)
# 4. Measurement window
window: "30d"
# 5. Data source
source: "Prometheus http_requests_total metric"
Common SLI Patterns
| SLI Type | Calculation | Suitable Scenario |
|---|---|---|
| Availability | Successful requests / Total requests | All user-facing services |
| Latency | P99/P95 response time | All interactive services |
| Throughput | QPS / TPS | Batch processing, data pipelines |
| Correctness | Data validation pass rate | Data stores, message queues |
| Freshness | Data update time < N minutes | Caches, indexes, reports |
| Coverage | Indexed data / Total data | Search engines |
| Durability | Non-lost data / Total data | Object storage, databases |
Common SLI Definition Mistakes
Mistake 1: Using resource metrics as SLIs
# ❌ Wrong: CPU utilization is not an SLI
sli:
metric: "CPU utilization < 80%"
why_wrong: "At 80% CPU, users may not notice anything, or latency may already be severely impacted"
# ✅ Correct: Define from user perspective
sli:
metric: "Request P99 latency < 200ms"
why_right: "Directly reflects the experience users perceive"
Mistake 2: Overly coarse aggregation
# ❌ Wrong: Global success rate
sli:
metric: "All HTTP request success rate > 99.9%"
why_wrong: "Health check requests and payment requests are mixed together, masking critical path issues"
# ✅ Correct: Define separately for critical paths
sli:
metric: "Payment API success rate > 99.99%"
sli:
metric: "Product API success rate > 99.9%"
Mistake 3: Only looking at averages
# ❌ Wrong: Average latency
sli:
metric: "Average latency < 100ms"
why_wrong: "Average latency masks the long tail — 1% of users may wait 5 seconds"
# ✅ Correct: Use percentiles
sli:
metric: "P99 latency < 200ms"
sli:
metric: "P95 latency < 100ms"
3. SLO Target Value Methodology
Core Principle of SLO Setting
SLOs should be set above the threshold where “users start to notice problems,” but not so high that there’s no error budget to spend.
This means SLOs have two boundary constraints:
- Lower bound: Below user tolerance → poor user experience → impacts business
- Upper bound: Above actual capability → no error budget → can’t release new features
Historical Data-Based SLO Calibration
The most reliable SLO setting method is based on historical data:
# SLO calibration analysis
def calibrate_slo(historical_sli_data, user_satisfaction_threshold):
"""
historical_sli_data: SLI data from the past 90 days
user_satisfaction_threshold: User satisfaction threshold
"""
# 1. Calculate historical SLI distribution
p50 = percentile(historical_sli_data, 50)
p90 = percentile(historical_sli_data, 90)
p99 = percentile(historical_sli_data, 99)
p999 = percentile(historical_sli_data, 99.9)
# 2. Find the user satisfaction inflection point
# The SLI value where user satisfaction suddenly drops is the SLO lower bound
satisfaction_inflection = find_inflection_point(
historical_sli_data,
user_satisfaction_threshold
)
# 3. Set SLO above the inflection point with a safety margin
suggested_slo = satisfaction_inflection * 1.1 # 10% safety margin
return {
"historical_p50": p50,
"historical_p99": p99,
"satisfaction_inflection": satisfaction_inflection,
"suggested_slo": suggested_slo,
"error_budget": 1 - suggested_slo
}
SLO Target Selection Guide
| SLO Target | Error Budget/Month | Suitable Scenario | Setting Conditions |
|---|---|---|---|
| 99% | 432 minutes | Internal tools, non-critical services | Tolerates higher unavailability |
| 99.5% | 216 minutes | Backend services, batch processing | Moderate availability requirements |
| 99.9% | 43.2 minutes | General user-facing services | Default choice for most services |
| 99.95% | 21.6 minutes | Important business services | Has redundancy and automatic failover |
| 99.99% | 4.3 minutes | Core business services | Multi-active architecture, comprehensive self-healing |
| 99.999% | 0.43 minutes | Very few critical services | Usually impractical, extremely high cost |
SLO Setting Decision Process
Step 1: Determine the service's business tier
→ L1 Critical / L2 Important / L3 Standard / L4 Auxiliary
Step 2: Analyze historical data
→ How has the SLI performed over the past 90 days?
→ What's the P50 / P95 / P99 distribution?
Step 3: Identify user tolerance
→ At what SLI level do users start complaining?
→ Historically, at what SLI level did business metrics get affected?
Step 4: Select initial SLO
→ Based on historical P99 or P99.9 performance, set a target slightly above current level
→ Leave sufficient error budget for releases and innovation
Step 5: Trial run validation
→ Set a 4-6 week trial period
→ Observe feasibility and whether it reflects real user experience
Step 6: Official release and periodic review
→ After trial passes, officially activate
→ Review SLO reasonableness monthly/quarterly
Initial SLO Setting Strategy for New Services
For new services without historical data:
# New service SLO initial setting strategy
new_service_slo_strategy:
phase_1: "Trial period (first 4 weeks)"
action: "Monitor only without setting SLO, collect baseline data"
goal: "Understand the natural distribution of SLIs"
phase_2: "Initial SLO (weeks 5-8)"
action: "Set a conservative SLO based on baseline data"
strategy: |
Availability SLO = Historical lowest availability + 0.5%
Latency SLO = Historical P99 × 1.2
goal: "Validate SLO feasibility"
phase_3: "Official SLO (from week 9)"
action: "Adjust based on trial data and officially release"
review_cycle: "Monthly review"
4. SLO Review Process
Why Regular Reviews Are Needed
SLOs aren’t set in stone. The following situations require re-evaluating SLOs:
- User expectation changes: Users’ tolerance for latency may decrease as competitors improve
- Business priority changes: Previously unimportant features may become critical
- Technical architecture changes: From monolith to distributed, from sync to async — SLOs need corresponding adjustments
- SLO too loose: Long-term non-consumption of error budget suggests the SLO can be tightened
- SLO too strict: Error budget always running out suggests the SLO needs to be relaxed or investment in improvement is needed
Review Content
# SLO Quarterly Review Template
## Review Scope
- Service name: payment-service
- Review period: 2026 Q2
- Participants: SRE lead, service owner, product manager
## Current SLOs
| SLI | SLO Target | Actual Performance | Error Budget Consumed |
|-----|---------|---------|-------------|
| Availability | 99.95% | 99.97% | 40% |
| Latency (P99) | <200ms | 185ms | 25% |
| Latency (P95) | <100ms | 92ms | 10% |
## Review Questions
### 1. Does the SLO reflect user experience?
- [ ] Is the user complaint volume correlated with SLO violations?
- [ ] Are there user-perceived issues not covered by SLIs?
- Analysis: A latency degradation in March wasn't captured by P99 SLO, but users complained
→ Need to add P95 latency SLI ✅
### 2. Is the SLO too loose or too strict?
- [ ] Is the error budget always used up? → No, 40% consumed
- [ ] Is the error budget always surplus? → Availability budget 40%, latency budget 25%
- Analysis: Latency SLO consumption is low; consider tightening
→ Latency P99 SLO from 200ms to 180ms ⚠️
### 3. Do we need to add or remove SLIs?
- [ ] Are there new critical user journeys to cover?
- [ ] Are there SLIs that are no longer relevant?
- Analysis: Added "payment callback latency" SLI to cover the async part of the payment flow
→ New SLI: Payment callback P99 < 5s ✅
### 4. Is the SLO cost reasonable?
- [ ] What's the infrastructure cost of maintaining the current SLO?
- [ ] What's the cost of upgrading the SLO to the next level?
- Analysis: Upgrading from 99.95% to 99.99% requires multi-active architecture, cost increases 200%
→ Don't upgrade for now; current SLO meets business needs ✅
## Review Conclusions
- Availability SLO: Maintain 99.95%
- Latency P99 SLO: Tighten from 200ms to 180ms
- Add latency P95 SLO: <100ms
- Add payment callback SLO: P99 < 5s
- Next review: 2026 Q3
SLO Review Decision Tree
Error budget consumption rate
│
├─ < 25% (long-term)
│ → SLO may be too loose
│ → Evaluate whether to tighten SLO
│ → Or use the surplus for innovation
│
├─ 25-75%
│ → SLO is reasonable
│ → Maintain current SLO
│
└─ > 75% (long-term)
→ SLO may be too strict
→ Evaluate whether to relax SLO
→ Or invest resources to improve system capability
5. Multi-Tier SLOs
Why Multiple Tiers Are Needed
A single-tier SLO can’t simultaneously meet the needs of “reflecting user experience” and “guiding technical decisions.” Users care about “does checkout succeed,” while operations cares about “is the database connection pool sufficient” — these need different SLO tiers to bridge.
Three-Tier SLO Architecture
┌──────────────────────────────────────────────────┐
│ User Experience SLO │
│ "Can users smoothly complete critical operations?"│
│ → Defined from user perspective, business-facing │
└───────────────────────┬──────────────────────────┘
│ Decompose
┌───────────────────────▼──────────────────────────┐
│ Service SLO │
│ "Does each service meet its interface contract?" │
│ → Defined from inter-service call perspective │
└───────────────────────┬──────────────────────────┘
│ Decompose
┌───────────────────────▼──────────────────────────┐
│ Resource SLO │
│ "Are underlying resources healthy?" │
│ → Defined from infrastructure perspective │
└──────────────────────────────────────────────────┘
User Experience SLO
# User Experience SLO example: E-commerce checkout
user_experience_slo:
journey: "User Checkout"
sli_1:
name: "Checkout Success Rate"
formula: "Successful checkouts / Checkout requests"
target: 99.99%
window: 30d
user_impact: "Checkout failure directly causes transaction loss"
sli_2:
name: "Checkout End-to-End Latency"
formula: "Time from clicking 'Submit Order' to seeing 'Order Successful' page"
target: "P95 < 2s, P99 < 5s"
window: 30d
user_impact: "Latency over 5s may cause user abandonment"
sli_3:
name: "Checkout Page Availability"
formula: "Successful product page loads / Total visits"
target: 99.95%
window: 30d
user_impact: "Page won't load → immediate user churn"
Service SLO
# Service SLO example: Order service
service_slo:
service: "order-service"
sli_1:
name: "API Availability"
formula: |
Non-5xx responses / Total requests
Excluded: /healthz, /metrics
target: 99.95%
window: 30d
sli_2:
name: "API Latency"
formula: "P99 response time"
target: "< 500ms"
window: 30d
breakdown:
- endpoint: "POST /api/orders"
target: "P99 < 1s"
- endpoint: "GET /api/orders/{id}"
target: "P99 < 200ms"
- endpoint: "GET /api/orders"
target: "P99 < 500ms"
sli_3:
name: "Message Processing Latency"
formula: "Time from message enqueue to processing completion"
target: "P99 < 10s"
window: 30d
Resource SLO
# Resource SLO example: Database
resource_slo:
resource: "order-db (PostgreSQL)"
sli_1:
name: "Database Availability"
formula: "Time SELECT 1 succeeds / Total time"
target: 99.99%
window: 30d
sli_2:
name: "Query Latency"
formula: "P99 query execution time"
target: "< 50ms"
window: 30d
sli_3:
name: "Replication Lag"
formula: "Replica lag"
target: "< 1s"
window: 30d
sli_4:
name: "Connection Pool Health"
formula: "Available connections / Total connections"
target: "> 30%"
window: 5m # Resource SLOs typically use shorter windows
Cross-Tier Correlation and Decomposition
The three SLO tiers are not independent — they have causal relationships:
User Experience: Checkout success rate 99.99%
↑ Depends on
Service: Order API success rate 99.95% + Payment API success rate 99.99%
↑ Depends on
Resource: Database availability 99.99% + Cache availability 99.95%
Key principle: Achieving lower-tier SLOs is a prerequisite for achieving upper-tier SLOs, but not a sufficient condition.
Database availability of 99.99% doesn’t equal checkout success rate of 99.99% — there are application logic, network, caching, and other layers in between. Therefore, each tier needs independently defined SLOs.
SLO Cascading Alerts
# SLO cascading alert example
cascade_alerting:
# Resource-level alert: early warning
- level: resource
condition: "Database connection pool utilization > 80%"
action: "Notify SRE, don't notify business team"
purpose: "Intervene before service-level SLO is affected"
# Service-level alert: impact is occurring
- level: service
condition: "Order API error rate > 0.1%"
action: "Notify SRE + service owner"
purpose: "Prevent impact on user experience SLO"
# User experience-level alert: users are affected
- level: user_experience
condition: "Checkout success rate < 99.99%"
action: "Immediate page, notify entire team + management"
purpose: "Users are感知ing the problem; must restore immediately"
6. SLO Documentation
SLO Document Template
Each service’s SLO should have complete documentation:
# Service SLO: payment-service
## Service Overview
- Service name: payment-service
- Business tier: L1 (Critical)
- Responsible teams: Payment team + SRE platform team
- SLO review cycle: Quarterly
## Critical User Journeys
1. User initiates payment → Payment processing → Return result
2. Payment callback → Order status update → Notify user
## SLIs and SLOs
### SLI-1: Payment API Availability
- Definition: Non-5xx responses / Total requests (excluding /healthz)
- SLO: 99.99% (30-day window)
- Error budget: 4.3 minutes/month
- Data source: Prometheus http_requests_total
### SLI-2: Payment API Latency
- Definition: P99 response time
- SLO: < 2s (30-day window)
- Data source: Prometheus http_request_duration_seconds
### SLI-3: Payment Success Rate
- Definition: Successful payments / Initiated payments
- SLO: 99.95% (30-day window)
- Data source: Business logs + database statistics
## Alerting Strategy
- Fast burn: 1h window burn rate > 14x → Immediate page
- Slow burn: 6h window burn rate > 6x → Ticket tracking
- Budget exhausted: Monthly budget 100% → Freeze releases
## Dependencies
- Upstream dependencies: order-service, user-service
- Downstream dependencies: payment-db, redis-cluster, third-party payment gateway
- Shared infrastructure: API Gateway, Load Balancer
## History
| Date | Change | Reason |
|------|------|------|
| 2026-04-01 | Availability SLO raised from 99.95% to 99.99% | Business requirement |
| 2026-05-15 | Added payment callback latency SLI | Cover async path |
| 2026-07-01 | Latency SLO tightened from 2.5s to 2s | Historical performance exceeds SLO |
7. Case Studies
Case 1: Designing SLOs for a Search Service
Background: An e-commerce search service with 50 million daily queries. Users are sensitive to search speed.
Step 1: Business Goal Analysis
Search is the prerequisite step before users enter product detail pages
→ Slow search → Users abandon browsing → Transaction loss
→ No results → User churn
Business goal: Search experience directly impacts GMV
Step 2: User Journey Analysis
User enters keywords → Search request → Return results → User clicks product
Key experience dimensions:
1. Is search available? (Availability)
2. Is search fast enough? (Latency)
3. Are results relevant? (Correctness/Relevance)
4. Does search return results? (Coverage)
Step 3: SLI Definition
search_service_sli:
sli_1:
name: "Search API Availability"
formula: "Non-5xx search responses / Total search requests"
target: 99.95%
sli_2:
name: "Search P99 Latency"
formula: "P99(search response time)"
target: "< 300ms"
sli_3:
name: "Search P95 Latency"
formula: "P95(search response time)"
target: "< 100ms"
sli_4:
name: "Zero Result Rate"
formula: "Searches returning 0 results / Total searches"
target: "< 5%"
note: "Zero result rate reflects search quality, not a technical metric but affects user experience"
Step 4: SLO Calibration
# Calibration based on historical data
historical_data = {
"availability_p50": 99.98,
"availability_p99": 99.93,
"latency_p99_avg": 250, # ms
"latency_p99_max": 450, # ms
"zero_result_rate_avg": 3.2, # %
}
# SLO setting
slo = {
"availability": 99.95, # Slightly below P50, leaving budget
"latency_p99": 300, # Slightly above average, achievable
"latency_p95": 100, # Stricter, drives optimization
"zero_result_rate": 5, # Allow some zero results
}
Case 2: Hierarchical Decomposition of Microservice SLOs
Background: An e-commerce platform with 15 microservices, needing to build an SLO system from the platform level down to individual services.
Hierarchical Decomposition:
Platform-level SLO (user-facing)
├── Checkout success rate > 99.9%
├── Search availability > 99.95%
└── Payment success rate > 99.95%
│
├── order-service SLO
│ ├── API availability > 99.95%
│ └── API P99 < 500ms
│ │
│ ├── order-db SLO
│ │ ├── Availability > 99.99%
│ │ └── Query P99 < 50ms
│ │
│ └── redis SLO
│ ├── Availability > 99.95%
│ └── Hit rate > 90%
│
├── payment-service SLO
│ └── ...
└── inventory-service SLO
└── ...
Key Decision: Each service’s SLO target should be stricter than the platform-level SLO it supports, because errors from multiple services compound:
Platform-level: Checkout success rate 99.9%
= order-service(99.95%) × payment-service(99.95%) × inventory-service(99.95%)
= 0.9995^3 = 0.9985 = 99.85%
→ Doesn't meet 99.9% platform-level SLO!
Need: Each service at least 99.97% → 0.9997^3 = 0.9991 = 99.91% ✅
8. SLO Toolchain
SLO Monitoring and Visualization
# Prometheus + Grafana SLO monitoring
slo_monitoring:
prometheus_rules:
# SLO achievement rate
- record: slo:availability:rate30d
expr: |
sum(rate(http_requests_total{status!~"5.."}[30d]))
/
sum(rate(http_requests_total[30d]))
# Error budget consumption
- record: slo:error_budget:consumed:rate30d
expr: |
1 - (slo:availability:rate30d / 0.9999)
# Remaining error budget
- record: slo:error_budget:remaining:ratio
expr: |
1 - (slo:error_budget:consumed:rate30d / (1 - 0.9999))
grafana_dashboards:
- "SLO Overview Dashboard"
panels:
- "Current SLI value vs SLO target"
- "Error budget consumption trend"
- "SLO achievement history"
- "SLO status grouped by service"
SLO as Code
# slo-spec.yaml - SLO specification as code
apiVersion: sre/v1
kind: ServiceSLO
metadata:
name: payment-service-slo
service: payment-service
spec:
window: 30d
targets:
- name: availability
sli:
source: prometheus
query: |
sum(rate(http_requests_total{service="payment",status!~"5.."}[{{.window}}]))
/
sum(rate(http_requests_total{service="payment"}[{{.window}}]))
slo: 0.9999
alerts:
- burn_rate: 14
window: 1h
severity: page
- burn_rate: 6
window: 6h
severity: ticket
- name: latency_p99
sli:
source: prometheus
query: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket{service="payment"}[{{.window}}])) by (le)
)
slo: 2.0
comparison: less_than
Summary
SLO design is a complete engineering method from business goals to technical metrics. Key points:
- Start from business: The starting point for SLOs is business goals, not technical metrics. First ask “what does the business need,” then ask “how do we measure it technically.”
- User journey-driven: Through Critical User Journey (CUJ) analysis, define SLIs from the user’s perspective to ensure SLOs reflect real user experience.
- Data-calibrated: Set SLOs based on historical data, avoid guessing. Validate feasibility with trial runs, continuously optimize through regular reviews.
- Multi-tier design: User experience → Service → Resource, three tiers of SLOs that are interrelated yet independently defined.
- Drive action: The value of SLOs lies in driving decisions — error budget consumption strategies, release governance, improvement priorities. An SLO that isn’t used is the same as having no SLO.
A good SLO system has the following indicators:
- SLOs reflect real user experience — when users complain, SLOs must be in the red
- Error budgets drive release decisions — teams trust and rely on budget status
- SLOs have hierarchical correlation — lower-tier SLO anomalies provide early warning for upper-tier SLO risks
- SLOs continuously evolve — there’s a review and adjustment every quarter
Finally, remember: SLOs are not goals — they’re tools. Their value lies not in the number itself, but in how many valuable engineering decisions they drive.
References & Acknowledgments
This article referenced the following materials during writing. We thank the original authors for their contributions:
- Google SRE Workbook - Service Level Objectives — Google SRE Team, referenced for Google SRE Workbook - Service Level Objectives