DEV Community

Cover image for Cypress 16.1.1 Upgrade Checklist: Measure Speed, Flake, Memory, and Secret Boundaries
Raju Dandigam
Raju Dandigam

Posted on

Cypress 16.1.1 Upgrade Checklist: Measure Speed, Flake, Memory, and Secret Boundaries

Cypress 16 brings meaningful runtime, network, retry, and security changes. That does not mean every suite becomes faster simply by changing the package version.

A responsible upgrade answers two questions:

  1. What behavior changed?
  2. Did those changes improve this suite under comparable conditions?

The following checklist targets Cypress 16.1.1, released September 29, 2026. It includes the larger Cypress 16 migration, the 16.1.0 reliability work, and the 16.1.1 patch fixes.

Before upgrading: capture a baseline

Run representative specs on the same CI image, browser, machine size, and application build. Keep at least:

Signal Why it matters
Total and per-spec duration Detect broad and localized changes
Retry and flake count Speed can improve while stability worsens
Peak browser/runner memory Long specs may degrade late in a run
Crash/hang count Averages hide catastrophic failures
Browser and Node versions Prevent invalid comparisons
Network protocol-sensitive assertions HTTP/2 can change observed headers/status behavior

One run is not a baseline. Use enough repeated runs to see ordinary variance, and report the environment with any published result.

Pin the runner image before comparing

Docker helps only if the image is fixed. Use an official cypress/browsers image with a full version tag or a registry digest, then run both baselines under the same resource limits:

export CYPRESS_IMAGE='cypress/browsers@sha256:<approved-digest>'

docker run --rm \
  -v "$PWD:/e2e" \
  -w /e2e \
  "$CYPRESS_IMAGE" \
  npx cypress run --browser chrome
Enter fullscreen mode Exit fullscreen mode

Avoid latest and moving short tags: a browser or Node update can otherwise enter between the “before” and “after” runs. Record the image digest, npx cypress version, node --version, browser version, CPU, and memory. If the application also runs in Compose, add a health check; container startup order alone does not mean the server is ready.

1. Confirm runtime and framework compatibility

Cypress 16 requires supported Node lines beginning with Node 22, 24, or 26; Node 20 and 25 are no longer supported for binary installation. Component Testing minimums also moved: Angular 21, Vite 8, and Next.js 15.0.4.

node --version
npm ls cypress vite next @angular/core
npx cypress verify
Enter fullscreen mode Exit fullscreen mode

Upgrade one major at a time if the project is several releases behind.

2. Review native browser networking

Chrome, Chromium, and Edge now use the native browser network. The application can negotiate HTTP/1.1, HTTP/2, or HTTP/3 as it would outside Cypress. cy.intercept() still works, but tests that assert transport details may need review:

  • req.httpVersion;
  • compression headers;
  • cached 304 responses;
  • browser-specific protocol assumptions.

Do not permanently enable the deprecated forceHttp1 escape hatch merely to preserve an old assertion. Fix the assertion to protect user-visible or application behavior instead.

3. Find typing-delay assumptions

The default keystroke delay is now zero. Most tests need no change. Tests that depended on the old implicit delay may expose application debounce or input-handling assumptions.

Search for fields whose behavior changes only when typing slowly. If a product deliberately requires a delay, make it explicit in that test rather than restoring a global slowdown.

4. Move retryable storage assertions to .should()

Cookie and storage reads are now query commands. Directly chained assertions re-read state until they pass or time out:

cy.getCookie('session_id').should('exist')
Enter fullscreen mode Exit fullscreen mode

An assertion inside .then() remains a one-time snapshot:

cy.getCookie('session_id').then((cookie) => {
  expect(cookie).not.to.be.null
})
Enter fullscreen mode Exit fullscreen mode

Use .should() when you want retry behavior. Keep .then() when a one-time read is intentional.

5. Review visibility assumptions

The modern visibility algorithm is now the default. Tests relying on legacy-only overflow, transform, or coverage behavior may fail. Prefer assertions that describe what a user can do rather than locking the suite to implementation details.

visibilityStrategy: 'legacy' is a deprecated migration aid, not a long-term configuration.

6. Remove obsolete memory configuration

Browser memory management is stable and enabled by default for Chromium-based browsers. Remove:

experimentalMemoryManagement: true
Enter fullscreen mode Exit fullscreen mode

If the suite intentionally disabled it, migrate to manageBrowserMemory: false and document why. Then compare long-running specs and repeated open-mode runs, not just small happy paths.

7. Migrate secret access

Cypress.env() was removed because it exposed configured environment values in browser context. Use:

  • cy.env() for sensitive values read asynchronously through the Node process;
  • Cypress.expose() for public, non-sensitive synchronous configuration.
cy.env(['apiToken'], { log: false }).then(({ apiToken }) => {
  cy.request({
    url: '/api/me',
    headers: { authorization: `Bearer ${apiToken}` },
    log: false,
  })
})
Enter fullscreen mode Exit fullscreen mode

Once yielded, the token is an ordinary value. Do not put it in assertions or error messages.

Also replace removed cy.exec() calls with controlled cy.task() implementations and delete cy.end().

8. Include the 16.1 reliability and patch fixes

Cypress 16.1.0 specifically targeted fewer hangs, lower memory growth, and trusted-certificate caching. Cypress 16.1.1 then fixed cy.clock() cancellation behavior, TypeScript option signatures, shadow-DOM .closest() performance, and dependency security issues. If those problems affected your suite, construct a representative reproduction and compare it separately. Do not attribute every duration improvement to HTTP/2 when a hang fix, browser update, cache state, or application change also occurred.

Report the upgrade honestly

A useful upgrade report looks like this:

Environment: ubuntu-latest, Chrome 146, Node 24
Sample: 20 identical recorded runs before and after
Median duration: ...
P95 duration: ...
Retries: ...
Peak memory: ...
Crashes/hangs: ...
Known confounders: ...
Enter fullscreen mode Exit fullscreen mode

The goal is not to prove that a release is universally faster. It is to determine what changed in your system and preserve evidence for any regression.

Which one of your suite's failures is currently being blamed on “Cypress performance” without a controlled measurement?

References

Top comments (0)