Edge Serialization Point
also called Per-Entity Single Writer, Entity-Scoped Authority
Giving one logical entity a single-threaded authority near its users so operations on it are ordered without global coordination - which makes the entity rather than the application the unit of scale.
Two people bid on the same auction lot from two continents. The bids must be ordered, the price both watchers see must agree within 100 ms, and neither bid relates to the other 399 lots running at the same time.
The usual answers each fail on one leg. A regional row orders correctly and pays a cross-continent round trip per bid plus a retry per conflict. An eventually consistent edge store gives the latency and resolves two concurrent bids by taking whichever carries the later timestamp, which is not the higher bid, then tells the loser they won.
The fitting pattern is neither: put one single-threaded authority in the system for that one lot and route every operation there.
Why it matters
It resolves the standard edge dilemma for a common shape: data that must be strongly ordered, but only within a small entity many users touch at once. Ordering becomes the order it arrived, so the 400 lots scale independently.
It also removes a category of concurrency code - no row locks, no retry budget, no distributed lock with a lease and a fencing token. And the contention unit becomes explicit and reviewable, which beats discovering it during an incident.
Implementation patterns
- Choose the entity as the thing users compete over and nothing larger - one authority per lot, chat room or document.
- Keep authoritative state inside it, with durable writes to its own storage.
- Fan reads out, not in. Watchers read a broadcast or a cached projection; only the ordered operation reaches the authority.
- Bound every turn: messages are serialised, so one unbounded scan blocks every caller.
- Instrument queue depth per entity, the signal that granularity is wrong.
Industry example
Cloudflare's Durable Objects implement this directly. Cloudflare's documentation states that there is only ever one instance of a Durable Object with a given id running anywhere in the world, with all Workers making subrequests for that id routed to the same instance, which is what lets them coordinate across requests. The general-availability post adds the execution model: the object processes messages in order and on a single thread, and each has its own strongly consistent storage. It names a first-party user - Waiting Room uses Durable Objects to hold a strongly consistent view of how many users are currently attempting to access a given site globally.
Cloudflare's own guidance states the failure mode plainly: one object for an entire application becomes a latency and throughput problem, because every request in the world queues behind a single instance.
Failure scenarios
- One authority for the whole application - a single-threaded server at edge prices.
- A hot entity exceeding one thread. There is no second instance to add; the only remedy is sharding the entity, which changes the product's rules.
- A pinned location far from the users, so an entity created in London serves Sydney at London latency for life.
Trade-offs
| Choose | Gains | Pays |
|---|---|---|
| Per-entity serialization point | ordering with no locks - scaling per entity | a hard single-thread ceiling - pinned location - no cross-entity queries |
| Regional row with optimistic concurrency | portable - cross-entity queries free | a round trip per operation - retries climb with contention |
| Eventually consistent edge store | lowest read latency | writes resolved by timestamp rather than by rule - silent wrong outcomes |
When not to use it
A plain round trip to one region is the right answer until the per-entity operation rate makes it the user-visible cost - roughly, one entity taking more than a few ordered writes per second from clients on several continents. Below that, a regional row is simpler and already understood.
Not for read-mostly data. A regional price list wants replication and caching; routing those reads through a single-threaded authority turns a free read into a queued one.
Not where the contention unit is the whole dataset. A global sequence number has one entity by definition, so you get every constraint and no parallelism.
Interview question
Q: You are designing live collaborative cursors and comments for a worldwide document product. Argue for a per-document single-threaded authority, then tell me the two ways that design fails in production and what you would measure to see each coming.
What a strong answer covers: the document as the contention unit, because operations on different documents have no ordering relationship · the first failure being wrong granularity, with one authority per workspace queueing everything behind one thread, caught by per-entity queue depth · the second being a document that exceeds one thread or is pinned far from its readers, unfixable by adding instances · and that for a document edited twice an hour, a regional row was correct and cheaper.
Quick check
Quiz: An edge platform guarantees one instance per object id worldwide, processed in order on a single thread. What is the consequence of giving the whole application one object? — Every request queues behind one thread, so global throughput is capped at one object's and a hot workload starves everything else.
Flashcard: When does a per-entity serialization point beat a regional database row? — When one entity takes more than a few ordered writes per second from clients on several continents, so the round trip and contention retries become the user-visible cost.