How a B2B SaaS Team Cut CI Pipeline Time from 45 Minutes to 8
A 120-engineer SaaS team slashed CI from 45 min to 8 min using layer caching, parallel test sharding, and affected-test selection — without rewriting their test suite.
CI/CD & Delivery · beginner · 12 min read · 2300 words · By Sandip Das · Published
What this covers
- The Situation
- The Problem
- Constraints
- Options Considered
- The Solution
- Implementation
- Results
- What Went Wrong Along the Way
- Lessons Learned
- Apply It Yourself
Key numbers
| Metric | Before | After |
|---|---|---|
| Median CI duration (PR) | 45 min | 8 min |
| p95 CI duration (PR) | 62 min | 13 min |
| Dep install time (cache hit) | 12 min | 25 sec |
| Spurious failure rate | 4.0% | 0.3% |
| Monthly CI compute cost | ~$2 100 | ~$2 650 |
Key components
- GitHub Actions cache (actions/cache) — Stores and restores node_modules keyed on package-lock.json hash, eliminating redundant npm ci runs on cache hits.
- Jest --shard flag — Distributes test files across N parallel runners so wall-clock test time is divided by the number of shards.
- Affected-test selector script — Uses git diff to identify changed monorepo packages and restricts the test run to only those packages and their dependents on PR builds.
- Docker Buildx GHA cache — Persists Docker build layers between runs so only changed layers are rebuilt, cutting image build time from 3 min to under 1 min on cache hits.
- Flaky test quarantine — Moves historically flaky tests to a nightly suite, reducing spurious PR failures from 4% to under 0.3% and restoring engineer trust in the pipeline.
- Duration-based test sequencer — Sorts tests by historical runtime before sharding to balance shard wall-clock times and prevent one slow shard from becoming the bottleneck.
The Situation
A 120-engineer B2B SaaS company builds a multi-tenant workflow-automation platform. The backend is a Node.js monorepo (roughly 400 000 lines of TypeScript across 18 packages), the frontend is a React single-page application, and the data layer is PostgreSQL with a Redis cache. Infrastructure runs on AWS: EKS for services, RDS for the database, ElastiCache for Redis. CI runs on GitHub Actions with GitHub-hosted runners. The team ships to production roughly 15 times per week across three squads, and the engineering organisation had grown from 40 to 120 engineers over 18 months — the CI pipeline had not kept pace.
The rest of this case study — the trade-offs, the scaling numbers and the build prompt — is available to LearnXops members. Create an account or see membership.
Topics: ci-cd, testing, github-actions, caching, parallelism, developer-productivity
Related case studies
- How a 300-Engineer Monorepo Cut CI Time by 78% with Remote Caching and Affected-Only Builds
- How a B2B SaaS Platform Migrated 200 Services to GitOps with Argo CD
- How a B2B SaaS Team Cut Failed Deployments by 80% with Canary Releases and SLO-Driven Rollback
- Knight Capital 2012: How an Incomplete Deployment and a Reused Flag Lost $460 Million in 45 Minutes
- The Cloudflare July 2019 Outage: How One Regex Took Down a Global CDN
- The Cloudflare November 2025 Outage: How a Database Permission Change Broke Global Proxy Traffic