Binance Depth Streams and Snapshots: Building a Local Order Book
A depth stream is a list of changes. Turning it into a book that matches the exchange's own requires one snapshot, a buffer, and a rule for deciding when the two no longer agree. Binance publishes that rule in seven numbered steps; this guide walks them, then covers the connection limits and the weight arithmetic that decide whether the process survives a full trading day.

Cover artwork: CoinSoso · AI-generated, not a photograph of a real venue, product or market capture.
Key takeaways
- The diff depth stream publishes changes with an update-id range, not a book, so a local book is always a snapshot plus a sequence of deltas.
- Binance's published procedure buffers events first, fetches the REST snapshot second, and discards buffered events whose final update id is at or below the snapshot's id.
- The gap test is the whole safety mechanism: if an event's first update id is more than one above the local id, the local book is wrong and must be rebuilt from a new snapshot.
- A 5,000-level snapshot costs 250 request weight, and the request-weight allowance is 6,000 per minute, so resync frequency is a budget decision, not a free retry.
- A single stream connection is valid for 24 hours, the server pings every 20 seconds, and five inbound messages per second is the connection limit.
A depth stream is a delta, not a book
The first thing to internalise about btcusdt@depth is what it does not contain. Each event carries a symbol, an event time, a first update id U, a final update id u, and two short lists: bid price levels that changed and ask price levels that changed. It does not contain the rest of the book.
That leaves the builder with one job: hold a complete book and apply every change in order, with no gaps. The snapshot provides the starting state and the stream provides the changes. Everything difficult about the problem lives in the seam between the two, which is why Binance publishes an explicit procedure rather than describing it as an implementation detail.
There are two depth streams with different jobs:
- Partial book depth returns the top 5, 10 or 20 levels per side, complete on every message, at 1,000 ms or 100 ms. It is easy to consume and it is not a book. You cannot compute depth at a price band wider than 20 levels, and you cannot tell whether a level was added or simply moved into the visible window.
- Diff depth returns only the changes, at 1,000 ms or 100 ms, and needs a snapshot to initialise.
The name of the second stream is the whole problem statement. A diff is meaningless without the thing it is a diff against.
The seven steps, and why they are in that order
Binance’s documented procedure for managing a local book is short enough to quote in structure:
- Open the diff depth stream.
- Buffer the events received, and note the
Uof the first one. - Fetch a depth snapshot from the REST endpoint.
- If the snapshot’s
lastUpdateIdis strictly less than theUfrom step 2, fetch the snapshot again. - Discard buffered events whose
uis less than or equal to the snapshot’slastUpdateId, then set the book to the snapshot. - Apply the remaining buffered events, then every subsequent event, using the update procedure.
- On each event, check
uagainst the local id; ifUis greater than the local id plus one, discard the book and start again.
The order matters. Subscribing before snapshotting is what makes the buffer contain the events that will arrive during the snapshot request — a request that can take a round trip or more. If you snapshot first and subscribe afterwards, every change that happened in between is lost, and the book is wrong from its first millisecond without any error being raised.
The check in step 4 is the part most implementations skip. If the snapshot is older than the first buffered event, there is a hole between them and retrying is the correct response. Retry loops should be bounded, and each attempt costs weight.
The update procedure itself has three branches that map to three real states:
| Condition | Meaning | Action |
|---|---|---|
u ≤ local update id |
Event already applied | Ignore it |
U = local update id + 1 |
Contiguous | Apply the level changes and set local id to u |
U > local update id + 1 |
Events missing | Discard the book, resync from step 1 |
The gaps the stream cannot close
The gap test only catches a missing event. It does not catch a book that has stopped changing.
Consider a connection where the exchange stops publishing updates for one symbol — a matching-engine issue, a symbol suspension, a network path that silently drops the socket without a close frame. Your local id stops advancing. Every new event either matches the id or is a gap, and a silent empty stream produces neither. The book remains “valid” and goes stale.
Two habits address this. The first is to compare the event time E in each message against wall-clock time and alarm when the difference exceeds a threshold you choose. The second is to schedule an independent resync at a fixed interval — every few minutes during trading, or before any decision that depends on deep levels — rather than trusting the sequence to prove freshness.
The weight budget decides how often that is affordable. A single 5,000-level snapshot costs 250 request weight, and Binance’s public exchange information reports a request-weight ceiling of 6,000 per minute shared by every request the key makes. Twenty-four full snapshots a minute would consume the entire budget for the whole account; a 1,000-level snapshot costs 50, which allows 120 resyncs a minute in theory and a far smaller number in practice once every other endpoint is counted. Most book builders do not need the deepest snapshot at all — they need the levels they quote against.
Connection rules that decide uptime
The stream has hard limits, and each of them produces a failure mode that looks like an exchange problem:
- A connection is valid for 24 hours, and a
serverShutdownevent precedes the disconnection. Reconnect on the clock, not only on errors. - The server sends a ping every 20 seconds and disconnects a connection that does not return a pong within a minute. The pong must echo the ping payload.
- Inbound messages are limited to 5 per second, counting pings, pongs and JSON control frames. A reconnect storm or an aggressive subscribe loop can trip this, and Binance states that repeatedly disconnected IPs may be banned.
- There is a limit of 300 connections per attempt every 5 minutes per IP, which is the rule that punishes a naive reconnect-on-failure loop most directly.
wss://data-stream.binance.visioncarries market data only. It is the right host for a public book builder and the wrong one for account events.
A book service that reconnects on a randomised delay, resubscribes once per connection, and rebuilds from a snapshot is a few dozen lines longer than one that reconnects immediately. The difference is measured in bans.
What the local book still cannot tell you
Even a perfectly synced book is not the exchange’s full state.
The snapshot and the stream both publish aggregated price levels, and a diff shows the new total at a level. It does not show how many orders sit there, how they are sized, or whether any of them belong to a hidden order type that never appears in the book at all — an iceberg’s reserve, or a venue-specific retail improvement order withheld from the public feed. Those orders still compete with yours when price arrives; they are simply invisible until they trade.
That asymmetry is not a data-quality problem to be engineered away. It is the reason a local book is a good input for quoting and a bad input for asserting what will fill. The related question of what depth actually predicts, and where the number stops being useful, is covered in spread, depth and slippage and in the comparison of how venues publish their order book snapshots. The imbalance-versus-last-price distinction is a separate trap, set out in whether book imbalance predicts the next print.
The other trap is the budget itself. Depth requests compete with order requests for the same weight ceiling, and a resync storm at the wrong moment can leave an account unable to place an order. The accounting is documented in API rate limits and order weights, and it is the reason a production book builder should reserve headroom rather than treat 6,000 as a target.
Risk note. The stream names, endpoints, limits and weight values in this article were read from Binance’s own Spot API documentation on 2026-10-30. Endpoints, weight schedules and limits change; the procedure is the durable part, the numbers are not. Nothing here is investment advice.
Sources
How this was researched. Written from primary documentation and the exchange or protocol's own published material, with sources listed at the end of the article.
Primary sources for the factual claims on this page. A date appears only where a human has actually read the source; where it is missing, the check is still outstanding.
Frequently asked questions
Why not just poll the REST snapshot every second instead of streaming?
Because the snapshot is the expensive call. Binance prices a depth request by the number of levels asked for: 1 to 100 levels costs 5 request weight, 101 to 500 costs 25, 501 to 1,000 costs 50, and 1,001 to 5,000 costs 250. The request-weight budget is 6,000 per minute, so a 5,000-level poll every second would consume 15,000 weight per minute. The stream carries the same changes for the cost of one connection.
What does it mean when the stream sends a quantity of zero?
It means the price level is gone. Binance's update procedure says that for each price level in the bid and ask lists you set the new quantity, insert the level if it does not exist locally, and remove the level from your book when the quantity is zero. Treating zero as 'update to zero' leaves an empty row in your book and quietly corrupts any depth calculation built on it.
How do I know the local book has drifted?
Two signals. The first is the gap test: if an event's first update id U is greater than your local update id plus one, events are missing and Binance says to discard the book and restart. The second is a resync you schedule yourself, because a book can stay sequence-consistent while still being stale — a connection that stops receiving events and does not error will pass the gap test forever.
Can I use data-stream.binance.vision for a user-data feed?
No. Binance documents that endpoint as market data only, and states that the user data stream is not available from that URL. It is useful for a book builder that runs without an API key, but account events still have to come from the main stream hosts, which means a listenKey and an authenticated connection.
What happens at the 24-hour mark?
The connection is closed. Binance states that a single connection to stream.binance.com is only valid for 24 hours and that a serverShutdown event is sent before the server goes down. A book builder that only reconnects on an error will sit on a dead socket, so the reconnect path should be driven by the clock as well as by failures.
Where to go next
Independent research. Each card shows the platform’s invite code, and its Create Account button is a referral link that may earn us a commission at no extra cost to you. Whether an account can be opened is decided by the platform at sign-up.
Binance

One of the largest global exchanges by traded volume, with a very broad product range.
20% Trading Fee Rebate
Use invite code con888 when signing up to enjoy trading fee benefits.
Download from the exchange's official download service. Verify the source and follow the on-screen installation instructions.
Do not install an APK from an unknown source, or one that has been modified or cannot be checked.
OKX

A large global exchange offering spot, derivatives and a self-custody wallet.
20% Trading Fee Rebate
Enter invite code con888 when signing up to check available trading fee benefits.
Download from the exchange's official download service. Verify the source and follow the on-screen installation instructions.
Do not install an APK from an unknown source, or one that has been modified or cannot be checked.