The Business Case
In OTC trading, the time between receiving a client order and hedging your exposure is directly proportional to risk. A 100ms delay on a volatile asset can mean thousands of dollars in slippage.
When we started building the hedging engine, we evaluated Go, Java, and Rust. The decision came down to one question: can we guarantee consistent latency under load?
Why Not Go?
Go is our choice for many services. It's productive, has great concurrency primitives, and deploys easily. But the garbage collector introduces unpredictable pauses.
In benchmarks, Go performed well on average. But P99 latencies showed 5-10ms GC pauses that appeared randomly under load. For a hedging engine processing hundreds of quotes per second, these pauses create windows of unhedged exposure.
Why Rust
Rust gives us three things that matter for this use case:
- No GC pauses: Memory is managed at compile time. Latency is consistent and predictable.
- Zero-cost abstractions: We can write clean, high-level code that compiles to optimal machine code.
- Type system as risk control: The borrow checker prevents data races. In a system handling real capital, this is a feature, not a constraint.
The Results
After migrating the hedging engine from a Go prototype to Rust:
- P99 latency: Dropped from 12ms to 0.8ms
- Throughput: 3x improvement in quotes processed per second
- Memory: 60% reduction in memory usage
The initial development was slower — Rust's learning curve is real. But the operational confidence we gained was worth it. The system handles our entire trading volume with predictable, consistent performance.
When Not to Use Rust
Rust isn't the answer for everything. For our API gateway, admin panels, and monitoring dashboards, we use Go and TypeScript. The productivity gain outweighs the performance difference for those use cases.
The key insight: match the language to the risk profile of the service, not to personal preference.