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:
- What behavior changed?
- 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
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
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
304responses; - 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')
An assertion inside .then() remains a one-time snapshot:
cy.getCookie('session_id').then((cookie) => {
expect(cookie).not.to.be.null
})
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
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,
})
})
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: ...
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?




