
This website uses cookies
We use Cookies to ensure better performance, recognize your repeat visits and preferences, as well as to measure the effectiveness of campaigns and analyze traffic. For these reasons, we may share your site usage data with our analytics partners. Please, view our Cookie Policy to learn more about Cookies. By clicking «Allow all cookies», you consent to the use of ALL Cookies unless you disable them at any time.
Over the past decade building distributed systems - from financial engines to blockchain infrastructure - I’ve learned a simple lesson:
High-frequency systems rarely fail because they are too slow.
They fail because they are unpredictable.
Throughput is easy to measure.
Tail latency is not.
You can optimize for requests per second and still ship a system that collapses under real concurrency because:
lock contention explodes
p99 latency becomes unstable
replay logic becomes nondeterministic
state corruption emerges under pressure
The root cause is almost always the same:
Uncontrolled shared mutable state.
This article describes an architectural pattern we repeatedly apply in production-grade Rust systems to eliminate that problem.
It’s called the Single-Writer Engine Pattern.
The typical high-load backend starts like this:
use std::sync::{Arc, Mutex};
struct State {
order_book: OrderBook,
balances: HashMap<UserId, Balance>,
}
type SharedState = Arc<Mutex<State>>;Each handler acquires a lock, mutates state, releases it.
It looks safe.
It passes code review.
It works in staging.
But at scale:
Multiple threads compete for the same memory.
Cache lines bounce across CPU cores.
Lock convoy effects appear.
Scheduler timing determines state mutation order.
Now your system’s behavior depends on runtime scheduling characteristics.
That is not engineering. That is chance.
Instead of asking:
How do we synchronize access to shared state?
We ask:
Why is this state shared at all?
The Single-Writer pattern enforces one rule:
All critical mutable state belongs to exactly one task.
Everything else communicates with it via message passing.
No locks.
No RwLock.
No Arc<Mutex<_>>.
Only ownership.
The core engine:
use tokio::sync::{mpsc, oneshot};
enum Command {
PlaceOrder {
order: Order,
respond_to: oneshot::Sender<Result<(), Error>>,
},
}
struct Engine {
order_book: OrderBook,
}
impl Engine {
async fn run(mut self, mut rx: mpsc::Receiver<Command>) {
while let Some(cmd) = rx.recv().await {
match cmd {
Command::PlaceOrder { order, respond_to } => {
let result = self.order_book.place(order);
let _ = respond_to.send(result);
}
}
}
}
}The HTTP layer never touches the state.
It sends commands.
The engine processes them sequentially.
Mutation order is deterministic.
This is not about being “single-threaded.”
It’s about being single-owner.
Many engineers assume more threads equals more performance.
In high-frequency systems, this is often wrong.
The real bottleneck is synchronization:
Cache line invalidation
Memory fencing
Lock acquisition contention
Context switching
When multiple cores write to the same memory, the CPU’s cache coherence protocol becomes your limiting factor.
A single-writer engine:
Keeps hot data on one core
Avoids cross-core invalidation
Eliminates lock contention entirely
Removes memory fence overhead
You lose parallel mutation.
You gain predictability.
In production systems, predictability is more valuable than peak theoretical throughput.
In financial or blockchain systems, order matters.
If state transitions happen in different orders:
balances change
matching outcomes change
risk models diverge
replay becomes unsafe
With locks, mutation order depends on scheduler timing.
With single-writer, order is explicit.
That simplifies:
replay
auditing
testing
state reconstruction
And that dramatically reduces operational risk.
In lock-based architectures, overload is invisible until latency explodes.
In a single-writer architecture, the channel capacity defines system pressure:
let (tx, rx) = mpsc::channel(1024);When the channel fills:
reject requests
apply prioritization
shed load intentionally
Backpressure is no longer accidental.
It is designed.
This alone can stabilize a high-frequency system under extreme load.
Because all mutations flow through a single loop:
We can assign sequence numbers.
We can checkpoint offsets.
We can replay events deterministically.
Crash recovery becomes trivial:
Load snapshot.
Resume from last offset.
Replay commands.
In distributed systems, simplicity in recovery logic is a major operational advantage.
A common objection:
“This only uses one core.”
Correct.
So we shard.
Examples:
One engine per trading pair
One engine per tenant
Hash-based routing: hash(key) % N
One engine per blockchain
Each shard maintains single-writer guarantees internally.
You scale horizontally while preserving determinism.
This pattern scales surprisingly well in real-world systems.
Single-writer is not universal.
Avoid it when:
Work is CPU-heavy and parallelizable.
State mutation is trivial.
Ordering does not matter.
You’re building CRUD APIs.
Use it when:
State consistency is critical.
Ordering affects correctness.
You require replay safety.
Tail latency must be stable.
Financial integrity matters.
In a blockchain indexer:
RPC Listener
Websocket Feed
Kafka Consumer
HTTP API
↓
Engine Task
↓
Canonical State
↓
DatabaseThe engine:
Processes events sequentially.
Handles reorg logic.
Enforces monotonic state transitions.
Writes consistent snapshots.
Everything else is IO.
The engine is the authoritative state machine.
From a CTO perspective, the benefits are not just technical.
They are organizational.
Single-writer systems:
Are easier to reason about.
Reduce concurrency-related bugs.
Simplify onboarding of engineers.
Improve operational predictability.
Lower incident frequency under load.
They trade theoretical concurrency for structural clarity.
In complex systems, clarity wins.
The Single-Writer Engine Pattern is not about cleverness.
It is about discipline.
It enforces:
clear ownership
deterministic mutation
explicit backpressure
reliable replay
stable tail latency
In high-frequency Rust systems, this pattern consistently separates:
Experimental prototypes
from
Production infrastructure.
And in the long run, production-grade predictability is what defines strong engineering organizations.
