All articles
InfrastructureOctober 7, 202611 min read

Does TON Have a Mempool? What You Can See Before a Block

Does TON have a mempool? Not a single global pool like Bitcoin. What a node sees before a block, why pending on toncenter is an emulation, and what a mempool stream can and cannot show.

TNTONNodeOctober 7, 2026

Ask "does TON have a mempool?" in a developer chat and you get two confident answers. One: "No, TON has no mempool." The other: "Yes, here is a pending transaction from toncenter." Both are right about something. TON has no single, network-wide pool of unconfirmed transactions that every node holds and agrees on, the way Bitcoin does. But a message does exist before it lands in a block, nodes do see it, and a few APIs let you look into that window.

This post explains what the word means on TON, why "pending" on toncenter is an emulation, what a stream of pre-block messages can and cannot tell you, and how TONNode's mempool stream works, limitations first.

What "mempool" means on TON

On Bitcoin or Ethereum the mempool is a concrete thing: every full node keeps a set of unconfirmed transactions, gossips it to its peers, and block producers pick from it, usually by fee.

TON starts from a different unit. A user never sends a "transaction". A wallet app signs an external message and hands it to a node. In the words of docs.ton.org, "external messages are sent from outside the blockchain, and as such only have an optional external sender address." The receiving contract, which for a user is the wallet contract, checks the signature and the sequence number, calls ACCEPT, and only then does a transaction come into being: "when an incoming external message is processed, a transaction is created only if the contract accepts the message."

Three consequences follow, and they are why "the TON mempool" is a loose phrase rather than a protocol object.

  • There is nothing to bid with. An external message carries no payment from its sender. The destination contract pays for the gas after it accepts, drawing on a gas credit that lets it inspect the message first. No queue is ordered by price, because there is no price on the message.
  • There is no single queue. TON is sharded: an account belongs to the shardchain whose prefix its address starts with, and a message addressed to a wallet only matters to the nodes producing that shard's blocks. A node that receives an external message broadcasts it in the public overlay, and the docs note that "validators share them with each other, and might accidentally (or intentionally) deliver it several times." Each node holds what it has heard; there is no agreed set anywhere.
  • A rejected message leaves no trace. If the contract does not accept, because the signature is wrong, the seqno was already used, valid_until has passed or there is no balance to pay with, no transaction is created and no block records the attempt.

So when someone says "TON mempool", the honest expansion is: the external messages some node has received and broadcast, which no block has included yet. It is a window of a few seconds, it looks different from every node, and a share of what is in it will never execute. That window is what a mempool stream shows you.

Why "pending" on toncenter is an emulation

Toncenter's v3 API has GET /api/v3/pendingTransactions, filtered by account or by trace id. Its Streaming API delivers events with a finality field that is pending, confirmed or finalized, and defines the first level precisely: "pending — result of emulation or speculative execution. This state can be invalidated."

A pending transaction on toncenter is not fished out of a node's queue. The indexer takes the external message, runs it against the current account state the way a validator would, and publishes the predicted transaction and the actions it would produce. When the real block arrives, the event is emitted again as confirmed, later as finalized; when the prediction turns out wrong, a trace_invalidated notification follows. Subscriptions are per address: the WebSocket subscribe operation takes an addresses list that "may be left empty when subscribing only to a trace, otherwise required for non-trace event types".

This is excellent for the question most products ask: did my user's payment go through, and can I show it a second earlier? What it does not give you is the raw pre-block flow of the network, every message from every wallet, before anything has been emulated. Those are two different products.

What a TON mempool stream can and cannot show

A mempool stream is the other product: a node that forwards external messages the moment it hears them. Before building on one, the limits matter more than the features. These are taken from the data quality section of the mempool docs.

Coverage is partial. The stream carries what one node receives from the public overlay. A message that never reaches that node is not in the stream, and absence from the stream proves nothing. TONNode publishes no completeness or speed figures and does not claim to be first.

Pending does not mean included. A checked message passed the node's broadcast checks, not the validator's execution. In one 90-minute sample in October 2026, roughly one in five checked messages was never accepted on chain.

Early messages are unverified. The node's earliest hook runs before its broadcast signature check, where any overlay peer can inject bytes. The stream delivers those as "path":"early","unverified":true, by default, because for some uses the head start matters more than certainty. Anything that acts automatically either sends "include_unverified":false or waits for the checked copy with the same cell_hash.

parsed is best effort. The decoded wallet body (v4r2, v5r1, highload_v3, a jetton transfer, a DEX swap) is inferred from the message bytes alone, and a contract that imitates a wallet layout can be labelled wrongly.

Duplicates happen. The same cell_hash can arrive as early and then as checked, again after a reconnect, and rarely after the de-duplication window. Handling has to be idempotent by cell_hash.

Some messages are dropped on purpose: BoCs over 65,535 bytes, BoCs that are not external messages, and destinations that are not plain addr_std.

If any one of these breaks your use case, you want confirmed transactions, not a mempool. Detecting an incoming USDT payment is the canonical example: a payment is a transaction in a block, and nothing before that should mark an order as paid.

How TONNode's mempool stream works

TONNode's stream is one WebSocket, wss://mempool.tonnode.io/v1/stream. A server authenticates with Authorization: Bearer tnmp_…; a browser cannot set headers, so a backend that holds the key asks POST /v1/ticket for a one-time 30-second ticket and passes the returned subprotocols to new WebSocket(url, subprotocols). The first message on every connection is hello, copied here from the docs:

JSON
{"v":1,"type":"hello","contract":"1.1","epoch":"9f3c1a7be2d04c11","head_seq":123456,"oldest_seq":118020,
 "ts_gw_us":1791322891600000,"key_id":"0123456789ab",
 "limits":{"max_conn":3,"max_filters":null,"delay_ms":0,"replay_limit":null}}

Filters are optional and OR-ed: dest (the sending wallet), out_dest (where the wallet is sending to), op (an op code, such as 0x0f8a7ea5 for jetton transfers) and pool (a DeDust pool). "filters":{} is the whole stream; a subscription holds up to 10,000 entries, and a later subscribe replaces the filters without replay. A subscription using all four filter kinds and opting out of early messages:

JSON
{"v":1,"type":"subscribe",
 "filters":{"dest":["0:2a18ac1734f34579e6a6c2a9e738bb5799d21e7a73ef106895c00c34549a9167"],
            "out_dest":["EQB3ncyBUTjZUA5EnFKR5_EnOMI9V1tTEAAPaiU71gc4TiUt"],
            "op":["0x0f8a7ea5"],
            "pool":["0:a0d1bc3a139cbc6b39a3e3633f74476be441343f9d0fd88b949fca0327b65a75"]},
 "include_unverified":false}

The server confirms with the number of distinct entries in effect and where delivery starts:

JSON
{"v":1,"type":"subscribed","filters":4,"include_unverified":false,"from_seq":123451}

From there one JSON object per message arrives in seq order: the raw boc, its hashes (cell_hash, the TEP-467 norm_hash, sha256), the destination wallet, path and unverified, two timestamps and, when the body layout is recognised, parsed with the wallet type, seqno, valid_until and the outgoing transfers and swaps.

Replay. The server holds the last ~60 seconds of events, at most 64 MiB. After a disconnect, reconnect, send resume with the epoch and the last seq you handled, and receive what you missed through your new filters. A gap event says what was skipped and why: slow, source_reconnect or ring.

Plans. Nothing is metered except simultaneous connections on one key: Test, 7 days, 1 connection, $5; Start, 30 days, 1 connection, $15; Pro, 30 days, 3 connections, $30; Business, 30 days, 10 connections, $100; more on request. No message quota, no added delay, no free tier. A key is bought in the console from the same balance as node plans; the full table is on the pricing page.

What is not in it. Messages sent through TONNode's own liteservers are not echoed to mempool subscribers. If you send through a TONNode node key, those transactions do not appear in this stream; to watch a wallet you control, send through another route or read your own sends from the chain.

Complete consumers in Node.js, Python and Go and the error codes are in the mempool stream docs.

TonAPI streaming and toncenter streaming, compared honestly

Three services touch the pre-block window, and they are not interchangeable. TonAPI's Streaming API offered GET /v2/sse/mempool and a WebSocket subscribe_mempool method with optional account filtering; its own documentation now opens with "Streaming API is deprecated — please use Webhooks API for real-time updates." Toncenter's Streaming API, at wss://toncenter.com/api/streaming/v2/ws, delivers transactions, actions, traces and state changes with a finality level; pending events are emulated and may be invalidated, and subscriptions require addresses for everything except traces.

TonAPI streaming Toncenter streaming TONNode mempool stream
Status per its own docs deprecated; webhooks suggested current current
What "pending" is a mempool message an emulated transaction or action; can be invalidated a raw external message; not executed
Scope mempool feed, account filter optional addresses required, except for traces whole stream, or filters up to 10,000 entries
Finality n/a for the mempool feed pending, confirmed, finalized none; confirm on chain
Replay after a drop not documented not documented last ~60 s with resume

None of the three publishes a number that lets you compare coverage. Measure on your own traffic before you decide.

Who needs a mempool stream, and who does not

You probably need it if:

  • you run a DEX or trading bot, and the seconds between a swap being broadcast and being executed are your edge, with include_unverified:false or a confirmation step before anything moves;
  • you watch a set of wallets or a pool and want to see a transfer or swap the moment it is broadcast, not when the block lands;
  • you study the network: message rates, wallet versions, busy DEX routers, how many messages never execute.

You do not need it if:

  • you detect payments. A payment is a transaction in a block; read it with get_transactions and never mark an order paid from a pending message;
  • you show balances or history. The mempool has no state; use the LiteServers chapter and transaction history by lt and hash;
  • you need every message, or your own sends through TONNode liteservers. Coverage is partial by the nature of the overlay, and your own sends are not in the stream by design.

For the trading case, building a TON trading agent covers the read, quote and swap loop a mempool feed would sit in front of.

FAQ

Does TON have a mempool?

Not a single global one. TON has no network-wide pool of unconfirmed transactions that every node holds and agrees on. What exists is the set of external messages a given node has received from the public overlay and not yet seen in a block; it differs from node to node, lasts a few seconds, and includes messages that will never execute.

Can I see pending TON transactions?

Yes, in two senses. Toncenter shows pending transactions and actions produced by emulating an external message against current state, per address, and may later invalidate them. A mempool stream such as TONNode's shows the raw external messages themselves, as a node hears them, before any execution. Neither is a confirmed transaction; only a block is.

Why is a pending message not in a block?

Because a transaction is created only if the receiving contract accepts the message. A wallet rejects a bad signature, a used seqno, an expired valid_until or a message it cannot pay for, and a rejected message leaves no trace on chain. A message can also be lost before it reaches the nodes producing that shard's blocks. In one 90-minute sample in October 2026, roughly one in five checked messages was never accepted.

Is the TON mempool stream complete?

No, and no stream can be. TONNode's stream carries what one node receives from the public overlay; a message that never reaches it is not in the stream. TONNode publishes no completeness or speed figures. Absence from the stream is never proof that something did not happen.

What does "unverified" mean in the stream?

An early message, written before the node's broadcast signature check, at a point where any overlay peer can inject bytes, so it may be garbage or a forgery. Early messages are delivered by default; a subscription with "include_unverified": false receives only checked messages, which passed the node's broadcast checks but have not been executed by a validator.

How much does the TONNode mempool stream cost?

Plans are priced by simultaneous connections on one key: Test is 7 days with 1 connection for $5, Start is 30 days with 1 connection for $15, Pro is 30 days with 3 connections for $30, and Business is 30 days with 10 connections for $100. There is no message quota, no added delay and no free tier.

Before you connect

Read the data quality section once more, decide whether you need early messages at all, make your handling idempotent by cell_hash, and confirm on chain before money moves. If that fits, a Test key is $5 for 7 days on the pricing page. If not, private liteserver access that reads confirmed state is the tool most products actually need.

Build on TON without rebuilding the infrastructure layer.

Choose MCP, private node access, or a straightforward API — each product works independently.