Q38 of 48 · Cypress

What's your strategy for keeping a 1000+ test suite under 30 minutes in CI?

CypressSeniorcypressci-speedscalingperformancesenior

Short answer

Short answer: Shard across N runners (Cypress Cloud or duration-balanced manual sharding), aggressively use `cy.session` and API login to skip UI auth, intercept slow third parties, push tests down the pyramid where possible, and quarantine flakes immediately. Combine these and 30 minutes for 1000 tests is realistic.

Detail

Each lever scales differently — combine them.

1. Sharding (biggest lever). Split specs across N CI machines. Cypress Cloud auto-balances by historical duration; manual sharding (--spec lists computed from duration logs) gets you 80% of the way. With 8 shards, a 30-minute total suite needs each shard ~4 minutes — very achievable.

2. cy.session + API login. UI login on every test is the single biggest waste in most suites. With cacheAcrossSpecs, login happens 4-8 times across the whole suite (once per role) instead of 1000 times. Easily saves 10+ minutes.

3. Intercept slow third parties. Stripe, analytics, telemetry — anything that adds latency. cy.intercept('POST', 'https://api.stripe.com/*', { statusCode: 200 }). Tests run against deterministic stubs.

4. Push down the pyramid. Audit specs that test logic that has no UI behaviour — rule evaluation, data formatting. Move those to unit/integration tests that run in seconds. The E2E suite shrinks; coverage doesn't.

5. Tagged subsets per CI gate. Smoke (5-10 critical paths) on every PR; full regression on PR-to-main; nightly sweep including slower specs. Most PRs only run smoke, which is sub-5 minutes.

6. Quarantine flakes day one. A 20-test flake quarantine that re-runs in a separate, allowed-to-fail job keeps the main suite trustworthy. Treat flake quarantine as a 7-day backlog with named owners.

7. Cache the Cypress binary, node_modules, and Chrome. Cold install takes 1-2 minutes per shard; with caching it's seconds. The CI provider's docs cover this.

8. testIsolation true (default). Don't fight it; embrace it. With cy.session, isolation isn't expensive.

9. Avoid cy.wait(N) in any form. Replace blanket waits with aliased intercepts.

10. Profile your slowest 20. cypress run --reporter mocha-junit-reporter produces per-test timings. The slowest 20 tests usually account for 30-50% of total time. Optimise those specifically (intercepts, login skip, scope reduction).

A practical baseline: 8 shards × 4 minutes per shard = ~30 minutes wall time, ~32 minutes total CI minutes. Anything more than that and one of the levers above is missing.

// WHAT INTERVIEWERS LOOK FOR

Multiple compounding levers (sharding, session caching, intercept, pyramid pushdown), profiling-first mindset, and quarantine discipline. Specific numbers ('8 shards × 4 min') signal hands-on experience.

// COMMON PITFALL

Reaching only for sharding — yes, it scales, but if every test does UI login you're paying that cost on every shard. Combine levers.