A client reporting matching latency of 200 ms is a clear symptom of order book architecture problems. In our practice, one exchange lost up to 10% of orders due to database-level locks. The solution: an in-memory limit order book with minimal synchronization. We deliver high-performance, ready-to-deploy order books for crypto exchanges. Our experience: 15+ projects. The typical investment for a turnkey order book ranges from $30,000 to $50,000, with an ROI achieved in under 6 months through reduced infrastructure costs and improved trading platform performance. Infrastructure cost savings from the in-memory approach can reach 40%, translating to tens of thousands of dollars annually for high-volume platforms. Our clients typically save $20,000-$50,000 per year on cloud infrastructure after migrating to our in-memory order book.
The order book is the central component of any exchange — an ordered list of buy and sell orders for an asset. Its performance directly determines the entire trading system's capabilities, from execution latency to maximum throughput. It supports limit and market orders. The average infrastructure cost savings after deploying an in-memory solution reach 40% under a load of 50,000+ orders per second.
What is the cost of order book development?
The cost for a turnkey solution is $30k–$50k, with typical annual savings of $20k–$50k on infrastructure after migration.
How is low latency achieved?
In-memory order book architecture
The order book resides entirely in RAM; disk access on every match is unacceptable for latency. To ensure cache-line efficiency and minimize memory barrier overhead, we employ a lock-free design where possible. The classic structure employs two sorted containers — bid side (buys, descending price) and ask side (sells, ascending price). Each price level contains a FIFO queue of orders adhering to price-time priority.
type Order struct { ID string UserID int64 Side Side // Buy | Sell Type OrderType // Limit | Market Price decimal.Decimal Quantity decimal.Decimal FilledQty decimal.Decimal CreatedAt int64 // nanosecond timestamp } type PriceLevel struct { Price decimal.Decimal Orders []*Order // FIFO queue } type OrderBook struct { Bids *redblacktree.Tree // Price -> *PriceLevel, descending Asks *redblacktree.Tree // Price -> *PriceLevel, ascending Orders map[string]*Order // OrderID -> Order (for fast cancellation) mu sync.RWMutex } Tree structure choices:
- Red-black tree: O(log n) for all operations. The library emirpasic/gods is a solid Go implementation.
- Skip list: concurrent but more complex; lock-free skip lists offer better scalability on multi-core systems with non-blocking operations.
- Sorted slice + binary search: O(n) insert, O(log n) search. Works for small books (< 1000 levels).
The importance of O(1) order cancellation
If cancellation required searching through all levels, latency grows linearly; therefore, we use a hashmap Orders map[string]*Order for direct indexing by ID, which is critical for high-frequency trading where every microsecond counts.
How does the matching algorithm work?
FIFO vs Pro-Rata
Price-Time Priority (FIFO) is the standard for most exchanges. FIFO is up to 2x faster than Pro-Rata under high load due to simpler bookkeeping, but Pro-Rata incentivizes larger orders by distributing fills proportionally. We choose the algorithm based on your requirements.
func (ob *OrderBook) matchOrder(taker *Order) []Trade { var trades []Trade counterSide := ob.getCounterBook(taker.Side) for taker.RemainingQty().IsPositive() { bestLevel := ob.getBestLevel(counterSide) if bestLevel == nil { break } if !ob.priceCrosses(taker, bestLevel.Price) { break } for len(bestLevel.Orders) > 0 && taker.RemainingQty().IsPositive() { maker := bestLevel.Orders[0] fillQty := decimal.Min(taker.RemainingQty(), maker.RemainingQty()) trades = append(trades, Trade{ Price: bestLevel.Price, Quantity: fillQty, TakerOrderID: taker.ID, MakerOrderID: maker.ID, TakerSide: taker.Side, Timestamp: time.Now().UnixNano(), }) taker.FilledQty = taker.FilledQty.Add(fillQty) maker.FilledQty = maker.FilledQty.Add(fillQty) if maker.RemainingQty().IsZero() { bestLevel.Orders = bestLevel.Orders[1:] delete(ob.Orders, maker.ID) } } if len(bestLevel.Orders) == 0 { ob.removeLevel(counterSide, bestLevel.Price) } } return trades } Snapshots and incremental updates
Clients do not receive the full order book upon connection due to potential size of multiple megabytes; instead, they request a snapshot of the top N levels via REST and then subscribe to a WebSocket channel for incremental diff updates. Each diff carries a monotonic sequence number to detect gaps.
| Scenario | Action |
|---|---|
| New connection | GET /api/v1/orderbook/snapshot?symbol=BTCUSDT&depth=50 |
| Missing diff (sequence gap) | Request a new snapshot |
| Normal stream | Apply diffs with sequence+1 |
type OrderBookDiff = { sequence: number; bids: [string, string][]; asks: [string, string][]; }; class OrderBookClient { private bids = new Map<string, string>(); private asks = new Map<string, string>(); private lastSeq = 0; applyDiff(diff: OrderBookDiff) { if (diff.sequence <= this.lastSeq) return; if (diff.sequence !== this.lastSeq + 1) { this.requestSnapshot(); return; } diff.bids.forEach(([p, s]) => s === '0' ? this.bids.delete(p) : this.bids.set(p, s)); diff.asks.forEach(([p, s]) => s === '0' ? this.asks.delete(p) : this.asks.set(p, s)); this.lastSeq = diff.sequence; } } Visualization: tick grouping and depth chart
A real order book can have thousands of levels. For display, volumes are grouped by tick (minimum price increment). Users can switch between tick sizes (e.g., 0.01, 0.1, 1 for BTC/USDT) and the system aggregates volumes accordingly. The depth chart shows the relative depth of each level — green for bids, red for asks.
Common problems and their solutions
- **Race conditions on cancellation and execution**: use RWMutex; for high concurrency, lock-free structures. - **Missing diff updates**: client stores the sequence; on a gap, requests a full snapshot. - **Too many levels in response**: limit depth (top 50) and provide grouping.What's included in order book creation
- Architecture and design: matching algorithm, replication scheme.
- In-memory engine implementation in Go with latency < 100 μs.
- REST API and WebSocket feed with snapshots and diff updates.
- React frontend components with grouping and depth chart.
- PostgreSQL integration for order persistence.
- Load testing (100k+ orders/sec).
- Documentation: OpenAPI, protocol description, deployment guide.
- Client team training.
- Warranty and support: 3 months post-deployment.
Our turnkey implementation process
- Requirements analysis and architecture.
- In-memory matching engine implementation.
- REST API + WebSocket feed.
- Frontend visualization.
- Integration with external systems.
- Load testing and optimization.
- Documentation and handover.
Performance
Our order book development service focuses on in-memory matching engine design for crypto exchanges, ensuring sub-100 microsecond latency. We specialize in high-frequency trading order book architecture with low-latency matching and WebSocket feeds. For an exchange with 10–20 pairs and moderate volume: a single Go process handles > 50,000 orders/sec. If needed, shard by pairs and horizontally scale API. Infrastructure cost savings from the in-memory approach reach 30-40% under high load.
| Metric | Value | Conditions |
|---|---|---|
| Matching latency | < 100 μs | In-memory, single core |
| Add order throughput | 100k+ ops/sec | Go, Red-Black tree |
| Cancel order | O(1) | Hash map lookup |
| Snapshot generation | < 1 ms | Top 50 levels |
| WS diff broadcast | < 1 ms | After each trade |
Contact us to evaluate your project. Order a turnkey order book implementation — get a consultation from an engineer with 10+ years in blockchain. Infrastructure cost savings and improved trading platform performance are real results from our projects.







