The Same Matching Engine Measured 130,000/s and 106/s
Matching engine throughput measured at four boundaries of one exchange, from 130,000/s to 106/s, with the conductor and outbox internals that explain the gap.
Fourteen long-form articles on systems I built, rebuilt, or curate: a cryptocurrency exchange matching engine, a durable workflow engine in Rust, a Postgres scheduler, an OPAQUE implementation, a lattice sieving tool, and the zero-knowledge proof landscape. Each one names the components, walks a request through the real code, and reports the measurements, including the ones that went the wrong way.
RSS feed · By Oleksii Vasylenko, Technical Lead
Five posts from rebuilding the matching path of a cryptocurrency exchange: the requirements we should have written first, the distributed lock we deleted, the Redis and Valkey cell design, the order book encoding, and a benchmark of the same engine at four boundaries that came out between 130,000 and 106 operations per second.
Matching engine architecture guide →
Matching engine throughput measured at four boundaries of one exchange, from 130,000/s to 106/s, with the conductor and outbox internals that explain the gap.
Why a matching engine keeps one writer per market: the Redis lock bug that put two writers on one book, and the RabbitMQ queue setting that replaced it.
How a distributed matching engine on Redis or Valkey is built: one writer per market, hash-tagged atomic commits, WAITAOF durability, and a two-cell benchmark.
Order book data structures in a production matching engine: one Redis sorted set for price-time priority, O(1) cancellation, and a reconcile check for drift.
Cryptocurrency exchange system requirements for trading rules, consistency, ledger, throughput, recovery, and audit, each tied to the Bitsten service behind it.
Five posts from building Orch8, a durable workflow engine in Rust that persists snapshots instead of replaying event history. Each one covers a subsystem with the real code: effect receipts and at-most-once dispatch, the snapshot model compared with Temporal, a Postgres scheduler on SKIP LOCKED, moving a running execution between machines, and tenant isolation.
Durable workflow engine architecture guide →
A workflow engine cannot promise exactly-once effects across a network. How an eight-state effect receipt gives at-most-once and fails closed on ambiguity.
Snapshot vs event replay for durable execution: determinism rules, O(1) vs O(n) resume, versioning, debuggability, and what each model gives up.
A Postgres job queue with FOR UPDATE SKIP LOCKED: the real claim query, partial index, per-tenant cap, window-function trap, lease heartbeats, and its limits.
Moving a running workflow to a device or another organisation: epoch fencing, capsule requirements, effect receipts that travel, and a hash-chained record.
Multi-tenant isolation in a workflow engine: per-tenant circuit breakers with persisted Open state, fair claim caps, tenant-scoped signals, fail-closed routing.
Four standalone pieces: a map of how zero-knowledge proof systems fit together, drawn from the awesome-zkp list I maintain; a source-level walk through OPAQUE password authentication in TypeScript; a Rust rewrite of the spherical code generator inside the G6K lattice sieving toolkit; and a decision guide for micro frontends versus a modular monolith from a four-team migration.
Zero-knowledge proof systems in production →
Zero-knowledge proof systems explained as six replaceable layers, from arithmetization to verifier, and where Groth16, PLONK, STARKs, and Nova sit on them.
OPAQUE password authentication in TypeScript, traced through Cloudflare’s opaque-ts: OPRF blinding, the 129-byte credential record, KE1/KE2/KE3 layout, 3DH keys.
How incremental Gram matrix updates cut one G6K spherical-code candidate at n=128 from minutes to seconds, with the limits of the measurement stated.
Micro frontends vs modular monolith: how Module Federation composes apps at runtime, how a monolith enforces boundaries in code, and the numbers that decide.