A lightweight tool for measuring Deribit WebSocket RPC round‑trip latency, including:
- Buy / Sell order latency
- Raw‑book tick‑aligned timestamps
- Engine processing timestamps (
usIn,usOut,usDiff) - CSV logging
- Summary statistics (p50, p90, p99, max)
- No CLI — everything configured through
config.toml - Credentials provided strictly via environment variables
- Single configuration file (
config.toml) - Zero CLI arguments
- Async Rust (
tokio,tungstenite) - Detailed latency samples & summaries
- Supports buy/sell side selection
- Supports edit‑offset stepping (move quotes closer or further away)
- Tick‑aligned latency via raw‑book subscription
- Full Docker + Devcontainer setup
- CI workflow included
.
├── Cargo.toml # Project manifest: dependencies, metadata, build settings
├── config.toml # User-defined configuration loaded at runtime
├── README.md # Project documentation and usage instructions
├── LICENSE # License information for the project
├── rustfmt.toml # Code formatting configuration for Rust
├── .gitignore # Specifies files Git should ignore
├── docker-compose.yaml # Docker Compose setup for running multi-service environments
├── .devcontainer/
│ ├── devcontainer.json # VS Code Dev Container configuration
│ └── dev.Dockerfile # Dockerfile for the development environment
├── .github/
│ └── workflows/
│ └── ci.yaml # GitHub Actions workflow for CI
└── src/
├── config.rs # Logic for loading and handling configuration values
├── main.rs # Application entry point
├── deribit_client.rs # Client implementation for interacting with Deribit API
├── latency.rs # Utilities for measuring and processing latency data
└── summary.rs # Functions to generate and print application summaries
Clone this repo:
git clone https://github.com/bxvtr/deribit-latency-tester.gitCreate .env and ensure that the config.toml is correctly configured:
DERIBIT_CLIENT_ID=your_client_id
DERIBIT_CLIENT_SECRET=your_client_secretLoad .env:
set -a
source .env
set +aRun deribit-latency-tester:
cargo build
cargo run --releaseLatency samples are written to output_latency_csv, for example:
output/local_latency.csv
Includes:
- RTT (mono + wallclock)
- Tick timestamps
- Engine (
usIn,usOut,usDiff) - Ack deltas
- Error codes & messages
The sample CSV contains only synthetic data. Real trading data and order identifiers are never committed to this repository.
Example:
==================== LATENCY SUMMARY ====================
RTT (Send → Ack):
count: 100 min: 340 µs median: 620 µs p90: 900 µs p99: 1400 µs max: 1600 µs
...
=========================================================
All runtime behavior is controlled through this file.
Below is a complete explanation of all parameters.
true = Deribit Testnet, false = Mainnet
"buy" or "sell"
Example: "BTC_USDC-PERPETUAL"
Order quantity.
Fallback price if Deribit ticker fails.
Initial offset relative to the market/base price.
How much the edit step changes the offset:
- BUY →
offset = offset - step - SELL →
offset = offset + step - Negative step → edits move quote *closer- to market.
Number of open → edit → cancel cycles.
Delay between RPCs to avoid rate limits.
Output file path.
Enable raw‑book subscription for tick‑aligned latency metrics.
If true, prints summary at the end.
When subscribe_raw_book = true, the tool subscribes to:
book.<instrument>.raw
This subscription does not determine when orders are sent.
It is used purely for advanced latency analytics:
- Every raw‑book tick is timestamped upon arrival.
- These timestamps are stored and associated with each RPC.
- This enables latency relative to the most recent market‑data tick, not only RTT.
This produces a more realistic latency profile for trading‑engine proximity testing.
The tool uses multiple timestamp sources with different granularities:
Used for all latency measurements:
- RPC send/receive time
- Round-trip latency (RTT)
- Tick-aligned latencies
- Ack-to-ack deltas
These are derived from Rust’s Instant::now() and recorded at nanosecond precision.
Used for human-readable logging:
- RFC3339 timestamps (
UTC) - Resolution: microseconds
Raw values from Deribit:
usInusOutusDiff
All provided at microsecond resolution.
If the WebSocket connection fails, send_rpc() returns an error → the program stops.
There is *no reconnect logic- (current design).
If Deribit returns an error inside the RPC response body, the tool logs it and continues to the next step.
If an open order does not return order_id, edit/cancel is skipped.
There is *no explicit timeout- — send_rpc().await waits until Deribit responds or the socket errors.