Replay Engine

Deterministic event playback with configurable market scenarios — test queue saturation, measure burst handling, and simulate exchange disconnects

● IDLE

Why Replay Engines Matter in Trading

Every production trading system needs a replay capability. Engineers use replay to:

  • Validate behavior under load: "What happens to our gateway when NASDAQ opens and sends 50K msgs/sec?"
  • Test failure modes: "How does the system behave when CME disconnects for 5 seconds mid-feed?"
  • Measure queue saturation: "At what rate do we start dropping messages? Is our backpressure tuned correctly?"
  • Benchmark changes: "Did this optimization actually reduce p99 latency under burst traffic?"
  • Reproduce production incidents: Deterministic replay of recorded feeds lets engineers reproduce exact failure conditions.

Traffic Profiles

Each scenario uses a different traffic shape. These model real market conditions:

Constant — Steady State
Uniform rate throughout. Models a normal trading session (no events, no news).
Burst — Periodic Spikes
Low baseline with periodic 10x spikes. Models options expiry, earnings releases, or batch auction results.
Flash Crash — Calm → Explosion → Aftermath
20% baseline → 500% spike → gradual decay. Models 2010 Flash Crash or circuit-breaker events.
Ramp — Linear Saturation Test
Linear ramp from 0 to max rate. Finds the exact saturation point of the queue processor.

Available Scenarios

Loading...

What to Observe During Replay

While a scenario runs, switch to the other pages to observe system behavior:

PAGEWHAT TO WATCH
Live Terminal Signal feed scroll rate, dropped message counter, queue depth
Performance p99 latency during bursts, GC collections during high allocation, allocation rate spikes
Concurrency Understand why the architecture handles these scenarios without locks

Implementation

REPLAY ENGINE — RATE-CONTROLLED EVENT INJECTION
private async Task RunScenarioAsync(ReplayScenario scenario, CancellationToken ct) { while (!ct.IsCancellationRequested && elapsed < duration) { // Calculate rate based on traffic profile curve var effectiveRate = CalculateEffectiveRate(scenario, elapsed); // Simulate exchange disconnect window if (scenario.SimulateDisconnect && IsInDisconnectWindow(elapsed)) { // Feed pauses — queue drains, UI shows disconnect await Task.Delay(100, ct); continue; } // Generate batch sized for target rate var batchSize = (int)(effectiveRate * batchInterval / 1000.0); for (int i = 0; i < batchSize; i++) { // Enqueue with latency measurement var sw = Stopwatch.StartNew(); _queueProcessor.EnqueueAsync(signal); _metrics.RecordLatency(sw.ElapsedTicks); } await Task.Delay(batchInterval, ct); } }