Naoto Exchange
Personal R&D, Jul 2025-present
A trading exchange I built alone: it takes orders, matches buyers with sellers and keeps every balance up to date, pairing an order in under a microsecond.
An exchange is where buyers and sellers meet. Someone offers to buy at a price, someone else offers to sell, and the exchange pairs them up and records who now owns what. Professional exchanges do this millions of times a day, and the time each order takes matters, because whoever gets matched first gets the price.
Naoto is one I've been building alone since mid-2025, to find out how that kind of system stays fast without ever getting a balance wrong. It pairs an order in about 600 nanoseconds, well under a thousandth of a millisecond, and it keeps running while parts of it are replaced.
It's three kinds of service. Clients connect to an order gateway, which checks that they can afford what they're asking for. Each asset has its own matching engine, which pairs buy and sell orders. An account service owns every balance. Services can join and leave the cluster at runtime, and the rest adapts without a restart.
Why it's fast
Before any code was written, every step an order sets off was designed from two sides at once: what the rest of the system actually needs from it, and what the hardware does when it runs. The aim was to keep as little as possible on the hot path, the part an order is actually waiting on.
Most of the work could move off it. Some moved earlier. Memory is set aside when the system starts, and a client's balance is fetched from the account service once, at login, instead of on every order. Asking another machine anything costs a network round trip, and on the scale an order works at, that would dwarf everything else it does.
The rest moved sideways, onto threads running next to the hot one: sending the confirmation back, applying trades to balances, broadcasting results. An order only waits on a few short steps (moving work off the hot path goes through each of them).
Every piece of data also has exactly one owner. Two parts of the system never write the same thing, so they never have to coordinate, which removes most of the locks a system like this would normally need and keeps processor cores from fighting over the same memory (one writer for every piece of state).
What couldn't move was made fast where it is. The order book, where prices and pending orders live, keeps two structures side by side, one for finding a price and one for knowing which price is best (one order book, two data structures). The first is a hand-built hash map that uses SIMD instructions to check sixteen slots at once (the SIMD key-value store).
Why it stays correct
Speed is only useful if the numbers are right. The risk check has to decide instantly whether a client can afford an order, using information that is always slightly behind, and it does so by reserving the funds the moment it accepts (reliable risk checking).
Every trade report carries a sequence number, so a service that falls behind can catch up exactly, with nothing skipped or applied twice (catching up a stale snapshot).
When a service disappears and its connection is replaced, the gateway notices if an order was in flight and refuses to confirm it rather than risk it having gone to the wrong place (when a descriptor changes mid-send).
Where it stands
The core path, from order to match to balance update, works end to end, with latency measured at every stage. Two pieces are still being built: a retransmission service that recovers trade reports lost on the network, and a stricter ordering for closing old connections so a stale one can never be reused mid-send.
Related writing
Across services
separate processes, often on separate machines
One writer for every piece of state
Most locks exist because two things can write the same data, so Naoto makes sure they never do, whether they're separate services or two threads.
Catching up a stale snapshot without blocking
Instead of waiting on another service for a client's balance, the gateway replays the updates it has already seen onto whatever snapshot comes back.
Inside one service
which thread does what, and when
Between two threads
sharing data without a lock
Reliable risk checking on real-time client states
The risk check never sees a client's real-time balance, only a slightly stale copy, and it has to be correct anyway.
Triple-buffering client state without ever blocking a reader
A risk check can't wait on whatever thread is updating a client's balance, so the balance lives in three buffers behind one atomic index.
When a descriptor changes mid-send
A file descriptor is just a reusable integer, so a thread sending on one while another replaces it can send an order to the wrong socket.
Down to the bytes
data structures, cache lines, SIMD lanes
One order book, two data structures
An order book needs exact-price lookups and best-price order at the same time, and no single structure is good at both, so it keeps two.
Designing a cache-friendly, SIMD-accelerated key-value store
Picking, and then hand-building, the data structure the order book actually lives in.