The Mempool & Propagation
By now we have a fully-formed transaction. Anatomy of a Transaction gave it its fields, Signing & Replay Protection made it self-authorizing, and Transaction Types wrapped it in a typed envelope carrying its fee parameters. The bytes are signed and valid. But signing a transaction does not change the world — recall from the part overview that state only moves when a transaction is included in a block and executed. Between those two moments the transaction has to live somewhere.
That somewhere is the mempool. This page is about the gap between “broadcast” and “included”: how a transaction spreads across a network of strangers who don’t have to accept it, how each of those strangers keeps its own private waiting room of pending transactions, and how a block builder eventually reaches into that room and orders what it finds. This is the most adversarial stop on the journey — it is where fee markets clear, where transactions get replaced and evicted, and where MEV is born.
There is no global mempool
Section titled “There is no global mempool”The single most important idea on this page, and the one most beginners get wrong: there is no such thing as the mempool. There is no shared server, no canonical list, no consensus over pending transactions. What exists is one mempool per node — an in-memory set of valid, not-yet-included transactions that that particular node has heard about and chosen to keep.
A mempool is local state. It is not part of the world state. It has no stateRoot, it is never agreed upon, and two honest nodes running the same client can — and constantly do — hold different sets of pending transactions at the same instant. When people say “the mempool,” they mean, loosely, “the union of what most nodes are currently holding” — a useful fiction, but a fiction.
node A's mempool node B's mempool node C's mempool ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ tx1 tx2 tx3 │ │ tx1 tx3 │ │ tx1 tx2 │ │ tx4 tx5 │ │ tx4 tx5 tx6 │ │ tx5 tx7 │ └───────────────┘ └───────────────┘ └───────────────┘ (heard tx2,3) (heard tx6, not 2) (heard tx7, not 3,4,6)
No node has the full picture. Each holds a *sample* of the pending set, shaped by who its peers are and what its local acceptance rules allow.Why build it this way? Because the alternative — a single authoritative pending list — would be a central point of control and failure, exactly the thing a network of untrusting strangers is designed to avoid. If everyone had to agree on the pending set before ordering it, you would need a second consensus protocol running ahead of the real one. Instead, the mempool is deliberately best-effort and disposable: nodes share what they know, keep what they find useful, and the only thing that ever becomes canonical is a block.
Propagation: transactions gossip
Section titled “Propagation: transactions gossip”A transaction reaches the network the same way rumors reach a crowd — by gossip. When you broadcast a transaction, your wallet hands it to one node (an RPC provider, or your own). That node does not forward it to “the network.” It has no line to the network. It forwards it to its handful of directly-connected peers, each of whom validates it, decides whether to keep it, and forwards it to their peers. In a few hops the transaction has flooded most of the network.
you ─► node ─► peer ─► peer ─► peer ... │ │ └─► peer │ └─► peer └─► peer ─► peer
Each hop: the receiver re-validates the tx cheaply, adds it to its own mempool if it passes local rules, then re-announces it to *its* peers.Two details make this efficient and safe:
- Announce, then fetch. On Ethereum’s transaction-gossip protocol, a node usually first sends its peers only the transaction hashes it has, not the full bodies. A peer that hasn’t seen a hash asks for the body; a peer that already has it stays quiet. This stops the same 200-byte transaction from being pushed to a node that already holds it — bandwidth is the scarce resource in a flood network.
- Validate before relay. No node relays what it wouldn’t accept. Before a transaction enters a mempool and gets re-announced, the node checks it cheaply: is the signature valid and does it recover to a real account? Is the nonce sane? Can the sender afford the maximum fee plus value at their current balance? Is the fee at least the node’s minimum? A transaction that fails is dropped on the spot and never propagates. This is why spam doesn’t travel: the first honest node it reaches refuses to carry it.
Because propagation is a flood over an irregular graph, it is neither instant nor uniform. A transaction announced in New York reaches a validator in Singapore a fraction of a second later than one announced next door. That asymmetry — who sees what, when — is not a bug you can engineer away; it is the raw material that MEV searchers and block builders compete over.
Ordering: how a proposer picks from its pool
Section titled “Ordering: how a proposer picks from its pool”A validator proposing a block does not include its whole mempool — a block has a finite gas limit. It must choose an ordered subset. The default rule, implemented by every execution client, is straightforward and follows directly from the fee mechanics of typed transactions:
- Maximize revenue per gas. Order candidate transactions by the effective priority fee (the “tip”) they pay the proposer per unit of gas. Under EIP-1559, the base fee is burned and does not go to the proposer, so the proposer’s income from a transaction is
min(maxPriorityFeePerGas, maxFeePerGas − baseFee) × gasUsed. Higher tip per gas ⇒ picked sooner. (The base-fee and tip machinery gets its full treatment in Gas & Fees; here we only need “the proposer sorts by the tip it keeps.”) - Respect per-sender nonce order. This constraint overrides raw fee sorting within a single account. Recall from the overview that an account’s transactions must apply in strict ascending nonce order. So even if Alice’s nonce-8 transaction pays a huge tip, it cannot be included before her nonce-7 transaction — nonce 7 must come first or nonce 8 is not even valid yet. The proposer sorts accounts by the tip of their next executable transaction, but within an account it always follows the nonce sequence.
Alice: nonce 7 (tip 2 gwei) ─► nonce 8 (tip 50 gwei) must go 7 then 8 Bob: nonce 3 (tip 30 gwei)
Proposer's greedy pick (by tip of the *next executable* tx): Bob#3 (30) ─► Alice#7 (2) ─► Alice#8 (50) ▲ Alice#8's 50-gwei tip cannot jump ahead of #7, because #8 is invalid until #7 bumps her nonce.This nonce constraint is why ethmini’s state-transition function checks sender.nonce == tx.nonce before doing anything: a transaction is only executable when the account is at exactly its nonce.
// From ethmini's WorldState::apply — validation before any state moves.// A transaction whose nonce is ahead of the account's current nonce is// not yet executable; it must wait for its predecessors. This is the// on-chain rule that the mempool's pending/queued split mirrors off-chain.if sender.nonce != tx.nonce { return Err(EthError::NonceMismatch { addr: tx.from, expected: sender.nonce, got: tx.nonce, });}Pending vs. queued
Section titled “Pending vs. queued”Because of the nonce rule, a mempool actually keeps two buckets, and clients expose both (you can see them via the txpool_status / txpool_content RPC methods):
- Pending — transactions that are executable right now: their nonce is exactly the account’s current nonce, or it follows an unbroken chain of earlier pending transactions from the same account. These are eligible for the next block.
- Queued — transactions with a future nonce and a gap in front of them. If Alice’s account is at nonce 7 and she broadcasts nonce 9 (but not 8), that nonce-9 transaction is queued: it cannot execute until nonce 8 arrives and fills the gap. It sits, valid but stranded, waiting for its predecessor.
Alice's account nonce = 7
broadcast: #7 #9 (#8 is missing) │ │ ▼ ▼ PENDING QUEUED ── waits until #8 shows up, then #9 promotes (next (future to PENDING and both can be included. block) nonce, gap)This split is the mempool’s local mirror of the very nonce rule the state-transition function enforces. The chain will only apply nonces in order, so the mempool sorts transactions into “could go now” and “blocked on a predecessor.”
Replacement and eviction
Section titled “Replacement and eviction”A mempool is finite memory, and transactions do not always get included promptly. Two mechanisms keep it healthy: how a sender replaces a transaction, and how a node evicts transactions it can no longer justify holding.
Fee-bump replacement (same nonce, higher fee)
Section titled “Fee-bump replacement (same nonce, higher fee)”Suppose you broadcast a transaction with a fee that turns out to be too low — the base fee rose, or the network got busy — and it is now stuck, sitting in mempools without being included. You are not out of luck, but you also cannot just “send it again,” because a second transaction with the same nonce is either a duplicate (identical) or a conflict (different).
The escape hatch is replacement: broadcast a new transaction with the same nonce but a higher fee. Nodes treat this as an instruction to swap out the old one. To prevent replacement spam (an attacker cheaply churning the pool), clients require the replacement to bid meaningfully more — typically at least ~10% higher on both the max fee and the priority fee. A replacement that clears that bar evicts the old transaction from the pool and takes its place; one that doesn’t is rejected as an underpriced duplicate.
Two common uses of the same mechanism:
- Speed-up — same nonce, same intent, higher fee, to overtake congestion.
- Cancel — same nonce, higher fee, but sending 0 ETH to yourself with no data. It occupies the nonce with a do-nothing transaction, so the original never gets a chance to execute. There is no true “cancel” on Ethereum; you can only replace with something harmless.
original: nonce 12, tip 1 gwei ── stuck in the pool replacement: nonce 12, tip 2 gwei ── ≥10% higher on both fees │ ▼ node swaps the entry: only ONE tx per (sender, nonce) survives. Whichever is eventually mined consumes nonce 12; the other is dropped.Eviction: dropping transactions the pool won’t keep
Section titled “Eviction: dropping transactions the pool won’t keep”A node’s mempool has hard caps — a maximum number of transactions, and a maximum count per sender. When it fills up, or when circumstances make a transaction unlikely ever to be included, the node evicts:
- Lowest-fee-first when full. If the pool is at capacity and a new, higher-paying transaction arrives, the node drops the cheapest one it holds to make room. Your under-tipped transaction is not stored forever; a busier network can quietly discard it.
- Now-invalid transactions. If a transaction’s sender no longer has the balance to cover it (an earlier transaction drained the account), or its nonce has already been consumed by a mined block, it is invalid and removed.
- Stale / timed-out transactions. Many clients evict transactions that have lingered beyond a configured lifetime (hours), on the assumption they’re either abandoned or hopelessly underpriced.
The consequence for you as a sender: a broadcast transaction can silently vanish. Nothing on-chain records that it was dropped, because it never touched the chain. This is precisely why the next page insists that submitted is not confirmed — the mempool is a waiting room with no memory and no obligation to keep your seat.
MEV and private mempools
Section titled “MEV and private mempools”Now put two facts together. First: proposers are free to order the transactions in a block however they choose — the protocol only requires per-sender nonce order, not fair sequencing across senders. Second: the public mempool broadcasts everyone’s pending intentions to the whole network before they execute. Combine them and you get MEV — Maximal (originally “Miner”) Extractable Value: the profit a block proposer, or a searcher paying the proposer, can extract purely by choosing what to include and in what order.
Because pending transactions are visible before they run, an observer can see, for example, a large DEX swap sitting in the pool and insert their own transactions before and after it — buying the asset first (pushing the price up), letting the victim’s swap execute at the worse price, then selling (a sandwich). Or they can copy a profitable pending transaction and pay a higher tip to have theirs mined instead (frontrunning). None of this breaks a single consensus rule. It is a direct consequence of a transparent, freely-orderable pending set.
The market’s response was private mempools (also called private order flow or private RPC). Instead of broadcasting to the public gossip network, a sender submits the transaction directly to a builder or a relay, where it stays hidden from the public pool until it is already placed in a block. The transaction skips the adversarial waiting room entirely.
PUBLIC path: PRIVATE path: wallet ─► node ─► gossip ─► everyone wallet ─► private relay ─► builder sees it pending (hidden until it's in a (MEV bait) block; no public gossip)Private mempools protect users from sandwiching, but they come at a cost to the network’s openness: order flow that used to be visible to all proposers now flows to a few privileged builders, which concentrates power and complicates censorship-resistance. Ethereum’s answer to that — proposer/builder separation and its consequences — belongs to consensus, not here. For this page, the takeaway is the causal chain: public pending set + free ordering ⇒ MEV ⇒ private mempools.
The architect’s lens
Section titled “The architect’s lens”- Why does it exist? Because a transaction is signed off-chain but can only take effect on-chain, and the two events are separated in time. The mempool is the buffer that holds valid-but-not-yet-included transactions so that block proposers have a supply to build blocks from, and senders don’t have to be online at the exact moment their transaction is mined.
- What problem does it solve? It decouples submission from inclusion. Without it, a transaction would have to reach a proposer in the exact instant they build a block or be lost. The mempool + gossip flood means “broadcast once, and any future proposer can find it.”
- What are the trade-offs? Openness costs privacy: a public pending set lets anyone see and react to your intent before it executes, which is the root of MEV. Per-node locality costs certainty: there is no global truth about pending transactions, so “is my transaction in the mempool?” has no single answer.
- When should I avoid it? When front-running would hurt you — large swaps, liquidations, arbitrage. Then you route through a private mempool or relay to skip the public pool, accepting more trust in a builder in exchange for hiding your intent until it’s already ordered.
- What breaks if I remove it? Senders and proposers would have to rendezvous in real time; a transaction not received in the exact block-building instant would simply never execute. You’d lose fee markets (nowhere for bids to accumulate and compete), replacement (nothing to replace), and any tolerance for the sender being offline. The network would still reach consensus on blocks — but getting a transaction into one would become fragile and timing-dependent.
Check your understanding
Section titled “Check your understanding”- Why is it wrong to speak of “the mempool” as a single shared list? What is a mempool, concretely, and what does it imply about two honest nodes at the same instant?
- Describe how a transaction propagates from your wallet to most of the network. What does “announce, then fetch” save, and why does an invalid transaction fail to spread?
- A proposer sorts transactions by the tip it earns per gas — yet Alice’s high-tip nonce-8 transaction cannot be included before her low-tip nonce-7 transaction. Reconcile these two rules.
- Explain the pending/queued distinction. If an account is at nonce 5 and broadcasts nonce 7 (but not 6), which bucket does nonce 7 land in, and what has to happen for it to become includable?
- Your transaction is stuck with too low a fee. What two mechanisms are relevant — one you initiate, one the node may do on its own — and how does fee-bump replacement differ from simply broadcasting the transaction again?
Show answers
- There is no shared or canonical pending list — a mempool is per-node local state: an in-memory set of valid, not-yet-included transactions that that node has heard about and chosen to keep. It has no
stateRoot, is never agreed upon, and is not part of the world state. The implication: two honest nodes running the same client routinely hold different pending sets at the same instant, because each has heard a different sample of the flood. - Your wallet hands the transaction to one node; that node validates it cheaply, adds it to its own mempool, and re-announces it to its directly-connected peers, who repeat the process — a gossip flood that reaches most of the network in a few hops. Announce-then-fetch sends only 32-byte hashes first, so a peer that already has a transaction never receives its full body again, saving bandwidth (the scarce resource in a flood). An invalid transaction fails to spread because every honest node validates before relaying: the first node it reaches refuses to accept or re-announce it, so it dies on the spot.
- The tip-sorting rule orders across accounts — the proposer ranks each account by the tip of that account’s next executable transaction. The nonce rule constrains ordering within a single account: transactions must apply in strict ascending nonce order, because a transaction is only valid when the account is at exactly its nonce. Alice’s nonce-8 transaction is not executable until nonce 7 has run and bumped her nonce, so no matter how large its tip, it cannot jump ahead of nonce 7.
- Pending = executable now: the transaction’s nonce equals the account’s current nonce, or follows an unbroken chain of earlier pending transactions from that account. Queued = a future nonce with a gap in front of it. Nonce 7, with the account at nonce 5 and nonce 6 missing, lands in queued — it is valid but stranded. It becomes includable only when nonce 6 arrives and fills the gap, after which 6 (and then 7) promote to pending.
- The two mechanisms are fee-bump replacement (you initiate) and eviction (the node may do it). Replacement means broadcasting a new transaction with the same nonce but a higher fee (typically ≥~10% higher on both max and priority fee); nodes swap it in for the old one, and only one transaction per
(sender, nonce)survives. This differs from “broadcasting again”: an identical resend is just a duplicate and changes nothing, and there is no separate “resend at a higher fee” other than replacement — you must reuse the nonce and out-bid, or the node rejects it as an underpriced duplicate. (Eviction is the node dropping your low-fee or stale transaction on its own when the pool is full or it goes invalid — which is why a broadcast transaction can silently vanish.)