Skip to content

Simple guide · Overview

Page status: Active

NutsNews Service Level Objectives

Issue: https://github.com/ramideltoro/nutsnews/issues/89

Visual overview

Primary diagram

System map

Issue: https://github.com/ramideltoro/nutsnews/issues/89

Render the repository-owned system map when you need it.

Diagram is not rendered yet.

View as text
NutsNews Service Level Objectives

Issue: https://github.com/ramideltoro/nutsnews/issues/89

flowchart TB
  accTitle: NutsNews Service Level Objectives
  accDescr {
    Issue: https://github.com/ramideltoro/nutsnews/issues/89
  }
  A["NutsNews Service Level Objectives"] --> B["SERVICE_LEVEL_OBJECTIVES.md"]
  B --> C["Auto-generated placeholder diagram"]

NutsNews Service Level Objectives

Fullscreen diagram view.

Issue: https://github.com/ramideltoro/nutsnews/issues/89

App PR: https://github.com/ramideltoro/nutsnews/pull/241

This runbook defines the first explicit NutsNews SLOs, error budgets, alert thresholds, and incident classes for reader, API, Worker, feed freshness, translation, and backup health.

NutsNews now has promises for what “healthy” means. If the site, API, Worker, translations, or backups fall outside those promises, admins can see how serious it is and what to check next.

The target is a stable reader experience with clear operating limits. Homepage and /api/articles availability use a 99.5% monthly target, Worker ingestion needs recent successful runs, the public feed must stay fresh enough for readers, translations should be mostly complete for recent stories, and backup restore checks must stay current. The admin readiness dashboard now includes an “SLO and error budgets” card that rolls up existing readiness signals and links back to this policy.

Issue #89 adds an SLO/error-budget operating layer over existing NutsNews observability. The application repository adds a derived /admin/readiness signal in web/lib/adminProductionReadiness.ts; it does not create a new table, credential, external monitor, or provider mutation. The signal maps the existing readiness inputs for public API health, graceful degradation, Worker/controller freshness, DB growth/feed freshness, translation coverage, backup freshness, CI status, and configuration into a green/yellow/red SLO budget status. Historical availability and latency remain measured by external uptime, Lighthouse CI, Vercel, Cloudflare, and Grafana rather than by a new app-side metrics store.

SurfaceTargetGreen evidenceError budget / warningCritical breach
Homepage availability99.5% monthly availability for public reader entry points/healthz and homepage checks pass; admin readiness has no red reader signalAny confirmed downtime burns the monthly 216-minute budget; repeated yellow readiness states need reviewHomepage or /healthz confirmed timeout/5xx for 5 minutes or more
Homepage latencyp95 public document response under 2.5 seconds and Lighthouse performance budget passingLighthouse CI and preview smoke pass; Vercel/Cloudflare do not show sustained slow responsesp95 over target for 30 minutes or two consecutive CI quality regressionsSustained slow responses make the reader unusable or timeout-prone
/api/articles success99.5% monthly success rate for read-only article API calls/api/articles?limit=1 and /api/articles?home=1 return valid JSON; public-feed fallback is available5xx, timeout, invalid JSON, or maintenance-mode responses burn API budgetAPI timeout/5xx or invalid JSON for 10 minutes, especially without a feed fallback
/api/articles latencyp95 under 1.5 seconds for read-only API callsPreview smoke and public reader smoke pass; no sustained runtime slownessp95 over target for 30 minutes or repeated preview-smoke latency regressionsLatency causes client errors, timeouts, or homepage reader breakage
Worker/controller successful runs95% successful scheduled/controller runs over 30 days; latest success within 3 hours/admin/readiness Worker signal is green and /admin/shards shows healthy shardsLatest success older than 3 hours or intermittent run failuresLatest successful run older than 24 hours, latest run failed, or ingestion stops
Feed freshnessFull first page available from public_feed_snapshot or safe fallback; new published growth in 24 hoursPublic API health is green and DB growth is greenSnapshot short, DB fallback only, or no published growth in 24 hoursNo snapshot/fallback first page or no published growth in 7 days
Translation completionAt least 90% recent non-English summary rows available for the sampled recent articlesTranslation coverage card is greenCoverage below 90% or missing quality evidenceCoverage below 75% while multilingual content is being promoted
Backup freshnessLatest Supabase backup and disposable restore fire drill completed successfully within 30 hoursBackup freshness card is green and links to a successful workflow run/report artifactToken/API unavailable, run pending, skipped, neutral, missing, or stale without active mutationFailed/stale backup while a production mutation, incident recovery, or restore decision needs it
RuleValue
Monthly availability target99.5%
Approximate 30-day monthly downtime budget216 minutes
High-burn warning25% of the monthly budget consumed, about 54 minutes
Critical-burn threshold50% of the monthly budget consumed, about 108 minutes, or any active reader/data/recovery risk
Review windowMonthly, with immediate review for critical incidents

Budget burn is tracked from external uptime evidence, GitHub Actions failures, admin readiness history, provider dashboards, and incident notes. Until NutsNews has a dedicated time-series SLO store, the readiness dashboard is the live status surface and this runbook is the source of truth for target thresholds.

SignalMediumHighCritical
Homepage availabilityIntermittent check failure that self-recoversConfirmed outage under 5 minutes or repeated flappingConfirmed outage for 5 minutes or more
Homepage latencyOne CI or dashboard warningp95 over target for 30 minutesReader requests timing out or failing because of latency
/api/articles successSingle failed smoke/API checkRepeated invalid JSON, timeout, or 5xx under 10 minutesTimeout/5xx/invalid JSON for 10 minutes
/api/articles latencyOne preview-smoke or runtime warningp95 over 1.5 seconds for 30 minutesLatency causes public feed failure or homepage timeout
Worker/controllerLatest success older than 3 hoursLatest run failed or ingestion delayed for a business dayLatest success older than 24 hours and public feed freshness is threatened
Feed freshnessSnapshot short but DB fallback existsNo published growth in 24 hours or edge snapshot staleNo first-page feed fallback or no published growth in 7 days
Translation completionRecent coverage below 90%Coverage below 75% but English fallback worksTranslation failure blocks publication or breaks reader content
Backup freshnessBackup status unknown or token unavailableRestore check stale/failed without active mutationBackup unusable while recovery or production mutation depends on it

NutsNews uses Critical, High, and Medium incident classes for SLO/error-budget decisions. These map to the incident response policy as follows:

SLO classIncident policy mappingMeaningResponse
CriticalSEV1Active reader outage, data risk, security risk, or recovery riskImmediate owner contact, mitigation within 15 minutes, post-incident review
HighSEV2Production degraded, release blocked, or budget burn likely to become reader/recovery riskOwner email or issue/PR update within 4 hours, scoped fix with evidence
MediumSEV3Maintenance warning or observability gap that does not threaten the current reader pathTrack in backlog or next maintenance window

Use the highest class that matches the evidence. A backup failure is Medium when no mutation is planned, High when it blocks a release, and Critical when recovery or a production mutation needs that backup.

The application readiness dashboard now includes an SLO and error budgets signal. It is derived from:

  • public-api-health
  • graceful-degradation
  • worker-controller
  • db-growth
  • translation-coverage
  • backup-freshness
  • ci-status
  • configuration

Green means the core live signals are inside the current budget. Yellow means one or more watch signals should be verified and classified as High or Medium. Red means at least one critical readiness signal is burning error budget and should be triaged against this runbook before promotion.

flowchart TD
A[Monitor, workflow, dashboard, or report detects a symptom] --> B[Open /admin/readiness]
B --> C[SLO and error budgets card]
C --> D{Red signal?}
D -->|Yes| E[Classify Critical or High]
D -->|No| F{Yellow signal?}
F -->|Yes| G[Classify High or Medium]
F -->|No| H[Within budget]
E --> I[Follow incident response policy]
G --> J[Create follow-up issue or maintenance task]
I --> K[Record budget burn and validation evidence]
J --> K
H --> L[Continue monthly SLO review]
  1. Open /admin/readiness before release promotion, cache policy changes, migrations, or recovery work.
  2. If the SLO card is red, pause promotion and classify the underlying red signal as Critical or High.
  3. If the SLO card is yellow, verify the linked dashboard or workflow and decide whether it is High or Medium.
  4. Record outage duration, affected surface, budget impact, linked workflows/dashboards, and validation evidence in the issue or incident notes.
  5. Reset the incident only after the same signal that detected the breach is green or manually verified.

No new environment variable, secret, database migration, provider credential, or external service permission is introduced by issue #89. Existing optional live readiness features still use:

  • SUPABASE_URL or NEXT_PUBLIC_SUPABASE_URL
  • SUPABASE_SERVICE_ROLE_KEY
  • ACTIONS_READ_TOKEN for server-side GitHub Actions status reads

External uptime, Grafana, Sentry, Vercel, Cloudflare, and Supabase dashboards remain provider-owned. Do not paste secrets, private URLs, tokens, raw environment files, or credential values into SLO notes.

RiskMitigation
The app signal looks like a complete historical SLO storeThe dashboard copy and this runbook state that historical budget burn still comes from external uptime, provider dashboards, workflows, and incident notes.
Targets drift from code thresholdsUpdate this file, PRODUCTION_READINESS_DASHBOARD.md, and web/lib/adminProductionReadiness.ts together when thresholds change.
Every yellow signal becomes urgentYellow signals must be classified as High or Medium by reader, data, and recovery impact.
A backup warning is under-prioritizedEscalate backup freshness to Critical whenever recovery or a production mutation depends on it.
Latency evidence is incompleteUse Lighthouse CI, preview smoke, Vercel, Cloudflare, and Grafana together until a dedicated latency SLO store exists.

Revert the app PR that adds the SLO and error budgets readiness signal, then revert this documentation file and the related production-readiness documentation updates. No database, secret, provider, Cloudflare, Vercel, Supabase, Grafana, or Sentry rollback is required.