Glidepath · Report · Pipeline performance

Where does a Glidepath pipeline spend its time?

Builds felt slow, and I didn't want to guess why. So I pulled every PipelineRun from Tekton Results and measured where the time went. The answer surprised me: outside the build itself, most of a pipeline's wall-clock was pods starting up to do almost nothing.

Report October 8, 2026Evidence 1,596 PipelineRuns and 7,414 TaskRuns from Tekton Results, Sep 17 to Oct 9, 2026Closed October 9, 2026
8 of 9 done · closed Oct 9, 2026

Most of the time was overhead, not work.

The build stage is the only pipeline where most of the wall-clock is real work. In most of the others, more than three quarters of the time went to scheduling pods and starting containers. Eight of the nine recommendations shipped the next day without dropping a single result, event or gate. The ninth, building amd64 images under emulation, is deferred, and it's still the biggest remaining cost.

Where the time goes

Work versus overhead per pipelineMedian wall-clock per Glidepath pipeline, split into step work and overhead. Build is 76 percent work; deploy is 23 percent; release 15; governance-check 13.P50 WALL-CLOCK, SECONDSbuild476s · 76% worktest176s · 43% workdeploy116s · 23% workrelease151s · 15% workimage-scan-check122s · 30% workprovenance-check115s · 56% worksast-check94s · 22% worksbom-check85s · 21% workgovernance-check77s · 13% workimage-promotion150s · 61% workrelease-notify53s · 21% workLEGENDstep workscheduling and start-up
Figure 1Amber is time spent running steps. The rest is pods being scheduled, init containers, result propagation and the reconcile loop.

Across all 7,414 TaskRuns, the gap between a TaskRun starting and its first step running was 14 seconds at the median, 40 at p90 and 105 at p99. That tracked node load, not pipeline design: the daily p90 swung from 15 seconds to almost six minutes.

Nine fixes, ranked by gain over effort

Each one had to keep every existing feature, result name, event and gate.

1. Stop building amd64 under emulation when nothing runs it

Deferred

The amd64 leg is cross-built under QEMU and is the slowest step on the platform: p90 664 seconds, worst case 46 minutes. Result: Backstage's build is still 25 minutes, 11 of them here.

2. Fix the dependency cache keys

Done

npm and Maven caches were keyed on the whole lockfile, so any dependency bump started from empty. Result: One shared cache directory per tool, also mounted for unit tests.

3. Collapse the zero-work pods

Done

Four to six pods before the work and five to six after, each paying a 14-second start-up tax to do under two seconds of work. Result: 13 pods to 4; a function build from 258-409s to 129s.

4. One vulnerability analysis per image

Done

Every scan pulled a 120 MiB database, and each image was analysed three times. Result: A shared Trivy server: the scan step takes 4 seconds.

5. Make release gates cheap and reliable

Done

Four gates full-cloned a repo to read one file, and one failed 48 percent of the time for a reason unrelated to security. Result: 135 of 284 failures were Release Record PRs, now excluded. A stub check retired (ADR-0025).

6. Turn off the Affinity Assistant on one node

Done

A StatefulSet and a placeholder pod per run, buying nothing on a single node. Result: 10 to 25 seconds and one StatefulSet less per run.

7. Shallow clones in the write-side tasks

Done

Eight tasks cloned full history to push one commit. Result: Target resolution reads the file over the API: 1 second.

8. Tell Argo CD about a dev deploy

Done

A pushed deploy sat unseen for up to two minutes waiting for the next poll. Result: A hard refresh, scoped by an admission policy: picked up in 4 seconds.

9. Semgrep rule fetch

Partly

Rules downloaded and metrics posted on every scan. Result: Metrics off. The fetch turned out to be under a second, so vendoring was dropped.

The biggest one, drawn

Collapsing the zero-work podsBefore, a stage ran thirteen pods, most doing under two seconds of work each. After, a preflight task and a debrief task replace eleven of them.BEFORE · ONE STAGE, 13 PODSamber: pods doing the real workAFTER · PREFLIGHT, THE WORK, DEBRIEFpreflightwas 4 to 6 podsthe real workunchangeddebriefwas 5 to 6 pods13 pods to 4.258 to 409s down to 129s.
Figure 2Item 3: every Task result and CDEvent kept its name, so nothing downstream changed. Measured on a real function build.

What caps every number above

Environment

A control plane under pressure

The scheduler and controller manager restarted 120 times in 16 days on lease timeouts. Each restart stalls scheduling for the whole cluster.

Fixed at close

Step pods were BestEffort

No requests on any Tekton container meant the lowest CPU share under contention. A cluster default now gives every step a small request.

Found on the way

Three bugs nobody had seen

Builds skipped when the pushed head was a merge commit, a grant that could have rewritten an Application, and a fallback to defaults on an unknown revision.