skip to content

In a Cypress suite, when is cy.session()'s cacheAcrossSpecs option worth turning on?

level: principalimportance: nice to knowfreq 26%

answer

  1. Ask what the default already gives you
  2. The saving depends on how you shard
  3. Nothing is written to disk
  4. Every call site must agree exactly
  5. One helper becomes a frozen contract

basics

~20 s

Turn it on when setup is slow and many specs on one machine share an identity. The cross-spec cache is in memory per machine per run, so sharding erodes the saving and every call site must pass identical arguments.

solid answer

~50 s

`cacheAcrossSpecs` defaults to `false`, so a session is scoped to its spec file. Setting it to `true` lets any spec in the same `cypress run` on the same machine restore it. The saving is real but bounded: the cache is in memory, never written to disk and never shared between machines, so specs split across machines pay `setup` at least once per machine, and the win is roughly *(specs per machine minus one)* times the `setup` cost. Against that, Cypress requires every call site to pass an identical `id`, `setup`, `validate` and flag value, and throws otherwise - so the definition must live in one shared helper, and editing it becomes a suite-wide change. A longer-lived session also makes a real `validate` mandatory. Worth it for slow sign-ins on lightly sharded suites; not worth the coupling for a single `cy.request()`.

go deeper

for a junior

Know the default is false and that a session is otherwise scoped to its spec file. You are not expected to make the adoption call yet.

for a middle

Explain what the option changes and where the cache lives: in memory, one run, one machine, never on disk. That alone bounds the benefit.

for a senior

Show the arithmetic. Estimate the saving from setup cost and specs per machine, and connect a long-lived session to the need for a strict validate.

for a principal

Own the trade as an organisational one: the option makes one sign-in helper a frozen contract for the whole suite, and that cost is weighed against a run-time saving you can measure.

## What the option changes By default, a session created by Cypress's `cy.session()` is scoped to the spec file that created it: `cacheAcrossSpecs` is `false`, so every spec pays its own `setup`. Setting `cacheAcrossSpecs: true` promotes the session to a global one that any spec in the same `cypress run`, on the same machine, can restore. Nothing else about the command changes - the same `id` still keys it, the same `validate` still gates it. The decision looks free. It is not, and the reason is where the cache lives. ## Where the cache actually lives - It is held **in memory** for a single `cypress run`. It is not written to disk. - It is **not shared between machines**. When specs are split across machines, `setup` runs at least once per machine. - A **new run starts empty**, so nothing carries over from yesterday's pipeline. - In `cypress open`, sessions are additionally kept across reruns of the same spec file, which is a development convenience rather than a run-time saving. | | `cacheAcrossSpecs: false` (default) | `cacheAcrossSpecs: true` | |---|---|---| | scope | one spec file | any spec in the same run on that machine | | `setup` runs | once per spec | once per machine per run | | survives the run | no | no | | shared between CI machines | no | no | | call sites must match | no | yes - `id`, `setup`, `validate` and the flag | ## Doing the arithmetic before turning it on 1. **Measure `setup`.** If it is one `cy.request()` to `/api/sessions`, the saving is milliseconds per spec. If it is a slow multi-step sign-in through the expense portal, it is seconds, and seconds multiply. 2. **Count specs per machine, not specs.** The saving is roughly *(specs on a machine minus one) times the `setup` cost*. A suite of sixty specs sharded across ten machines saves five `setup` runs per machine, not fifty-nine. 3. **Count identities.** The arithmetic is per `id`. Ten roles across six specs each means the win is spread thinner than a single shared reviewer identity would suggest. 4. **Decide whether the run is even long enough to care.** If the whole suite is four minutes, an option that constrains how the team writes sign-in is a poor trade for three seconds. ## What it commits the team to This is the part candidates miss. When a session is cached across specs, every spec that uses it must call `cy.session()` with the **same** `id`, the **same** `setup`, the **same** `validate`, and the **same** `cacheAcrossSpecs` value. If any of those differ, Cypress throws rather than quietly reusing the session - Cypress compares the function source, so a reformatted copy in a second spec is a different function. That constraint is really an organisational one: - The `cy.session()` call has to live in exactly **one** shared helper, imported everywhere. Copy-pasting it into a spec is now a build break rather than a style smell. - Editing that helper is a **suite-wide** change. Adding a header to the sign-in request invalidates the session for every spec at once. - A helper that branches - a different `setup` per environment, say - has to branch on the `id` as well, or the same key ends up with two definitions. Some teams read that as a benefit: it forces the single definition they wanted anyway. Others find it makes a shared helper the most change-averse file in the repository. Both readings are defensible, and which one applies is a judgement about the team, not about Cypress. ## The second-order effects - **`validate` stops being optional.** A session that may be restored an hour into a run is far more likely to be holding an expired token than one scoped to a single spec. - **Failures get harder to localise.** A first spec that establishes a subtly wrong session hands it to specs that never ran the sign-in code, so the spec that fails is not the spec that caused it. - **The debugging lever is coarse.** `Cypress.session.clearAllSavedSessions()` clears spec and global sessions together; in open mode the Instrument Panel's clear button does the same and reruns the spec. ## A reasonable default Turn it on when `setup` is genuinely expensive, the same identity is used by many specs on the same machine, and the sign-in definition already lives in one shared helper with a real `validate`. Leave it off - the default - when the suite is heavily sharded, when sign-in is a single API call, or when the team is not ready to treat one helper as a frozen contract. Either answer is defensible; announcing "always turn it on because it is faster" without the sharding arithmetic is not.

  • What error does Cypress raise when two specs pass the same id but a different setup?
    A duplicate-id error: Cypress reports that the session already exists and refuses to create a new one under a previously used identifier. It compares the source of `setup` and `validate` and the `cacheAcrossSpecs` value, so even a reformatted copy counts as different. The remedy is to import one shared definition rather than duplicate the call.
  • How do you clear a cross-spec Cypress session while debugging?
    `Cypress.session.clearAllSavedSessions()` drops both spec-scoped and global sessions, so the next `cy.session()` call is a guaranteed miss. In `cypress open` the Instrument Panel above the test has a clear-all button that does the same and reruns the spec. Both are coarse - there is no per-id eviction - so treat them as debugging tools, not as suite plumbing.

saying these in an interview costs you the question

  • Says the cache persists to disk between runs
  • Assumes CI machines share one cross-spec session
  • Turns it on without measuring the setup cost
  • Copies the cy.session() call into several specs
  • Skips validate on a session that lives a whole run
  • Claims it is always faster with no downside