Skip to content

Cypress Timeouts

Every retry loop needs a maximum duration, that's what timeouts define. This lesson covers the different timeout settings Cypress exposes and how to override them for specific commands.

Why Timeouts Exist

Automatic retrying is powerful, but it needs a limit, otherwise a genuinely broken test would hang indefinitely instead of failing with useful feedback. Cypress defines several distinct timeout settings for different categories of operations, each configurable globally or per command.

// cypress.config.js
export default defineConfig({
  e2e: {
    defaultCommandTimeout: 6000, // default: 4000ms
    requestTimeout: 8000,
    pageLoadTimeout: 30000,
  },
});

These are global defaults; individual commands can still override them when a specific operation genuinely needs more (or less) time.

Key Timeout Settings

defaultCommandTimeout   // most cy commands and assertions (default 4000ms)
requestTimeout          // waiting for an XHR/fetch to go out (default 5000ms)
responseTimeout         // waiting for a response after a request (default 30000ms)
pageLoadTimeout         // waiting for cy.visit()/page loads (default 60000ms)
  • defaultCommandTimeout applies to most commands like cy.get() and .should().
  • pageLoadTimeout is much longer by default, since full page loads legitimately take longer.
  • Any command accepting an options object can override its timeout individually: { timeout: 10000 }.
  • Raising a global timeout to fix one slow test can hide genuine performance regressions elsewhere.

Timeout Settings Cheat Sheet

Default values and typical use cases for each timeout configuration.

Setting Default Applies To
defaultCommandTimeout 4000ms Most commands and assertions
execTimeout 60000ms cy.exec()
taskTimeout 60000ms cy.task()
pageLoadTimeout 60000ms cy.visit(), full page navigations
requestTimeout 5000ms Waiting for an XHR/fetch to be sent
responseTimeout 30000ms Waiting for a response, including cy.wait('@alias')

Overriding a Timeout for a Single Command

Rather than raising the global defaultCommandTimeout for the whole suite (which slows down every genuinely failing test too), override the timeout only on the specific command that legitimately needs more time.

// Only this specific assertion gets extra time
cy.get('[data-cy="report-status"]', { timeout: 15000 })
  .should('have.text', 'Report ready');

This keeps the rest of the suite's failures fast to detect, while accommodating one genuinely slow operation.

Diagnosing a Timeout Failure

A timeout failure message tells you exactly which command was still retrying, and what the last observed value was, when time ran out. Reading this carefully, rather than immediately raising the timeout, often reveals the actual root cause.

  • Check whether the element ever appears at all, versus appearing too slowly.
  • Check whether a network request the UI depends on is failing or hanging.
  • Only raise a timeout once you've confirmed the underlying operation is simply slow, not broken.

Common Mistakes

  • Raising defaultCommandTimeout globally to fix one slow operation, masking genuinely broken tests elsewhere.
  • Confusing requestTimeout (waiting for a request to be sent) with responseTimeout (waiting for its response).
  • Not distinguishing pageLoadTimeout from defaultCommandTimeout when diagnosing a slow cy.visit().
  • Increasing a timeout as a first response to any failure, without first checking whether the awaited condition ever becomes true.

Key Takeaways

  • Cypress defines separate timeouts for commands, requests, responses, and page loads.
  • Override a timeout per command when only that specific operation is legitimately slow.
  • Raising global timeouts should be a last resort, not a default fix for flaky tests.
  • A timeout failure message shows the last observed state, valuable for diagnosing the real cause.

Pro Tip

Before increasing any timeout, reproduce the failure in the interactive Test Runner and watch what actually happens, in most cases you'll find either a genuinely broken feature or a missing loading-state assertion, not something a longer timeout should paper over.