backenddrills

Web and client integration

Browser request races: stale reads and uncertain submits

By the BackendDrills editorial team · Published and checked October 6, 2026 · 6-minute read

Before you start: HTTP and basic JavaScript promises. Find this reading in a study path →

A browser can receive responses in a different order from the user's actions. Give each view update an ownership rule. Separately, treat a cancelled or failed write response as potentially uncertain until the server contract establishes its outcome.

Two searches, one visible result

A user searches for “spring”, then changes the term to “spring transactions”. The second request returns first. A slow response for the first term later overwrites the new results. Loading indicators and fast average latency do not protect against this schedule. Capture the query associated with each request and apply a response only if it still belongs to the current view generation.

// Illustrative fragment; latest is owned by this view.
const generation = ++latest;
const response = await fetch(searchUrl);
if (!response.ok) throw new Error('Search failed');
const data = await response.json();
if (generation === latest) renderResults(data);

A complete implementation also guards error and loading updates with the same ownership rule. Otherwise an older failure can erase a newer success. If a component is removed or an account changes, invalidate its generation so late work cannot update the wrong view.

Cancellation helps, but define the guarantee

AbortController can signal cancellation to fetch and related work. Use it to reduce unnecessary activity when a read becomes obsolete. It does not prove that a server-side write was undone. Fetch also does not reject merely because the server returns an HTTP error status; inspect the response status before assuming successful data.

A submit with no response

Now imagine a form that creates a booking. The server accepts it, but the client loses connectivity before receiving confirmation. Showing “try again” without an operation identity can encourage duplicate creation. Keep the submitted identity, offer a status or recovery path under the API contract and make the visible state distinguish rejected from unknown. Disabling the button alone does not protect against another tab or a later retry.

Practice with controlled response order

  1. Use a local fixture with two independently releasable responses.
  2. Resolve the newer read first, then the older read.
  3. Repeat with an older failure and a removed view.
  4. For a write, lose the acknowledgment after the effect and inspect the recovery flow.
  5. Test keyboard navigation and a readable status message for each state.

Finish with a small state diagram: idle, loading, current success, definitive failure and uncertain write. Annotate which request owns each transition. The browser and API should describe the same operation outcome rather than guessing independently.

Check the underlying behavior

Original illustrative examples, prepared with AI assistance and checked against the linked primary documentation. No customer incident or vendor endorsement is claimed. Our editorial approach.

Practice the next decision

Try a complete free backend drill: inspect evidence, make three decisions and review the reasoning. No account or card required.

Try a free incident drill →

Explore 1008 scenarios · $28 one-time

Selected practice from the study paths

Free readings need no account. Full edition drills require verified access; opening a paid link does not expose its answers.

Recommended next readings