Hoe debug je 'Latency issues' op een Linux server?
Een latency spike tijdens een live trading sessie voelt als een messteek. Je bot op Binance of Interactive Brokers mist een fill, de order komt 200 ms te laat aan en je spread slurpt je edge op. Rustig maar: met een heldere aanpak op Linux zet je die jitter onder controle en krijg je je backtests en live bots weer stabiel.
Wat je nodig hebt
Begin met een basisset. Een Linux server (Ubuntu 22.04 LTS of 24.04 LTS), een terminal en sudo-rechten.
Bij voorkeur een VPS of dedicated machine bij een provider met lage netwerkjitter naar je broker (denk AWS us-east-1, GCP europe-west4, of een colocatie bij Equinix). Monitoring: houd Prometheus + Node Exporter bij de hand, plus Grafana voor dashboards. Voor netwerkmeetingen: mtr, tcpdump, iperf3.
Voor applicatie-observatie: Python 3.11+ met uvloop, een event loop profiler en een broker-API mock voor tests.
Zorg dat je API keys veilig staan (environment vars, niet hardcoded). Hardware: minimaal 2 vCPU’s, 4 GB RAM, en een netwerkverbinding van 1 Gbps met lage RTT naar je broker. Een typische setup kost €10–€20 per maand bij een VPS-aanbieder. Voor serieuze trading kan een dedicated machine of colocatie vanaf €50–€150 per maand nodig zijn.
Stap 1: Baseline meten en isoleren
Je weet pas wat er speelt als je cijfers hebt. Start met een ping naar je broker API-endpoint (bijvoorbeeld api.binance.com of api.ibkr.com). Richt een baseline in van 5–10 minuten en noteer de min/avg/max RTT en packet loss.
- Voer uit:
ping -c 300 api.binance.com. Verwacht: avg RTT < 50 ms voor EU naar Singapore, < 100 ms voor US-east. Packet loss moet 0% zijn. - Voer uit:
mtr -r -c 100 api.binance.com. Kijk naar loss per hop en vertraging per segment. - Check je systeemload met
htopenvmstat 1 30. CPU > 80% of stevig wisselende load duidt op contention. - Check kernel timers met
chronyc sourcesentimedatectl status. NTP-synchronisatie moet binnen 1 ms lopen.
Veelgemaakte fouten: meten naar een HTTP-IP zonder SNI-resolutie, of vergeten dat je broker meerdere PoP’s heeft.
Gebruik daarom de juiste endpoint en test naar de dichtstbijzijnde regio. Tijdsindicatie: 15–30 minuten. Resultaat: een baseline die je later als vergelijkingsmateriaal gebruikt.
Stap 2: Netwerk en TCP tuning voor lage jitter
Linux is conservatief ingesteld. Voor trading bots wil je lage latency, niet per se maximale throughput.
- Zet TCP BBR aan:
sudo sysctl -w net.core.default_qdisc=fqensudo sysctl -w net.ipv4.tcp_congestion_control=bbr. Herlaad niet nodig, maar monitor bufferbloat. - Verklein TCP-kaas:
sudo sysctl -w net.ipv4.tcp_low_latency=1. Goed voor korte verbindingen naar APIs. - Beperk kernel network buffers matig:
sudo sysctl -w net.core.rmem_max=16777216,sudo sysctl -w net.core.wmem_max=16777216. Niet té klein: je wilt geen packet loss. - Verhoog de UDP buffer als je WebSockets gebruikt:
sudo sysctl -w net.core.rmem_default=8388608,sudo sysctl -w net.core.wmem_default=8388608. - Zet NIC offloads aan/uit per situatie:
sudo ethtool -K eth0 rx off tx off gro off gso offop virtuele NICs kan jitter verlagen, maar test op je specifieke setup. - Voeg een route toe naar de dichtstbijzijnde PoP van je broker via
ip route addals je provider multi-homed is. Check metip route get.
Pas tuning voorzichtig toe en test altijd na. Veelgemaakte fouten: blind copy-pasten van extreme sysctl-waarden.
Pas één parameter tegelijk aan en meet. Vergeet niet /etc/sysctl.conf te updaten voor herstart-bestendigheid. Tijdsindicatie: 30–60 minuten. Verwacht een daling van 5–20 ms in RTT en minder jitter, afhankelijk van je pad.
Stap 3: CPU, process scheduling en power management
Kernel scheduling en power saving kunnen jitter veroorzaken. Zet je bot op dedicated cores en zorg dat de CPU constant loopt. Veelgemaakte fouten: vergeten dat cloud VMs shared CPU hebben.
- Zet de governor op performance:
sudo cpupower frequency-set -g performance. Op cloud VMs kan dit beperkt zijn, maar op dedicated helpt het. - Pin je Python-proces vast met taskset:
taskset -c 2,3 python bot.py. Gebruik 2 dedicated cores voor je bot en 1 voor logging/monitoring. - Verlaag de timer skew:
sudo sysctl -w kernel.timer_migration=0op kernels die dit ondersteunen. Test of dit geen regressies geeft. - Beperk interrupt load:
cat /proc/interruptschecken, en indien nodig RPS/RFS tuning toepassen voor NIC queues. - Zet swap uit voor latency-gevoelige processen:
sudo swapoff -a(alleen als je voldoende RAM hebt). Monitor RAM-gebruik. - Installeer uvloop:
pip install uvloopen activeer in je bot:import uvloop; uvloop.install(). Vaak 10–30% snellere I/O. - Meet call-tijden met
time.perf_counter_ns()rond je API-calls en orderhandling. Log p50, p95, p99. - Gebruik async HTTP clients (aiohttp of httpx) met connection pooling en keep-alive. Stel timeouts in op 200–500 ms voor order endpoints.
- Voor WebSockets: gebruik ping/pong intervals van 15–30 seconden en een heartbeat-thread om connectie-stabiliteit te meten.
- Profileer CPU-bottlenecks met py-spy of cProfile:
py-spy top --pid $(pgrep -f bot.py). Kijk naar JSON parsing en signature-creatie. - Test met een broker-mock: simuleer latency van 20–100 ms met
tc netem delay 50msop een loopback interface. Valideer je backtest vs live. - Simuleer order latency in backtests: voeg een normale verdeling toe (mean 30 ms, std 10 ms) voor REST, en 5–15 ms voor WebSockets.
- Meet slippage op tick-level data: voor Binance BTCUSDT verwacht 0.01–0.05% slippage bij normale volumes, meer in news events.
- Test broker-limieten: Interactive Brokers heeft rate-limits (bijv. 100 calls/min). Zorg dat je bot queuet en backpressure toepast.
- Risicomanagement: definieer max acceptable latency (bijv. 200 ms voor market orders). Als je die overschrijdt, fallback naar safe-mode: annuleer of limiet order.
- Log elke latency-metric met timestamp en context (symbol, side, size). Bewaar 7–14 dagen voor forensics.
- Ping/mtr naar broker endpoint toont avg RTT < 100 ms en 0% packet loss.
- NTP synchronisatie binnen 1 ms; chronyc sources groen.
- Kernel tuning actief (BBR, tcp_low_latency) en persistente configuratie opgeslagen.
- CPU governor op performance; bot vastgepinnd op dedicated cores.
- Python bot gebruikt uvloop, async HTTP client met pooling, en meet p50/p95/p99 latency.
- WebSocket heartbeats stabiel; geen disconnects binnen 1 uur.
- Backtest latency-simulatie gelijk aan live metingen; slippage en fees meegenomen.
- Risk limits geconfigureerd: max latency, fallback, rate-limits, en logging van elke order.
Soms is een dedicated instance nodig voor stabiele latency. Test ook met chrt -f 99 python bot.py voor realtime scheduling, maar wees voorzichtig met prioriteiten.
Tijdsindicatie: 20–40 minuten. Doel: stabiele CPU-load zonder frequentie-dips, jitter tot onder de 5 ms.
Stap 4: Applicatie-latency debuggen in Python
Je bot zelf kan jitter introduceren. Focus op blocking I/O, JSON-parsing en REST- vs WebSocket-latency.
Gebruik uvloop voor snellere event loops. Veelgemaakte fouten: globale locks gebruiken in async code, of te veel logging op disk zonder buffering.
Log naar stdout en routeer via journald of een buffer naar remote storage. Tijdsindicatie: 45–90 minuten. Doel: applicatie-jitter onder de 5 ms voor REST, en stabiele WebSocket heartbeats zonder disconnects.
Stap 5: Backtest vs live vergelijken en risicomanagement2>
Een backtest met 1 ms latency zegt weinig als live 50 ms jitter heeft. Bouw een testpad dat de live-omgeving benadert.
Veelgemaakte fouten: backtests zonder latency en fees, of vergeten dat broker APIs tijdens peak hours trager zijn. Test rond market open (bijv. 09:30 ET) en vergelijk met rustige uren.
Tijdsindicatie: 60–120 minuten. Doel: een realistisch latency-model dat je risico’s dekt en je orderstrategie valideert, inclusief een betrouwbare Dead Man's Switch voor je trading server.
Verificatie-checklist
Als alles op groen staat, is je Linux server klaar voor stabiele trading. En onthoud: latency is een marathon, geen sprint. Blijf meten, blijf tunen, en houd het hoofd koel bij een live bug terwijl je bot comfortabel binnen zijn risicobudget blijft.
