Engineering Apr 15, 2026 · 9 min read

Building CI/CD Pipelines That Don't Slow You Down

By the Aaganera Engineering Team

Building CI/CD Pipelines That Don't Slow You Down

Nobody notices a CI/CD pipeline the day it's built. They notice it eighteen months later, when a routine pull request takes twenty-five minutes to get a green check, engineers start batching changes to avoid triggering the pipeline twice, and "just merge it and see" quietly becomes the team's actual testing strategy. Pipeline slowness doesn't fail loudly — it fails by changing behavior. Engineers work around a slow pipeline long before anyone files a ticket about it, and by the time it becomes a visible problem, it's already been shaping (and shrinking) how often the team ships for months.

Where pipeline time actually goes

The default failure mode is running everything serially: install dependencies, run every unit test, run every integration test, build every artifact, then deploy — one step waiting on the previous one to finish completely. That structure is easy to set up and painful to live with, because the pipeline's total time is the sum of every step's worst case, even when most of those steps don't depend on each other. The first real win is almost always parallelization: splitting the test suite across multiple workers, running independent build steps concurrently, and only serializing the steps that truly have a dependency (you can't deploy before the artifact exists, but you can absolutely run linting and unit tests at the same time).

The second big cost is redundant work between runs. Reinstalling every dependency from scratch on every single commit — when the lockfile hasn't changed — is pure waste. Caching dependency installs, build layers, and compiled artifacts between runs (keyed correctly, so a real dependency change still busts the cache) routinely cuts pipeline time by more than half on projects that hadn't touched their caching setup in a year. It's unglamorous work, but it's usually the highest-leverage change available.

Structuring feedback so it matches the risk

Not all tests deserve the same position in the pipeline. Fast unit tests that run in seconds should gate every pull request immediately — that's the feedback loop engineers actually use while writing code. Slower integration and end-to-end tests, which might take fifteen minutes and depend on spun-up services or seeded databases, belong in a separate stage that runs after the fast checks pass, not blocking every commit from the first second. This tiered structure means a developer gets a "something's broken" signal in under two minutes for the common cases, instead of waiting twenty minutes to find out they had a typo.

The same principle applies to deployment itself. Pushing straight from a merged PR to production in one step is a single point of failure with no safety net. A staged rollout — staging first, then a canary release to a small slice of production traffic, then a full rollout once the canary looks healthy — catches the class of bug that only shows up under real traffic patterns, without betting the whole user base on it. It costs a bit of latency between merge and full release, but it converts "a bad deploy takes down everyone" into "a bad deploy takes down five percent of traffic for ten minutes and gets caught automatically."

"A pipeline that takes twenty-five minutes doesn't just cost twenty-five minutes — it costs every shortcut an engineer takes to avoid running it."

The last piece is treating pipeline speed as a metric you actually monitor, not just a background utility you only think about when it breaks. Pass/fail status tells you whether the pipeline works; it tells you nothing about whether it's getting slower. Tracking median and p95 pipeline duration over time — the same way you'd track API latency — surfaces creeping regressions (a new test suite that quietly adds four minutes, a cache that stopped hitting) while they're still small, instead of after the team has already adapted its habits around them.

Signals worth checking in your own pipeline this quarter:

  • Are independent steps (lint, unit tests, separate build targets) actually running in parallel, or still queued one after another?
  • Is dependency and build-layer caching actually hitting, or silently rebuilding from scratch every run?
  • Do you know your median pipeline duration from three months ago, or would you have to guess?

A fast pipeline isn't a nice-to-have engineering luxury — it's what makes frequent, small, low-risk deploys possible in the first place. Every hour spent trimming pipeline time buys back dozens of hours of engineers actually trusting the process enough to ship.

Want engineering that ships fast without cutting corners?

See how our backend development team approaches delivery, or talk to us about your current pipeline.