ScreenshotNeo

BlogHow-to

How to Find Where Cypress Tests Spend Time

Find whether Cypress time goes to slow tests, specs, retries, setup, or constrained CI machines, then choose what to investigate using run data and profiling.

By the ScreenshotNeo team4 October 202611 min read

To find where Cypress tests spend time, measure at three levels: individual tests, spec files, and the whole CI run. For recorded Cypress Cloud runs, sort the Slowest Tests view to find slow individual tests, inspect the run’s Specs tab in Bar Chart view to find long spec files, and use Machines to see whether uneven spec durations or machine pressure is limiting parallel performance. Without Cloud, use local run output and Cypress’s process-profiler logs alongside your CI provider’s utilization graphs.

Do not start by adding machines or rewriting tests. First identify where elapsed time accumulates, then choose a diagnostic aimed at that layer. Cypress’s duration bands and suite targets are triage heuristics, not guarantees; actual results depend on the app, browser, test setup, and runner environment.

1. Establish a baseline and locate the time

  1. Record a comparable run. Note the branch, commit, browser, CI machine type, number of machines, retry settings, and whether the run was recorded to Cypress Cloud. Compare like-for-like runs; a changed runner or app state can overwhelm the effect of a code change.
  2. Find slow individual tests. In Cypress Cloud, open Slowest Tests and sort by duration. Look for tests that repeatedly appear near the top, not just a single outlier. For averages by branch, tag, and time range, the Cloud Run Duration report covers passing runs. In Open Mode, the Specs page can show average duration across the last four runs.
  3. Find slow spec files. Open the recorded run’s Specs tab and switch to Bar Chart. Check whether one or a few specs dominate total duration. A long spec can constrain a parallel run because Cypress distributes whole spec files, not portions of an active spec.
  4. Check machine assignment. In Machines, inspect which specs each machine ran and how long they took. If one machine receives a long spec near the end while others are idle, the spec distribution may be limiting the gain from parallelism.
  5. Separate test time from run time. A slow overall run can include browser startup, CI setup, application startup, dependency installation, retries, and waiting for external services. Record those phases separately where your CI logs expose them; test durations alone do not explain all wall-clock time.

Cloud analytics require recorded run data for the views above. If that is unavailable, start with local test output, the profiler command below, CI resource graphs, and spec-level timing. Treat any difference between two runs as evidence only when the conditions are sufficiently similar.

2. Read the duration data in context

Cypress’s Optimizing test performance guide publishes these ranges as guidance for triage:

Measurement Cypress guidance How to use it
Individual test Under 3 seconds: Excellent; 3–10 seconds: Acceptable; 10–30 seconds: Investigate; over 30 seconds: Poor Use the bands to prioritize investigation. Cypress also says component tests should consistently run under 2 seconds.
Spec file Under 1 minute: Excellent; 1–3 minutes: Acceptable; 3–5 minutes: Investigate; over 5 minutes: Poor Long specs can slow the run tail and make whole-file parallel scheduling less balanced.

These are Cypress’s published heuristics, not performance requirements or independent benchmarks. A 12-second test may be expected if it exercises a real slow workflow; a 2-second test can still be wasteful if it repeats across hundreds of cases. Use the shape of your own run and the change you need to make as the deciding evidence.

Cypress also gives rough whole-suite targets: under 50 tests, under 3 minutes serial; 50–200 tests, under 10 minutes serial and under 3 minutes with four or more machines; 200–500 tests, 15–30 minutes serial and under 10 minutes with four or more machines; 500 or more tests, use parallelization and target under 15 minutes with four or more machines. These targets may not fit every application, spec mix, or CI environment. The guide’s Kitchen Sink example reports a 1:51 serial run becoming 59 seconds with a second machine; it is an example, not a speedup promise for another suite.

3. Diagnose a slow test

Open the test’s command log and source, then follow the time through setup, actions, waits, and assertions. Common contributors include using an end-to-end test where a component test would cover the behavior, repeated login work, slow real network calls, arbitrary waits, and app initialization.

  • Inspect waits. Look for fixed delays such as cy.wait(5000). When waiting for a request that matters to the test, Cypress recommends waiting on an aliased route instead of an arbitrary duration. A fixed delay can waste time when the app is fast and still be too short when it is slow.
  • Inspect authentication setup. If many tests repeat the same login, determine whether Cypress cy.session() can preserve and restore session state safely for the test’s needs. Measure the login portion before and after any change.
  • Inspect real network calls. Decide whether the test needs a live external service to verify the behavior. External latency and variability can dominate test time; if the dependency is not the subject of the test, evaluate a controlled route stub or fixture. Keep separate coverage for the integration that must exercise the real service.
  • Check test type and scope. Use the narrowest test type that still covers the behavior you need. A browser-level workflow may be appropriate, but repeating broad setup for logic that can be tested at a smaller scope adds overhead.
  • Look for retries. A retry can turn one failing attempt into several attempts, making wall-clock time much longer than the final test result suggests. Compare attempts and retry counts, and investigate instability instead of treating retries as free extra time.

For a useful comparison, record the test’s duration and relevant setup or request timing over several comparable runs. Change one likely source at a time, then compare results under the same conditions.

4. Check CPU and memory pressure in CI

When durations vary widely between local and CI runs, or adding parallel machines gives little benefit, determine whether the runner is saturated. Cypress documents this profiler command for npm:

DEBUG=cypress:server:util:process_profiler npx cypress run

The debug output reports CPU and memory consumption every 10 seconds. Cypress says CPU consistently above 100% indicates machine saturation. Check the same time window in your CI provider’s CPU and memory graphs; also collect Cypress and system information:

npx cypress info
node -p 'os.cpus()'

The same DEBUG=cypress:server:util:process_profiler prefix can be used with Yarn, pnpm, or Bun as documented in the Cypress guide. For example, use the prefix with the relevant package-manager run command. Keep profiler output with the run record so that a timing anomaly can be compared with resource usage.

Look for consistent CPU saturation, memory pressure, or contention during the slow portion of the run. A higher machine count can increase total resource demand; if the runner is already constrained, parallel work may compete for CPU or memory instead of shortening elapsed time. Use provider graphs and repeated runs to distinguish a resource limit from a slow test or a long spec.

5. Decide whether parallel scheduling is the bottleneck

Cypress Cloud parallelization assigns whole spec files to available machines using duration estimates and historical run data. Similar spec durations help distribute work. An in-progress spec is not split across machines during that run, so a single long spec can leave other machines idle near the end.

  1. Use the Machines view to identify idle time and the specs each machine received.
  2. Check whether one or more specs are much longer than the rest.
  3. If the spec list is imbalanced, consider splitting the longest specs into files with more similar durations, while keeping each file understandable and independently runnable.
  4. Re-run with the same machine count and comparable conditions, then compare total duration and per-machine work.

Cypress cautions that very short specs—around under 10 seconds—rarely benefit from further splitting because per-spec overhead, including browser launch and video encoding, can outweigh any saved execution time. Adding machines is most useful when there is enough independent spec work to distribute and machine resources are adequate. Cypress’s guide suggests considering parallelization when a serial suite exceeds roughly 10–15 minutes, while noting gains diminish when per-spec overhead dominates.

6. Account for setup, retries, and the Runner UI

Review the CI timeline before attributing all elapsed time to Cypress test commands. Dependency installation, build steps, app startup, browser startup, artifact handling, and teardown can all add wall-clock time. Repeated setup inside each test or spec can also make the suite slower even when individual assertions are quick.

Rendering the Cypress Runner UI during cypress run can affect runtime, especially on lower-resourced machines. Cypress documents that Test Replay changes whether the Runner UI is rendered by default. Use the --runner-ui option only when that display is needed, and compare runs with the same setting.

The API reference documents slowTestThreshold in milliseconds as a setting for marking tests slow in cypress run. Its exact default is version-dependent, so check the reference for your installed Cypress version before setting a numeric value. A threshold labels slow tests; it does not make them faster.

7. A diagnostic decision table

Evidence Likely area to investigate Next step
A few tests repeatedly top Slowest Tests Test-level waits, setup, network calls, or test scope Inspect command timing and retry attempts; measure a targeted change.
One spec dominates the Specs bar chart Spec size or a slow test within that spec Inspect its test durations; consider a balanced spec split if scheduling leaves machines idle.
Machines are idle while one spec continues Whole-spec scheduling tail Review spec boundaries and duration balance; active specs are not divided across machines mid-run.
Profiler CPU is consistently above 100% Runner CPU saturation Compare provider graphs and machine capacity; determine whether concurrency is worsening contention.
Cloud durations look fine but CI wall time is high Build, install, app startup, browser startup, artifacts, or teardown Use CI stage timestamps to locate time outside test execution.
Duration varies substantially between attempts Flaky behavior, retries, network variability, or resource contention Compare attempt-level logs and resource graphs instead of relying on a single run.

8. Troubleshooting

Cloud does not show Slowest Tests or spec analytics

The described Cloud views need recorded run data. Record runs to Cypress Cloud to build the data those views use. If Cloud is unavailable, inspect local run output and profiler logs; do not infer that a spec is slow from its name or size alone.

The profiler command prints no periodic data

Confirm that the debug prefix is present in the environment for the Cypress process and that the command is launching Cypress. Check the package-manager syntax for your shell and runner. Use the Cypress guide’s Yarn, pnpm, or Bun form if applicable.

Adding machines barely changes total duration

Check whether the suite has enough spec files, whether durations are balanced, whether a long spec forms the run tail, and whether machines are CPU- or memory-constrained. Cypress parallelizes at the spec-file level, so extra machines cannot divide one active spec.

CI is much slower than local

Compare browser and Cypress versions, machine resources, network access, app startup, and retry counts. Capture profiler output and provider graphs for the same run window. Local results do not account for a busy or smaller CI runner.

A test is marked slow but the threshold seems wrong

slowTestThreshold is a reporting threshold in milliseconds. Confirm the installed Cypress version’s default and configuration behavior in the API reference. Changing the threshold changes labeling, not execution time.

A split made the run slower

Very short specs can accumulate browser-launch, video-encoding, and scheduling overhead. Compare the new file durations and per-machine assignment; merge overly small files if overhead exceeds the scheduling benefit.

9. Measure whether a change worked

  1. Keep a baseline with test durations, spec durations, retries, machine count, relevant CI stages, and resource data.
  2. State the suspected bottleneck before changing code—for example, repeated login, one network wait, CPU saturation, or one oversized spec.
  3. Make one targeted change and repeat the run under comparable conditions.
  4. Compare the metric that should move, as well as total wall time. A faster test may not shorten the whole run if CI setup or another spec dominates.
  5. Retain the change only when the repeated evidence supports it and coverage remains appropriate.

This method avoids treating one unusually fast or slow run as proof. It also helps separate a real improvement from variation in external services or shared CI resources.

Or skip the browser setup

For a page screenshot used in a test report or debugging workflow, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns PNG, JPEG, WebP, or PDF. Its cookie and consent handling accepts banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and responses include X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

See the ScreenshotNeo API documentation for request options. This runnable cURL example saves a WebP screenshot:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed; the MCP server lets AI agents take screenshots; and 1,000 screenshots a month are free with no card. Paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month, with no card required.

FAQ

Can I find the slowest Cypress tests without Cypress Cloud?

Yes. Use local run output, spec timing, Cypress process-profiler logs, and CI utilization graphs. Cloud provides convenient recorded-run analytics, but it is not the only way to investigate.

Does a slow-test threshold improve test speed?

No. It marks tests for visibility. Diagnose and change the measured source of delay to affect runtime.

Why can a long spec limit parallel gains?

Cypress assigns complete spec files to machines. It does not split a spec already running across machines, so other machines can finish first and sit idle.

Should every spec be split until it is short?

No. Splitting very short specs can add browser and artifact overhead. Use machine assignment and measured durations to decide whether a split is likely to improve balance.

Sources