How to Debug Why CI Is Slow
Slow CI has a small set of causes. Work through them in order instead of randomly tweaking the workflow.
Debug slowness top-down: is it waiting to start, or slow once running? Then narrow to the job, then the step.
1. Queue or run?
If created_at to started_at is large, you are queueing for runners; the fix is capacity. If run time is large, keep going.
2. Which job is on the critical path?
Rank jobs by duration and account for needs: dependencies. Optimize the gating job.
3. Are caches hitting?
A logged "cache miss" every run means a broken key. Caching is usually the biggest single lever, so fix this first.
4. Is the work parallelizable?
A long serial test job should be sharded across parallel runners.
5. Is the runner under-resourced?
Steps that swap or thrash on disk point to too little RAM/disk. Right-sized runners (like Latchkey) remove that ceiling instead of forcing a fixed GitHub-hosted tier.
Key takeaways
- Decide queue-bound vs run-bound first.
- Fix cache misses before micro-optimizing.
- Under-resourced runners cause hidden slowness.