High-Performance-Limit-Order-Book: How This C++ Engine Cheats the Cost of Matching
A limit order book that wins speed by splitting one hard problem into three cheaper ones: sorted prices, linked order queues, and direct order lookup.
- This repo makes matching fast by routing each operation to the cheapest structure instead of forcing every action through the same path.
- Its real trick is cancellation: an order ID jumps straight to a node, then unlinks in constant time without searching the book.
- AVL trees handle price ordering, linked lists preserve FIFO priority, and the hash map turns order lookup into a shortcut.
- Stop orders and synthetic order generation make the engine feel closer to a live market than a classroom demo.
Most limit order book writeups obsess over matching speed. This repository is more interesting than that. It treats speed as a routing problem: prices go into trees, queue order stays in linked lists, and cancellations skip the search entirely through a hash map.
That design choice changes the feel of the whole engine. Instead of one giant data structure doing everything badly, the system splits work across the structure that makes each action cheapest. That is the real thesis of AkshitaBhansali/High-Performance-Limit-Order-Book.
The fastest path is not the shortest path
The obvious way to think about an order book is as a searchable ledger. This repo rejects that framing. It asks a narrower question every time: what is the least expensive way to answer this specific request?
A new limit order cares about price priority, so it belongs in a sorted structure. A cancel cares about identity, so it belongs in a direct index. A queue position cares about time, so it belongs in a doubly linked list. The book is fast because each operation avoids doing other people’s work.
Three structures, one matching engine
The core model is a triad: Order, Limit, and Book. Orders carry identity and pointers. Limits collect orders at a single price. The book coordinates the whole market and keeps separate trees for buy, sell, and stop logic.
// Conceptual shape of the engine
struct Order {
int orderId;
int quantity;
double price;
Order* nextOrder;
Order* prevOrder;
Limit* parentLimit;
};
struct Limit {
double price;
int totalVolume;
int size;
Order* head;
Order* tail;
};
class Book {
std::unordered_map<int, Order*> orderMap;
// buy tree, sell tree, stop trees
};
That shape matters more than any single method. The linked list preserves first-in, first-out behavior inside a price level. The tree preserves price ordering across levels. The map gives every order an address.
The result is not a monolith. It is a stack of shortcuts, each optimized for a different kind of question.
Why cancellation is the real performance test
Insertion gets attention because it looks busy. Cancellation tells you whether the design is actually sharp. A naive engine has to search for the order, find its level, and then repair the surrounding structure. This engine jumps straight to the node.
| Task | Naive path | This repo's path | Why it matters |
|---|---|---|---|
| Cancel by order ID | Search the book, then remove | Look up the pointer in the hash map, then unlink | Avoids traversal on one of the most common maintenance operations |
| Maintain FIFO inside a price | Sort or scan repeatedly | Use a doubly linked list | Time priority stays O(1) to update |
| Find the best bid or ask | Walk many candidates | Use the price tree | Sorted price levels stay directly accessible |
| Update parent references | Recompute after removal | Store the parent limit on the order | Removal stays local |
That is why the hash map is the quiet hero here. It turns a cancellation into pointer surgery instead of search. In a matching engine, that difference is everything.
Why AVL trees, not just any balanced tree
The repo uses AVL trees for price levels. That is a deliberate choice. AVL trees are stricter than red-black trees, so inserts can cost a bit more, but the tree stays tighter and lookup behavior is more predictable.
In a latency-sensitive system, predictability matters. You are not just chasing a low average. You are trying to narrow the spread of work across operations. A stricter balance policy can be the right trade if the engine values consistent access paths over slightly cheaper inserts.
Stop orders turn the book into a cascade machine
The interesting twist in this repo is that stop orders are not an afterthought. They live in their own trees and wait for the market to move. When a trade crosses a threshold, the engine can activate them and push new orders into the active book.
That makes the system feel reactive instead of static. One execution can release another. That cascade is where the engine starts to resemble a live market, not just a matching exercise.
Generating illustration...
Synthetic chaos is part of the design
The generator is not just making random orders. It uses distributions centered around the spread, which creates clustering near realistic price zones. That matters because a book with only uniform noise does not stress the same parts of the engine.
Realistic synthetic flow tests the exact thing this repo cares about: how the data structures behave when prices bunch up, queues deepen, and the tree has to keep its balance under pressure.
// Conceptual behavior in the generator
// 1. Center prices near the spread
// 2. Bias order flow around realistic market levels
// 3. Stress the book with clustered inserts and cancels
std::normal_distribution<double> priceAroundSpread(mean, sigma);
std::uniform_int_distribution<int> qtyDist(minQty, maxQty);
Where this repo sits in the order-book universe
This is not trying to be QuantConnect/Lean, and it is not trying to be a full exchange stack. It is narrower than that. The value is in the implementation choices, not in the breadth of surrounding trading infrastructure.
| Project | Language | Scope | What it optimizes for |
|---|---|---|---|
| AkshitaBhansali/High-Performance-Limit-Order-Book | C++ | Focused matching engine and simulation utilities | Cheap routing, direct lookup, predictable price handling |
| QuantConnect/Lean | C# | Broad algorithmic trading platform | Feature breadth, backtesting, and live-trading workflow |
| Aeron | Java and C++ | Low-latency messaging infrastructure | Transport efficiency and throughput, not order-book logic |
| Simple educational LOB demos | Mixed | Single-concept examples | Teaching the basic mechanics of matching |
That places the repo in a useful niche. It is a reference implementation with enough ambition to teach real tradeoffs, but not so much surrounding machinery that the core idea gets buried.
What this repo teaches
The main lesson is simple: low latency is usually not one miracle optimization. It is disciplined structure selection. Every major action gets the cheapest path available, and the engine stays honest about what each data structure is good at.
That is why this project is worth reading. It shows a matching engine as a set of carefully chosen shortcuts, not a black box. In that sense, the code is less a simulator than a map of how to think about speed.