Reconnect
The pattern that works:- Detect the close. WS:
'close'event. gRPC: stream'end'or'error'. - Wait with exponential backoff. Start at 1 second, double each retry, cap at 60 seconds.
- Reconnect. Reset the backoff to 1 second on a successful connect.
- Re-send your subscriptions. They are not persisted across reconnects.
- Fill the gap with REST. From the timestamp of your last good event, query
/api/v1/candles?start=...or/swaps/range?start=...for the missing window. We do not replay missed events on the stream.
Backpressure
If your client is slower than the message rate, the server’s send buffer fills up. When it overflows, you get disconnected with an error indicating overflow. To stay under:- Don’t await heavy work in the receive loop. Push events into an in-memory queue and process them on a separate worker.
- Coalesce. If you’re rendering a chart, you usually only need the latest event per pool per frame, not every event.
- Filter aggressively. Subscribe with the narrowest filter you can — a
poolsfilter is much cheaper than no filter.
Keepalive
WebSocket: send{ "type": "ping" } every 30 seconds. The server replies with { "type": "pong" }. If you don’t see a pong within ~10 seconds, treat it like a disconnect.
gRPC: configure HTTP/2 keepalive on the channel:

