Mission 2.4 · Stage 2 — Self-Service Infrastructure, Automation, and Measuring the Platform
Measuring the Platform: DORA, Developer Experience, and Cost
Goal: A platform dashboard showing DORA metrics per team, golden-path adoption, developer satisfaction, and cost per team, used to steer the platform roadmap.
By the end of this mission
- Define and collect the four DORA metrics (plus reliability)
- Measure developer experience with surveys and the SPACE framework
- Show cost per team with OpenCost and tags
- Run the platform as a product: SLOs for the platform itself and a roadmap from data
Part 1
Understand it first
DORA metrics
From the DevOps Research and Assessment program, the best-validated delivery metrics: DEPLOYMENT FREQUENCY (how often you ship to production), LEAD TIME FOR CHANGES (commit to production), CHANGE FAILURE RATE (share of deployments causing a failure that needs remediation), and FAILED DEPLOYMENT RECOVERY TIME (how long to restore after a bad deploy). Later reports add RELIABILITY (meeting SLOs). Throughput and stability move together in high performers; speed and safety are not a trade-off when the platform is good.
With GitOps, the data is already in your systems: commits and PR merges (GitHub), deploys (Argo CD sync events or config-repo commits), and failures and restores (incidents, rollbacks, reverts). Measure per team and watch trends, and never use them to rank individuals, or the numbers get gamed.
Developer experience
Metrics from systems miss friction that only people feel: flaky tests, slow local builds, confusing docs, waiting on reviews. The SPACE framework (Satisfaction, Performance, Activity, Communication and collaboration, Efficiency and flow) reminds you to combine perception data (a short quarterly survey: 'how easy is it to deploy a change?', 'what slowed you down this month?') with system data. The DX Core 4 and similar frameworks package the same idea.
Cost visibility
OPENCOST (CNCF) allocates Kubernetes cost to namespaces, labels, and teams using real cloud prices, including idle capacity. Combined with AWS cost allocation tags (set by Terraform, Crossplane compositions, and Karpenter) you can show each team its spend (SHOWBACK) or bill it (CHARGEBACK). Visibility alone typically changes behaviour: right-sizing requests, deleting stale previews (Mission 2.3), and using Spot (Mission 0.3).
The platform's own SLOs
The platform is a product with users, so it gets SLOs (SRE course): 'golden-path template succeeds 99% of the time', 'CI queue time p90 < 2 minutes', 'Argo CD sync of a merged change < 5 minutes', 'portal availability 99.5%'. When the platform breaks, every team is blocked, so platform incidents deserve the same rigour as customer incidents.
Part 2
Your project after this mission · 4 files change
- shoplite-platform/
- addons/
- opencost/
- opencost-app.yamlnew
- docs/
- dx-survey.mdnew
- metrics/
- dora-queries.sqlnew
- platform-slos.yamlnew
Part 3
Build it, step by step
- 1
Collect deployments and changes
Apache DevLake (or Google's Four Keys, or a commercial tool) ingests GitHub, Argo CD, and incident data and computes DORA metrics out of the box. Whatever the tool, the model is three tables: CHANGES (commit SHA, time), DEPLOYMENTS (SHA, environment, time, success), and INCIDENTS (start, end, caused-by deploy). These queries show the calculations, so you understand the numbers the dashboards print.
shoplite-platform/metrics/dora-queries.sqlwhole filesql -- Deployment frequency: prod deploys per team per week SELECT team, date_trunc('week', deployed_at) AS week, count(*) AS deploys FROM deployments WHERE env = 'prod' GROUP BY 1, 2; -- Lead time for changes: median commit → prod deploy, last 30 days SELECT d.team, percentile_cont(0.5) WITHIN GROUP (ORDER BY d.deployed_at - c.committed_at) AS median_lead_time FROM deployments d JOIN changes c ON c.sha = ANY (d.shas) WHERE d.env = 'prod' AND d.deployed_at > now() - interval '30 days' GROUP BY d.team; -- Change failure rate: share of prod deploys linked to an incident or rollback SELECT team, round(100.0 * count(*) FILTER (WHERE caused_incident) / count(*), 1) AS change_failure_pct FROM deployments WHERE env = 'prod' AND deployed_at > now() - interval '90 days' GROUP BY team; -- Failed deployment recovery time: median incident duration for deploy-caused incidents SELECT team, percentile_cont(0.5) WITHIN GROUP (ORDER BY resolved_at - started_at) AS median_recovery FROM incidents WHERE caused_by_deploy IS NOT NULL GROUP BY team; - 2
Install OpenCost
Chart
opencostfromhttps://opencost.github.io/opencost-helm-chart, pointed at the cluster's Prometheus. Then query cost per team label.terminal$ kubectl -n opencost port-forward svc/opencost 9003:9003 &curl -s 'localhost:9003/allocation/compute?window=7d&aggregate=label:shoplite.dev/team' | jq -r '.data[0] | to_entries[] | "\(.key)\t$\(.value.totalCost|floor)"'── expected output ──checkout $412storefront $298catalog $187fulfilment $96__idle__ $341 - 3
Give the platform SLOs
Written with Sloth (or Pyrra), which generates Prometheus recording and burn-rate alert rules (Observability course, burn-rate alerts). Check the exact metric names your Backstage and Argo CD versions export (
/metrics) before copying queries.shoplite-platform/metrics/platform-slos.yamlwhole fileyaml version: prometheus/v1 service: shoplite-platform slos: - name: golden-path-success objective: 99 description: Backstage scaffolder runs that complete successfully. sli: events: error_query: sum(rate(scaffolder_task_count{result="failed"}[{{.window}}])) total_query: sum(rate(scaffolder_task_count[{{.window}}])) alerting: { name: GoldenPathFailing, page_alert: { disable: true } } - name: gitops-sync-success objective: 99.5 description: Argo CD sync operations that succeed. sli: events: error_query: sum(rate(argocd_app_sync_total{phase!="Succeeded"}[{{.window}}])) total_query: sum(rate(argocd_app_sync_total[{{.window}}])) - 4
Ask developers
A five-question survey, every quarter, the same questions so trends are comparable. Free-text answers are the most valuable part: they become roadmap items.
shoplite-platform/docs/dx-survey.mdwhole filemarkdown # ShopLite developer experience survey (5 minutes) 1. How easy is it to get a change into production? (1 very hard – 5 very easy) 2. How often did tooling or the platform block you this quarter? (never / monthly / weekly / daily) 3. How confident are you when you deploy? (1–5) 4. How easy was it to find the information you needed (docs, owners, runbooks)? (1–5) 5. What single thing slowed you down most this quarter? (free text)
Checkpoint — you should now have
- ✓A dashboard shows DORA metrics per team with a 90-day trend.
- ✓OpenCost shows spend per team, including idle capacity.
- ✓The platform has its own SLOs with alerts.
- ✓The next quarter's platform roadmap cites survey and metric data.
Part 4
Break it on purpose
Make each change, run the command, and read the error before revealing the diagnosis. Recognising these messages on sight is what makes you fast on a real team. Undo the change afterwards.
Break #1
Metrics become targets
Leadership sets a goal: 'every team must deploy 20 times a week', and ranks teams on a leaderboard.
Part 5
Interview questions from this mission
What are the DORA metrics and how would you collect them?
How do you decide what to build next on the platform?