Yashveer Singh
Connect
<- All posts
Tech Debt and Refactoring12 min read

Why Your Test Suite Is Slow and How to Fix It

A test suite gets slow because of a few specific causes: tests that hit the database when they should not, integration tests masquerading as unit tests, expensive setup repeated per test, and tests that run sequentially when they could run in parallel. Each cause has a known fix, and the wins compound. Most teams can cut their suite time in half in a week.

Written by Yashveer Singh, founder of Yashveer Labs.

What you actually need to know

  • A slow test suite is almost always a small number of slow tests plus a fixable architectural issue. It is not a fact of life.
  • Profile the suite first. The 80/20 rule holds hard. Find the slowest 10 percent and you have found the cause.
  • Database access is the most common culprit. Either mock it or share connections across tests.
  • Parallelization is the largest single win when shared state allows it.
  • Flaky tests need a triage process, not a "we know about them" Slack channel.
CauseHow it shows upTypical fixWin
Real DB calls in unit testsA few seconds per testMock the data layer or transactional rollback5x to 20x on those tests
Expensive shared setupSlow first test, fast restModule-level setup, fixtures2x on suite
No parallelizationCPU sitting idle in CIWorker pools, per-worker DB2x to 4x on suite
Slow third-party callsOne test takes 30 secondsMock or use a recorded fixtureEliminates the dominator
Flakes triggering retriesCI takes 20% longer randomlyFix or quarantine flakesSteadier runs

The core argument

A slow test suite is the most underrated tax on engineering productivity I have seen. Each individual run might cost five minutes. A team running it twenty times a day across ten engineers is spending around fifteen engineer-hours a day waiting. Over a year that is real money, and that is before you count the times someone skips running tests locally because they are too slow and then breaks main.

The instinct I see most often is to live with the slowness because the suite "is what it is." That is almost always wrong. In every slow test suite I have profiled, the time is concentrated. A small number of tests account for most of it. A small number of structural decisions account for the slow tests. Fix those structural decisions and the suite becomes fast.

The work is not exotic. It is mostly identifying which tests are doing more than they should and changing them to do less. Mock the network call. Share the database connection. Hoist the expensive setup out of the per-test loop. Run things in parallel that have no business being sequential. None of this is hard. It just requires someone to actually look at the profile and care.

The teams that let test suites grow to twenty or thirty minute runs are the ones that have not given anyone the time to do this work. Once you do, the win is permanent and the team's whole rhythm improves.

The fixes in priority order

Profile first

Run the suite with timing and produce a sorted list of the slowest tests. Most runners support this. If yours does not, instrument it. The instinct to "just optimize everything" without measuring is how you spend a week and save thirty seconds.

Remove unnecessary database calls

A test that needs to verify a pure function should not be hitting Postgres. Move that test to a layer where the data is in memory. For tests that genuinely need the database, use transactional rollback so the data is reset for free at the end of the test instead of by a manual DELETE statement.

Hoist expensive setup

If every test in a file initializes the same expensive resource, do it once for the file. Most frameworks support module-level setup. The savings compound across hundreds of tests.

Mock external services

A test that calls a real third-party API is brittle, slow, and dependent on network. Use a recorded response or a stub. The contract tests for the external service should be separate and rare.

Parallelize

Once shared state is handled, the easiest 2x to 4x win on most suites is running tests in parallel. The blocker is usually a shared database. Solve that with per-worker databases or transactional isolation.

How long does it take

Suite sizeTime investmentExpected speedup
Small (under 500 tests)A day2x to 3x
Medium (500 to 5000 tests)A week3x to 5x
Large (5000+ tests)Two to three weeks3x to 10x

The reason the relative win grows with suite size is that bigger suites have more slow tests and more parallelization headroom. The absolute fix on each test is small. The compounding is what matters.

What a fast test suite looks like

  • Unit tests run in under 10 seconds locally.
  • The full suite runs in under 5 minutes in CI.
  • A failed test points at the cause within seconds of reading the failure.
  • Flakes are rare and tracked. New flakes get fixed or quarantined immediately.
  • Engineers run tests locally before pushing because the cost is low.

Expert opinion

I have walked into more than one engineering org where the test suite took 35 minutes and everyone treated it as immutable. Two weeks of focused work usually got it to under five minutes. The team's rhythm changed overnight. People started running tests locally again, broke main less often, and shipped faster. The investment is small and the return is huge. The only reason this work does not happen is that nobody is given the time, and the cost of not doing it is invisible because it is spread across everyone's calendar.

>

Yashveer Singh, founder of Yashveer Labs

How this played out on a real project

A SaaS team I worked with had a 40 minute test suite that everyone agreed was a problem but nobody was assigned to fix. I profiled it for an hour. Two facts stood out: 14 tests accounted for almost 18 minutes of the run, and the suite was running entirely sequentially because shared database state made parallelization unsafe.

In a week I refactored the slow tests to mock the database where they did not need it and use transactional rollback where they did. I added per-worker database isolation and turned on parallel execution. The suite went from 40 minutes to about 7 minutes, then to under 5 after a second pass on flakes. The team's velocity changed measurably the following month. The pattern is the same one I described in the test pyramid for SaaS and reinforced by end to end tests, when they help and when they hurt.

Common mistakes

  1. Living with a slow suite because "that's just how it is."
  2. Optimizing without profiling. The slow tests are not where you think.
  3. Adding more CI parallelism without fixing shared state. The tests will trample each other.
  4. Treating flakes as a known issue instead of fixing them. They teach the team to ignore CI.
  5. Mocking too aggressively until tests prove nothing about real behavior.
  6. Running integration tests on every commit. Run them on a slower cadence if they cannot be made fast.
  7. Deleting slow tests instead of fixing them. Coverage is harder to rebuild than speed is to fix.

A two week plan to fix it

  1. Day one. Profile the suite. Produce a sorted list of slowest tests.
  2. Days two to four. Refactor the top 10 percent. Mock the database where appropriate, hoist setup, mock external services.
  3. Days five to seven. Add per-worker database isolation. Turn on parallel execution. Confirm correctness.
  4. Week two. Audit and fix the top flakes. Establish a process for new flakes that gets them out of the suite within a day.
  5. Week two ongoing. Add a CI budget rule: any test slower than 5 seconds gets a comment. Any flake gets a ticket. Treat suite performance as a feature with an owner.
  6. Long term. Make this part of the tech debt audit you run quarterly so the suite stays fast as it grows.
FAQ

Frequently asked

Author

The person who wrote this

Yashveer Singh wrote this. Class 12, Commerce track, full stack developer. The categories do not align, which is the point. The work runs in production. Everything else is paperwork. If the project on your plate is the one this article describes, you can reach me through the contact page or through Instagram. I will read it. I will reply. That is the standard.

Related reading