← Work

Infrastructure

Low-latency multi-venue data infrastructure

Direct WebSocket feeds from four exchanges, a Chainlink oracle relay and the Polymarket CLOB, time-aligned and logged across five machines placed by measured latency. Roughly 24 GB of tick data recorded, and a fire path taken from ~10 s naive to ~58 ms.

Role

Builder and operator

Period

2026 — present

Stack

Python, asyncio, WebSockets, EIP-712, AWS Ireland & Virginia, Hetzner, Tailscale

Why build it

Every model in the other projects needs the same thing: clean multi-venue data with known latency characteristics. Aggregator APIs hide the milliseconds the research is about, so every feed here is direct.

Each event carries two timestamps, the venue's and the local receive time. That pair is what makes latency analysis possible after the fact, and it costs nothing to record.

Where it runs, and why

LocationRoleWhy there
AWS IrelandExecution, orderbook recording~25 ms RTT to the Polymarket CLOB
AWS VirginiaNOAA scraper~5 ms to the source, against ~181 ms from Turkey
Hetzner IstanbulSecond scraping IPIndependent rate-limit budget
İzmir, home Linux boxInference engine, 24/7 analysisA Turkish residential IP survives rate limits that ban datacentre ranges
LaptopDevelopment

They mesh over Tailscale. Execution is also reachable on a public address, so a mesh outage cannot stop trading. The home box runs Monte Carlo and posterior updates around the clock and pushes triggers to Ireland over a WebSocket. Ireland listens and fires.

The fire path

Naive order submission took 10,163 ms. It now takes about 58 ms. Most of that came from taking things out:

  • Pre-signing EIP-712 orders at arm time. The critical path becomes a bare HTTP POST, about 24 ms.
  • Warming the tick-size, neg-risk and fee-rate caches before the event window. Worth roughly 470 ms.
  • Deleting a blocking order-status poll, which turned out to be the dominant term all along.
  • A 4-second keep-alive loop. Cold HTTP calls averaged 878 ms; on a persistent connection, ~172 ms.
  • Not polling balances. That endpoint is 5–30 s stale, so reading it costs latency and tells you nothing.

Decision-to-post is 0.1–0.2 ms. The order POST round trip is about 30 ms.

Tail latency

One scraping IP sat at a p99 near 1,500 ms with a single 5,031 ms outlier. During that outlier the market repriced and the order came back unmatched.

There is no faster host to move to. What worked was polling the same source from two independent IPs and taking whichever arrives first, deduplicated on the observation's own timestamp. Live logs show the winner alternating between hosts by 209 ms, then 113 ms, then −7 ms. Neither host is reliably ahead. Racing them removes the tail.

Sustained polling at ~166 requests per second got a datacentre IP banned for hours. The residential IP under the same load was throttled but stayed up. So bursts are confined to the publication window and the system idles outside it.

Orderbook state

Polymarket's WebSocket sends full book snapshots plus incremental deltas. The deltas carry no top-level asset identifier; the identifiers sit inside the change array, because the YES and NO legs of a binary market are coupled and one order emits two entries.

An implementation that filters on the top-level field drops every delta and never reports an error. Once that was handled, the reconstructed book agreed with independent REST snapshots at 99–100% on top of book.

Safety

I wrote the risk layer after a loss, not before one. A single-market strategy re-fired every four minutes with nothing to stop it and lost about $80.

What exists now: per-market circuit breakers, daily spend caps, fire-count limits, an inventory clamp, a dead-man switch on book silence, and a feed-staleness kill switch. Defaults fail closed. A stale feed means no new positions. A missing model feed means skip, never assume. Live submission raises unless an environment flag is set explicitly, and post-only is mandatory with an abort if the venue reports taker behaviour.

Scale

About 24 GB of tick-level market data across the projects: roughly 19 GB of crypto tapes and 5 GB of weather and football orderbook data, with journal streams reaching ~500 MB per market-day at peak. All of it replays, which is the only reason the negative-result measurements were possible.

Ask me about it