Key concepts
| Term | Definition |
|---|---|
| Flashblock | A 200ms sub-block containing a portion of the full block’s transactions |
| Preconfirmation | An ultra-fast signal that a transaction will be included, before the full block is sealed |
| Full Block | A series of 10 Flashblocks combined to form the complete 2-second block |
Architecture
Base operates a high-availability sequencer system:| Component | Role |
|---|---|
| base-consensus | Consensus layer (CL) — replaced op-node after Azul |
| base-reth-node | Execution layer (EL) — replaced op-geth after Azul |
| op-conductor | High-availability controller with Raft consensus for leader election |
| Component | Purpose | What it unlocks |
|---|---|---|
| rollup-boost | CL↔EL Engine API proxy | Shares Flashblocks with the EL without modifying the CL, providing a stable seam for future block-building evolutions (multi-builder, etc.) |
| base-builder | Out-of-protocol builder at 200ms cadence | Produces sub-second Flashblocks, decoupled from the EL, enabling pluggable builder mechanisms |
| websocket-proxy | Flashblocks stream fan-out | Broadcast layer so many consumers can read the stream without overwhelming the builder |
| base | RPC surface exposing preconfirmations | Converts streamed Flashblocks into familiar RPCs so apps and wallets can consume preconfirmation state |
Block Building
Are Flashblocks optional?
Are Flashblocks optional?
Is there any difference in transaction inclusion for Flashblocks vs. 2-second blocks?
Is there any difference in transaction inclusion for Flashblocks vs. 2-second blocks?
Can the sequencer stop publishing Flashblocks?
Can the sequencer stop publishing Flashblocks?
Why is my transaction having trouble getting included?
Why is my transaction having trouble getting included?
j can use up to j/10 of the total block gas limit—so in principle a very large transaction has a harder time landing in the first Flashblock. In practice this rarely matters: Base’s per-transaction gas maximum (16,777,216 gas, ~16.7M) is below Flashblock 1’s ~40M capacity, so any valid transaction fits in the first Flashblock by size alone. If a transaction is slow to include, the usual cause is a low priority fee relative to others competing in the same 200ms window.See Throughput and Limits for gas limits and throughput-related network parameters.How do I ensure my transaction is in the first Flashblock?
How do I ensure my transaction is in the first Flashblock?
Why do transactions sometimes appear out of order by fee?
Why do transactions sometimes appear out of order by fee?
- Transactions are ordered by fee at the time they’re selected for inclusion
- If a high-fee transaction arrives after a lower-fee transaction has already been committed to the current Flashblock, the high-fee transaction will appear after it (or in the next Flashblock)
- This is expected behavior, not a bug—the builder doesn’t “reorder” already-committed transactions
How frequently do Flashblock reorgs happen?
How frequently do Flashblock reorgs happen?
What does it mean when a Flashblock is reorged?
What does it mean when a Flashblock is reorged?
WebSocket
Can I connect directly to the Flashblocks WebSocket stream?
Can I connect directly to the Flashblocks WebSocket stream?
wss://mainnet.flashblocks.base.org/ws) is reserved for infrastructure-to-node data syncing. Applications should not connect to it directly.Instead, query your RPC node or node provider (e.g., QuickNode, Alchemy, Infura, dRPC) for Flashblocks data via:- RPC API: Standard JSON-RPC methods with the
pendingtag - WebSocket subscriptions: Use
eth_subscribevia your node provider’s WebSocket endpoint
Why are there 11 Flashblock indices (0-10)?
Why are there 11 Flashblock indices (0-10)?
Why are there sometimes fewer than 10 Flashblocks?
Why are there sometimes fewer than 10 Flashblocks?
Can the Flashblock index exceed 10? Is that a bug?
Can the Flashblock index exceed 10? Is that a bug?
- Sequencer delay: If the sequencer takes slightly longer than 2000ms to finalize and seal the full block, the Flashblock stream continues emitting incremental updates for the current block to keep the stream live.
- Timing drift: If the internal 200ms clock drifts or starts early relative to the L2 block’s canonical start time, an extra update can fit within the 2-second window.
- Do not hardcode
9or10as the final index — the last Flashblock for a given block is not predictable by index alone. - Watch the
payloadIdinstead. The most reliable signal that a block has finished is whenpayloadIdchanges, or when the full block is confirmed via standard RPC. All Flashblocks sharing the samepayloadIdbelong to the same block, regardless of how high the index goes. - Once the sequencer advances to the next block,
payloadIdresets andindexreturns to0.
What encoding format is the transaction data in?
What encoding format is the transaction data in?
diff.transactions array is Recursive Length Prefix (RLP) encoded.Why am I getting rate limited on the WebSocket?
Why am I getting rate limited on the WebSocket?
- Running your own Flashblocks-aware RPC node
- Using a third-party node provider with Flashblocks support
RPC
Why am I getting rate limited using mainnet.base.org?
Why am I getting rate limited using mainnet.base.org?
- Use a third-party node provider with Flashblocks support (Alchemy, Infura, QuickNode, dRPC)
- Run your own Flashblocks-aware RPC node
Why does eth_call 'pending' report a block number several blocks behind tip?
Why does eth_call 'pending' report a block number several blocks behind tip?
eth_call "pending" is called, it operates on top of that historical base, so the block number visible in the call context (e.g. block.number) may appear to be N-5.When eth_call "pending" executes, the entire block context — block.number, block.timestamp, block.basefee, and all other block properties — corresponds to that historical base block (potentially N-5), not the current chain tip. The call result is correct in that it reflects all received Flashblocks state applied on top, but contracts that rely on block context properties should be aware that those values may be several blocks behind.If you operate a node in a geographic region where your P2P latency is not significantly higher than the WebSocket stream latency, you can reduce this difference by lowering the MAX_PENDING_BLOCKS_DEPTH configuration value. This controls the maximum number of historical blocks worth of Flashblocks your node stores, so a lower value will make the block context closer to tip at the cost of reduced tolerance for P2P latency spikes.What RPC methods support Flashblocks?
What RPC methods support Flashblocks?
| Method | Usage |
|---|---|
eth_getBlockByNumber | Use pending tag |
eth_getBalance | Use pending tag |
eth_getTransactionReceipt | Returns preconfirmed receipts |
eth_getTransactionByHash | Use pending tag |
eth_getTransactionCount | Use pending tag |
eth_call | Use pending tag |
eth_simulateV1 | Use pending tag |
eth_estimateGas | Use pending tag |
eth_getLogs | Use pending for toBlock |
eth_subscribe | Stream Flashblock data in real-time |
base_transactionStatus | Check if transaction is in mempool (Beta) |
Node Setup
How do I set up a Flashblocks-aware RPC node?
How do I set up a Flashblocks-aware RPC node?
Further reading
- Enable Flashblocks — run your own Flashblocks-aware RPC node
- Flashblocks API Reference — RPC methods, WebSocket subscriptions, and infrastructure stream schema
- Flashblocks Deep Dive — engineering blog post with implementation details, built in collaboration with Flashbots