What is pipeline duration, and how do you measure it in Metabase?
Pipeline duration is the wall-clock time from the start of a CI run to its finish, reported as a median and a p95 per pipeline. It is the length of every developer's feedback loop — and a big input into lead time for changes. Measure it in Metabase from run history synced from Jenkins, Buildkite, CircleCI, or Azure DevOps Pipelines.
What does pipeline duration measure?
It measures how long a developer waits between pushing and knowing. That wait compounds: slow pipelines push people into batching changes, batching inflates review size and risk, and both drag on deployment frequency and lead time for changes. Three decisions make the number trustworthy:
- Percentiles, not averages. Durations are right-skewed — cold caches, dependency bumps, and busy runners create a long tail. The median is the typical experience; the p95 is the worst-case loop that sets how long people actually plan to wait.
- Queue time apart from run time. Time from
queued_attostarted_atis a capacity problem; time fromstarted_atto finish is a pipeline problem. Summing them hides which one you have. - Per pipeline, trended weekly. A fleet-wide number mixes a three-minute lint job with an hour-long release build. Segment by pipeline and watch the week-over-week drift — durations creep, they rarely jump.
What data does it need?
- A
pipeline_runstable:pipeline_name,branch,result,started_at,duration_seconds. - A
queued_attimestamp, so queue time can be computed asstarted_at - queued_atand tracked on its own. - Run outcomes, so the duration series can be scoped to successful runs — failed runs end early and distort the distribution.
SQL patterns
SELECT
date_trunc('week', started_at) AS week,
COUNT(*) AS runs,
ROUND((percentile_cont(0.5) WITHIN GROUP (
ORDER BY duration_seconds
))::numeric / 60, 1) AS median_minutes,
ROUND((percentile_cont(0.95) WITHIN GROUP (
ORDER BY duration_seconds
))::numeric / 60, 1) AS p95_minutes
FROM pipeline_runs
WHERE result = 'success'
GROUP BY 1
ORDER BY 1;SELECT
pipeline_name,
ROUND((percentile_cont(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM started_at - queued_at)
))::numeric / 60, 1) AS median_queue_minutes,
ROUND((percentile_cont(0.5) WITHIN GROUP (
ORDER BY duration_seconds
))::numeric / 60, 1) AS median_run_minutes
FROM pipeline_runs
WHERE result = 'success'
AND started_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY pipeline_name
ORDER BY median_queue_minutes DESC;SELECT
pipeline_name,
COUNT(*) AS runs,
ROUND((percentile_cont(0.5) WITHIN GROUP (
ORDER BY duration_seconds
))::numeric / 60, 1) AS median_minutes,
ROUND((percentile_cont(0.95) WITHIN GROUP (
ORDER BY duration_seconds
))::numeric / 60, 1) AS p95_minutes
FROM pipeline_runs
WHERE result = 'success'
AND started_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY pipeline_name
HAVING COUNT(*) >= 20
ORDER BY p95_minutes DESC
LIMIT 15;Pitfalls
queued_at to started_at as its own series before spending a sprint on caching.Where this metric applies
- Jenkins + Metabase — build durations and queue times per job
- CircleCI + Metabase — workflow and job timings per project
- Buildkite + Metabase — build and wait times per pipeline
- Azure DevOps Pipelines + Metabase— run durations across pipelines
- GitHub Actions + Metabase — workflow run timings per repository
- GitLab CI + Metabase — pipeline durations by ref
Related
Metrics
Dashboards
FAQ
Should failed runs count toward pipeline duration?
result = 'success', state the convention on the dashboard, and if fail-fast behavior interests you, chart failed-run duration as its own series.What is a good pipeline duration?
Why report median and p95 instead of the average?
percentile_cont computes both in one pass, as in the SQL patterns above.Is queue time part of pipeline duration?
started_at to finish) reflects the work in the pipeline: caching, parallelism, test bloat. Queue time (queued_at to started_at) reflects runner capacity, and when agents are saturated it can dwarf run time while every per-step optimization does nothing. Developers experience the sum, so chart both on the CI pipeline health dashboard, but diagnose them apart.How do you track pipeline duration in Metabase?
queued_at, started_at, and duration per run. Define median and p95 once as saved questions with percentile_cont, trend them weekly per pipeline, and put the slowest-pipelines table next to build success rate on a CI pipeline health dashboard.