What Is Multi-Writer Contention?
Multi-writer contention is the condition in which two or more independent actors, such as services, AI agents or people, read and write the same mutable state within the same short window, so that each write can invalidate what another writer just read. It is distinct from multi-tenancy and partitioning, where many actors each write their own isolated state. Partitioning is a scaling problem. Contention is a correctness problem: it decides whether concurrent decisions can trust what they read.
Updated
What is multi-writer contention?
Contention is an old idea in systems design. Martin Thompson's Single Writer Principle puts the performance side plainly: "When trying to build a highly scalable system the single biggest limitation on scalability is having multiple writers contend for any item of data or resource." Databases address the correctness side with locks, isolation levels and serialization errors.
Multi-writer contention, with the test "contention, not tenancy," is the form Tacnode uses when assessing AI agent workloads. The point of the test is that company shape predicts nothing. A platform running thousands of agents, each drafting its own document for its own tenant, is partitioning: many writers, no shared state. A single product can carry real contention: two agents racing on one shared refund cap, concurrent agent purchases against one spending mandate, one customer's account touched at once by voice, chat and mobile channels, or a per-tenant quota counter decremented from several regions. The test reads what each decision writes to, not how many customers the system has.
How multi-writer contention works
The basic failure is a read-modify-write race. Two writers read the same value, each computes a new value from what it read, and the second commit silently discards or contradicts the first. With a budget cap, both writers pass the check and the cap is exceeded.
For a single row, databases handle this well. In PostgreSQL, a conditional update re-checks the condition against the latest committed version of the row:
UPDATE team_budget
SET spent = spent + 300
WHERE team_id = 'team-7'
AND spent + 300 <= cap
RETURNING spent;Under Read Committed, if another transaction updated the row first, the PostgreSQL docs state: "The search condition of the command (the WHERE clause) is re-evaluated to see if the updated version of the row still matches the search condition." The second update proceeds only if the budget still has room. Under Repeatable Read, the same conflict instead fails with "could not serialize access due to concurrent update," and the application retries.
Contention gets hard when the check is not on one row. A limit checked against a sum of holds, a velocity count over a sliding window, or totals assembled from several systems has no single row to lock. Writers each read a derived value, and that value lags the commits it should include.
How to tell the two apart in a design review:
| Signal | Partitioning | Contention |
|---|---|---|
| What each write touches | The writer's own tenant, user or document | State other writers also touch |
| Effect of adding writers | More throughput | More conflicts and retries |
| What a stale read costs | Little | A limit passed that should have failed |
| Fix | Shard by key | Coordinate the shared state |
Why multi-writer contention matters in real-time systems
Many teams treat high concurrency and contention as the same thing and size the wrong problem. A system with heavy partitioned load needs capacity; sharding solves it. A system with contention needs every decision to see what other decisions just committed, and adding capacity can make that worse by adding writers.
AI agents make contention common, because agents act without a person serializing them. The question that settles it: when two writers hit this state at the same moment, what resolves the conflict today? If the answer is a row lock, a merge or the booking system's own transaction, the conflict is handled. If the answer is "the pipeline usually keeps up," it is not. For decision state Tacnode holds, such as holds, budgets and per-agent limits, writes are transactional, so conflicting commits cannot both land; for data owned elsewhere, Tacnode gives each decision accurate context to read. More on concurrent decisions over shared state is in context under concurrency.
FAQ
Related terms
Unmergeable state is shared mutable state whose concurrent updates can't be combined afterward without breaking a rule, such as a budget, quota or balance.
A race condition occurs when a system's outcome depends on the timing of concurrent operations, letting interleaved reads and writes corrupt shared state.
Isolation levels control how database transactions see each other's concurrent changes, from READ UNCOMMITTED to SERIALIZABLE. Anomalies, defaults, examples.
Sharding is a database architecture pattern that splits data horizontally across independent servers. Learn how hash, range, and directory sharding work.
MVCC (Multi-Version Concurrency Control) lets databases keep multiple versions of each row so readers see consistent snapshots without blocking writers.
Decision coherence is the property that concurrent automated decisions act on the same version of shared state, instead of contradicting each other.
The single-writer principle gives each item of mutable state one owner that performs every write, so writers never contend. Others read or send requests.
A state footprint is the state an agent task reads and writes across its context, the orchestrator and external systems, used to find conflicts between agents.
