How the OMS and ME Fit Together: Two Shard Axes
A production exchange shards in two different ways at once, because two different kinds of state have two different consistency units. This page is the map: how the user-sharded OMS and the symbol-sharded matching engine compose into one system. The two pages that follow go deep on each axis; read this one first.
The two layers
Section titled “The two layers”- The OMS owns per-user state — buying power, reservations, session, the open-orders index — and shards by user. → Sharding the OMS by user
- The matching engine owns per-symbol order books and shards by symbol. → Sharding by the actor pattern
Why the axes must differ
Section titled “Why the axes must differ”You cannot shard both layers the same way — that’s the core insight the whole design rests on:
| Consistency unit | Shard key | Why not the other key | |
|---|---|---|---|
| OMS | a user’s account | user | a user trades many symbols — you can’t pin their balance to one symbol shard |
| Matching engine | an order book | symbol | a book is inherently multi-user — you can’t shard matching by user |
So the system needs both, and they meet at the ME-bridge: a leader-only agent in each OMS
cluster that reads an order’s symbol and submits it to that symbol’s ME cluster (the symbol → ME map
is static config).
An order, end to end
Section titled “An order, end to end”The subtle part is the fill crossing the axes. A match in the ME (symbol axis) produces fills for
two users — taker and maker — who generally live in different OMS clusters (user axis). Each
side’s OMS cluster settles its own user. This is exactly why the ME must emit lifecycle events keyed
by a deterministic orderId (the ME contract):
each OMS cluster picks up the fill for the order it owns.
Each layer is itself an A + B hybrid
Section titled “Each layer is itself an A + B hybrid”Both layers combine the two structures from the actor-pattern page:
- Option A — many clusters (each its own Raft log + leader + core) → scales throughput.
- Option B — many actors inside one cluster (one shared log/core) → logical isolation only.
| Layer | Option A (scale throughput) | Option B (logic isolation) |
|---|---|---|
| OMS | many OMS clusters, HRW users across them | many resident user-actors per cluster (the LRU/TTL cache) |
| ME | one cluster per symbol-group | multiple order books inside a cluster |
So “add capacity for more users” = add OMS clusters (A); “add capacity for more symbols” = add ME clusters (A) — independently, without touching the other layer.
They scale independently
Section titled “They scale independently”The only coupling between the layers is the static symbol → ME map (the bridge’s routing) and the
ME contract.
Otherwise:
- Scaling OMS clusters (more user capacity) is the staged HRW migration — the ME never notices.
- Scaling ME clusters (more symbol capacity) touches order-book placement — the OMS only updates its static map.
Go deeper:
- Sharding the OMS by user: hot-user actors with eviction — the user axis.
- Sharding an OMS by the actor pattern — the symbol axis.
This site is not affiliated with, endorsed by, or sponsored by Adaptive Financial Consulting Limited or the Aeron project. Aeron is a registered trademark of Adaptive Financial Consulting Limited.
Aeron is a trademark of Adaptive Financial Consulting Limited in the United Kingdom and other countries.