All Blog Posts
eth_subscribe reconnect, backpressure, and WebSocket costs

eth_subscribe reconnect, backpressure, and WebSocket costs

By Elias Faltin 7min read

A dropped eth_subscribe connection leaves two jobs behind: recover the missed data and pay for the recovery requests. A slow consumer can cause the same disconnect repeatedly. Without a saved block cursor, each retry risks missing logs or scanning history you already processed.

This guide covers the operating costs and failure checks for Ethereum WebSocket subscriptions. For subscription setup and a recovery implementation, start with WebSockets for blockchain developers.

What a WebSocket subscription costs

Count subscription requests, delivered notifications, and recovery requests separately. Alchemy bills standard Ethereum subscription traffic by bytes. Infura uses event-specific credits. Dwellir counts each notification as one response.

OperationAlchemyInfuraDwellir
eth_subscribe10 compute units5 credits1 credit
eth_unsubscribe10 compute units10 credits1 credit
newHeads0.04 compute units per byte50 credits per block1 credit per notification
logs0.04 compute units per byte300 credits per block1 credit per notification
Pending transactions0.04 compute units per byte200 credits at approximately one-second intervals1 credit per notification

These published billing units were checked on September 22, 2026. They are not equivalent units of currency. Apply your plan's allowance and price to estimate the bill.

For example, 1,000 bytes delivered through an Alchemy Ethereum subscription consume 40 compute units. Measure your payloads before using that size in a forecast. Full transaction objects and transaction hashes produce different byte totals.

Infura's stated pending-event cadence gives an illustrative daily estimate of 200 × 86,400 = 17.28 million credits. Actual usage depends on the delivered event stream. Its logs charge applies per block, so do not multiply that rate by every matching log.

On Dwellir, estimate the notification count and add request responses. One credit per notification simplifies that calculation, but a rise in events still increases usage. Compare the total against your plan allowance.

WebSocket billing units for subscription setup, block headers, logs, and pending transactions.

Include recovery in the usage estimate

A reconnect creates a new subscription. Recovering missed logs also requires HTTP requests. Each retry adds usage, even when it restores a stream you already paid to consume.

For illustration, assume 60 disconnects in an hour. Each recovery uses one eth_subscribe call and one eth_getLogs call:

ProviderCalculationAdditional usage
Alchemy60 × 10 + 60 × 604,200 compute units
Infura60 × 5 + 60 × 25515,600 credits
Dwellir60 × 1 + 60 × 1120 credits

This example excludes live notifications, head checks, retries, and additional log-query windows. Actual recovery costs depend on the gap and the provider's query limits. See the eth_getLogs limits guide for window sizing.

Use exponential backoff with jitter and a retry limit. Alert when a stream repeatedly exhausts that limit. A retry limit should trigger investigation or failover, while the application records that its data is incomplete.

Persist the last durably processed block, including its hash. After reconnecting, subscribe before recovering the missing range, and buffer new events during recovery. Re-read an overlap to check for chain reorganizations. Deduplicate logs by block hash, transaction hash, and log index, and reverse records from replaced blocks.

HTTP recovery can retrieve canonical blocks and logs. It cannot reconstruct every pending transaction that appeared and disappeared while you were disconnected. A mempool feed needs an explicit data-loss policy.

Reconnect sequence showing resubscription and HTTP recovery requests that add to live-stream usage.

Handle slow consumers before the connection closes

Geth buffers notifications before sending them. Its pub/sub documentation describes a 10,000-notification limit, after which it closes the connection. This is a Geth limit, not a guarantee for every hosted endpoint.

Separate socket reads from database writes and other slow work. Measure the application's queue depth and the age of its oldest unprocessed event. Those measurements show whether processing is falling behind before a disconnect occurs.

Bound the queue and decide what happens when it fills:

  • For an indexer or accounting stream, preserve the last committed cursor and recover missing canonical events. Do not silently discard logs.
  • For a display that needs only the newest value, coalescing updates can be acceptable. Count discarded updates and label stale data.
  • For pending transactions, record any loss because canonical log recovery cannot restore the original stream.

Narrow logs subscriptions with contract addresses and topics where possible. This reduces work for the consumer. It also reduces byte-based or per-notification usage, though per-block billing does not necessarily fall with the log count.

Repeated disconnects during traffic bursts justify checking consumer capacity, gateway limits, and the network path. The disconnect alone does not prove which component failed.

Detect a stalled stream while the socket is open

A connection state of OPEN does not prove that subscription data is current. Track transport health and chain progress separately.

ObservationCheckResponse
No frames or heartbeat repliesWebSocket ping/pong timeoutReconnect with backoff and recover the gap
Heartbeats arrive but heads stopCompare with an independent HTTP headReconnect if the chain advanced and the stream did not
Processing lag grows during a burstQueue depth and processing timeReduce subscription volume or increase consumer capacity
Two workers process the same streamSubscription ownership and consumer IDsKeep intended redundancy; remove accidental duplicates
HTTP health check passes but WSS failsAn authenticated WebSocket subscriptionAlert on the affected transport

Choose staleness thresholds for each chain and application. Account for missed blocks and upstream delays. Do not force every replica to reconnect because one expected block was late.

WebSocket protocol ping/pong checks connection liveness. Browsers do not expose protocol ping frames to application code. Browser clients need an application heartbeat or another supported liveness check.

WebSocket monitoring checks for slow consumers, dead connections, stalled block streams, and duplicate subscriptions.

Check the stream before increasing the plan

Use one record per subscription to track its filter, owner, notification rate, last processed block, and recovery requests. Keep credentials out of those records. Compare notification growth with changes to filters and worker counts.

Before increasing capacity, check whether a pending feed is required and whether duplicate workers are intentional. Then measure the consumer's processing rate under a representative burst. A larger request allowance will not fix a blocked reader.

Dwellir's WebSocket pricing counts each notification as one credit. Include HTTP recovery in your estimate and check which plans support eth_getLogs. Contact the Dwellir team with your peak event rate and recovery window to size the endpoint.

read another blog post