API design

Optimistic concurrency with ETags: interview questions and practical design

Optimistic concurrency with ETags prevents a client from overwriting a newer representation by requiring its update to match the version it read.

Written and reviewed by Sahil Srivastav

API designBackend engineeringInterview guide

What it actually is

Optimistic concurrency with ETags prevents a client from overwriting a newer representation by requiring its update to match the version it read.

Two editors can read the same document and submit different changes. Without a precondition, the later write silently erases the earlier one.

The useful interview answer is precise about the boundary: The server returns an ETag representing the exact version or representation. A client sends `If-Match` on a mutation; the server updates only when the tag still matches.

Why it matters in production

Two editors can read the same document and submit different changes. Without a precondition, the later write silently erases the earlier one.

ETags move the version check into HTTP’s conditional request semantics, where caches and clients already understand it.

How it works

Representation validator

The server returns an ETag representing the exact version or representation. A client sends `If-Match` on a mutation; the server updates only when the tag still matches.

412 versus 409

A failed `If-Match` precondition is commonly 412 because the request condition is false. Use 409 when the domain operation conflicts for a reason beyond a conditional validator.

Strong and weak validators

A strong ETag supports byte-sensitive update safety; a weak validator can express semantic equivalence for caching but is not appropriate when every representation difference matters.

Implementing it

Add a version column and conditional update to one resource.

Run two clients from the same initial ETag and verify one receives a precondition failure.

Return the current representation or a safe refresh hint without applying the stale update.

Interview questions and how to answer them

Why is an ETag better than a last-updated timestamp?

It is an explicit validator with well-defined conditional semantics and can represent a version even when timestamps collide or clocks differ.

How do you implement the check safely?

Include the version predicate in the update, check affected rows, and return a precondition failure when no row matched. A prior read check is not enough.

What should the client do after 412?

Fetch or merge the current representation, present the conflict if necessary, then retry with a fresh ETag. Do not blindly replay the stale body.

Answers that lose the round

  • Checking the ETag in application code and writing later without an atomic predicate.
  • Using a timestamp with insufficient precision as the only version.
  • Treating 412 as a server error and retrying the stale mutation unchanged.
  • Using weak ETags for a write precondition that needs exact version identity.

Practise in a real repository

Explaining a concept and enforcing it in code are different skills, and machine coding rounds test the second. Gronex ships broken backend repositories whose test suites assert the invariant rather than the happy path.

FAQ

Are ETags only for caching?

No. They are validators for both cache revalidation and optimistic write concurrency.

Can an ETag be a database version number?

Yes, if it changes on every relevant representation update and is scoped to the resource. Do not expose a mutable value that can be forged if that matters.

Does this prevent all lost updates?

It prevents updates that honour the precondition from overwriting a newer version. Clients and all write paths must participate for the guarantee to hold.

More backend concepts