Data Availability
How batch data gets onto L1 — channels, frames, calldata vs. blobs, and the derivation pipeline that reads it back.
Third-party documentation. This is independently authored analysis of the public Optimism (OP Stack) codebase — not the official docs, and not reviewed or endorsed by the Optimism (OP Stack) team.
Data Availability
An optimistic rollup's security rests on a single guarantee: the data needed to reconstruct the L2 state is available on L1. Anyone must be able to replay the chain from L1 data alone, or the "optimistic" trust assumption breaks. This module is about how the OP Stack turns L2 blocks into L1 data, and how that data is read back.
The chain of custody: blocks → batches → channels → frames → L1 txs
- Blocks are produced by the sequencer (see the Sequencing module).
- op-batcher groups blocks into batches — one batch is a set of compressed L2 blocks sharing the same L1 origin and sequencing window.
- Batches are written into channels, a compressed byte stream with a maximum lifetime (measured in L1 blocks) and a maximum size. When a channel is full, or its time is up, it is closed.
- A closed channel is split into fixed-size frames. Frames are individually small and are included in L1 transactions to the batch inbox. This framing makes large channels robust: frames can be spread across multiple L1 blocks and even re-ordered, and the receiver reassembles them by channel ID + frame number.
Calldata vs. blobs
How frames physically reach L1 has changed with the stack's history:
- Pre-Ecotone: frames ride in the calldata of L1 transactions. Calldata is permanently stored by Ethereum and readable forever, but it is expensive and bloats the L1 chain state.
- Post-Ecotone (current): frames ride in EIP-4844 blobs. Blobs are far cheaper per byte than calldata, but are only retained by Ethereum nodes for ~18 days. The OP Stack treats this as a grace period: blobs exist so anyone can reconstruct and dispute during the challenge window; beyond the retention period, archive nodes and the canonical chain data are the long-term record.
- Both are published to the same batch inbox; op-node's derivation reads whichever data form the batch transaction uses.
Costs and compression
Data availability is the largest ongoing cost of an optimistic rollup. The stack attacks it with:
- zlib compression of channel contents — transaction payloads compress well, typically cutting DA cost several-fold.
- Span batches — a batch format that deduplicates common transaction fields (nonce, gas price, sender) across blocks in a batch instead of repeating them per transaction.
- Blob submissions — the dominant saving on modern deployments (roughly an order of magnitude cheaper than calldata).
- Pass-through pricing — the L1 data fee each L2 user pays reflects exactly these costs, so chain growth is funded by the transactions that cause it.
The derivation side: reading data back
op-node's pipeline reverses the encoding: it scans L1 blocks for batch-inbox transactions, collects frames, reassembles channels by ID, decompresses, and extracts batches. Only then does it feed block attributes to op-geth. Two details matter for builders:
- The sequencing window — a batch is only valid if its L1 origin is within a fixed window of the batch's target L2 block; this bounds how long a chain can "survive" on stale L1 data.
- Reorgs — if L1 reorgs, frames vanish from the canonical L1 chain and the derived L2 chain follows the new L1 truth.
Edge cases
- A channel that stays open past its max lifetime is force-closed by the batcher; frames from a closed channel that arrive late are ignored.
- If a frame is lost (e.g. a failed L1 tx), the batcher re-sends it in a later transaction; receivers are tolerant of gaps as long as frames arrive within the channel lifetime.
- After blob expiry (~18 days) the L1 blob-bearing transaction itself still exists and records the blob commitment, so proof of publication persists even when the data is pruned — but nodes that need to re-derive the chain must retain blobs or use an archive provider.
