Skip to main content
End-to-end latency is more than the matching engine: a request crosses the network, the API servers, and order-entry prioritization before it reaches the engine, and the acknowledgement crosses them again on the way back. Measure round trips end to end, and optimize each leg.

Receiving market data

Use WebSocket, not REST polling. The WebSocket API is the recommended way to receive market data and interact with the exchange: one connection multiplexes every channel and order entry, and updates are pushed the moment they happen. REST is fine for bootstrapping state, but polling it adds a full round trip to every observation. Colocate in Asia. The exchange is hosted in Asia, so network round-trip time is dominated by your distance from it. Running your trading systems in an Asian region gives the lowest and most stable round trips. Provision enough hardware. A host that cannot drain its socket promptly falls behind, and the server force-disconnects clients whose connections stay saturated. Size the host so the socket reader always has a core to itself, with spare CPU and memory beyond that, and scale up for busy accounts or full-depth market-data subscriptions. Watch your receive-queue backlog under peak load to confirm the host keeps up. Keep the read loop light — parse and hand off, and do strategy work on other cores. If you only need a sampled view of bbo or oraclePrices, subscribe with throttleMs to receive at most one frame per window.

Placing and canceling orders

Trade over the socket. Order entry over the existing WebSocket connection skips connection setup entirely — see Trade over WebSocket. Use ALO for the fastest placement. Order entry applies a taker speed bump: any order that could remove liquidity — a non-post-only place, or a modify whose time-in-force allows taking — is held for a short delay before sequencing. ALO (post-only) orders can never take, so they skip the speed bump and go straight to the engine. If your flow is maker-only, submit ALO: it is the fastest path in, and modifies of an ALO order keep the fast path too. The delay is operator configuration that the API doesn’t expose and that can change, so measure your own taker round trips rather than hard-coding a value. Cancels are prioritized. Cancel requests are processed on a dedicated lane ahead of queued order placements, so pulling quotes stays fast even when order entry is busy. cancelOrder (or a batch of them) beats a burst of competing placements to the engine. Use client IDs to skip a round trip. Supply a clientId when placing and you can cancel by clientId immediately — no need to wait for the acknowledgement to learn the server-assigned orderId. Client IDs also let you correlate orders-channel events with in-flight requests. A clientId must be unique among your live orders (reuse after the order reaches a terminal state; placing a live clientId again is rejected with DUPLICATE_CLIENT_ID, and a modifyOrder keeps the order’s orderId and clientId — see Modifying orders for when it keeps queue priority), and live client IDs are bounded in practice by the per-account cap of 1,000 open orders: a placement past it is rejected with OPEN_ORDER_CAP_EXCEEDED.