The 90% of the bill you never saw
Picture an optimistic rollup like Arbitrum on a busy afternoon. It scoops up 500 swaps, executes them off-chain in a fraction of a second, and posts the result to Ethereum. In the last three guides you learned how a rollup borrows Ethereum's security — optimistic ones with fraud proofs, zk-rollups with validity proofs. But here is the question nobody asks until they read a gas breakdown: in one of those rollup transactions, *where does the money actually go?*
Before March 2024, the answer was startling: roughly 80–95% of the cost was a single line item — posting the batch's raw bytes to L1 as calldata. The off-chain computation was nearly free. The data was the entire bill. That flips the whole scaling story on its head. The bottleneck for a Layer 2 is not how fast it can compute; execution already moved off-chain. The bottleneck is how to get the data onto a secure base layer cheaply — and that is the data availability problem.
What "data availability" actually means
People conflate three different guarantees. Validity: was the computation correct? Availability: was the data behind it actually published, so anyone who wants it can download it? Storage: will it be kept forever? Data availability is only the middle one — the promise that the bytes were released, right now, for the whole world to grab. It says nothing about correctness (that's the proof's job) and nothing about permanence (that's archival).
Why does every rollup flavour need it? For an optimistic rollup, a verifier can only build a fraud proof if it can re-execute the batch — which means it needs the input data. For a zk-rollup, the validity proof already proves the state transition was correct — but a proof that your balance changed correctly is useless if you cannot see what the new state is. You need the data to know what you own, and to construct your own withdrawal if the operator vanishes. Validity without availability is a locked vault with a verified balance you can never reach.
Calldata vs blobs: what EIP-4844 changed
The old way was brutal. Rollups dumped their batch data into ordinary transaction calldata, which costs 16 gas per non-zero byte (4 gas per zero byte). Worse, that calldata competed in the same gas market as every swap, mint, and NFT trade on L1 — so when Ethereum was congested, rollup fees spiked in lockstep with it. The data was both expensive and held hostage to mainnet demand.
# Posting ~100 KB of rollup batch data to L1 # OLD WAY -- calldata (pre-EIP-4844) nbytes = 100_000 gas = nbytes * 16 # 16 gas / non-zero byte -> 1_600_000 gas eth_at_20gwei = 1_600_000 * 20e-9 # = 0.032 ETH (~$96 @ $3000) PER BATCH # NEW WAY -- one blob (EIP-4844) GAS_PER_BLOB = 131_072 # = 2**17 blob gas, carries 128 KiB blob_base_fee = 1 # wei, while blobs are below target cost_wei = GAS_PER_BLOB * blob_base_fee # = 131_072 wei ~= $0.0000004 # Same bytes. A separate fee market. Often a 10-100x drop, split across the batch.
EIP-4844, also called proto-danksharding, shipped in Ethereum's Dencun upgrade on 13 March 2024. It introduced a new transaction type that carries blobs (binary large objects) alongside the normal payload. Three properties make it transformative: each blob is 128 KiB; there is a separate EIP-1559-style fee market for blob gas, so blob space no longer competes with execution gas; and — crucially — the blob data is invisible to the EVM. A contract cannot read a blob's bytes; it sees only a small commitment to them.
# EIP-4844 blob-gas market -- entirely separate from execution gas
GAS_PER_BLOB = 2**17 # 131072 (one 128 KiB blob)
TARGET_BLOB_GAS_PER_BLOCK = 3 * 2**17 # 3 blobs (raised to 6 by Pectra / EIP-7691)
MAX_BLOB_GAS_PER_BLOCK = 6 * 2**17 # 6 blobs (raised to 9 by Pectra)
MIN_BLOB_BASE_FEE = 1 # wei
BLOB_BASE_FEE_UPDATE_FRACTION = 3338477
# excess_blob_gas accumulates when blocks run ABOVE target, drains when BELOW
def blob_base_fee(excess_blob_gas):
return MIN_BLOB_BASE_FEE * exp(excess_blob_gas / BLOB_BASE_FEE_UPDATE_FRACTION)
# -> the fee sits at the 1-wei floor until blobs are PERSISTENTLY full, then rises fastThe effect was immediate: when Dencun went live, rollup fees fell 10x or more overnight, with some L2 transactions dropping below a cent. But be honest about the limit — that cheapness holds only while blobs stay below target. The initial target was 3 blobs per block (max 6); later upgrades (Pectra, 2025) raised those to a target of 6 and a max of 9. Once blobs are consistently full, the blob base fee climbs, and L2 fees rise again. That pressure is exactly what full danksharding exists to relieve.
Why blobs are temporary — and the KZG trick
Here is the insight that makes blobs cheap. Data availability does not require permanent storage. The data only needs to be available long enough for anyone who cares to download it and either reconstruct the state or raise a challenge. After that window, the network can forget it. EIP-4844 keeps blobs for 4096 epochs (~18 days), then prunes them. Whoever actually wants the history — block explorers, the rollup itself, indexers — archives it off-protocol. You are renting ~18 days of availability, not buying forever-storage. That distinction is the whole reason blobs can be a different, cheaper resource than calldata.
So what does land on-chain forever? Not the blob — just a tiny KZG commitment to it (a 48-byte polynomial commitment), stored as a 32-byte versioned hash that the EVM can read via the BLOBHASH opcode. A point-evaluation precompile lets a contract verify that the committed polynomial evaluates to a claimed value at a chosen point — without ever seeing the blob. This is how a zk-rollup cheaply proves that the data it committed really matches its blob. And the same commitment machinery is what makes the next step — sampling — possible.
Full danksharding: sampling instead of downloading
Why is EIP-4844 only the proto version? Because it ships the blob format and fee market, but every node still downloads every blob. That is fine at 3–6 blobs, but you cannot ask a home staker on a domestic connection to pull tens of megabytes per block. Full danksharding removes that cap with one beautiful idea: nobody downloads everything, yet everyone is collectively sure the data is there.
The mechanism is data availability sampling (DAS) on top of erasure coding. The block proposer Reed–Solomon-codes the data so it is extended such that any 50% of the pieces can reconstruct the whole. Then each light node randomly requests a handful of small chunks. If you sample 30 random chunks and they all return and verify against the KZG commitments, the data is available with probability greater than 1 − 2⁻³⁰. To hide the data, an adversary would have to withhold more than half of it — which even a few random samples will almost certainly catch.
# A light node checks availability WITHOUT downloading the full blob set
commitments = download_commitments(block_header) # small: just the KZG commitments
NUM_SAMPLES = 30
for _ in range(NUM_SAMPLES):
(row, col) = random_coordinate() # pick a random chunk
chunk, proof = request_from_peers(row, col) # tiny download
assert verify_kzg(commitments[row], col, chunk, proof)
# All samples returned and verified ->
# data is available with probability > 1 - 2**(-NUM_SAMPLES)
# No single node ever held the whole blob -- the NETWORK guarantees availability.Danksharding aims for a target of around 64 blobs per block (~8 MB), with room to grow far beyond — but it is a multi-year path, not a single fork. The incremental rollout, PeerDAS, introduces peer-to-peer sampling as the stepping stone, with each node downloading only a subset of the data and sampling the rest. One clarification that trips people up: danksharding shards data, not execution — unlike the abandoned Eth2 execution-sharding plans, every transaction still runs on one chain; only the blob data is spread across the network.
Renting data elsewhere: modular DA layers
Step back and the picture is a stack of jobs: execution, settlement, consensus, and data availability. A monolithic chain does all four itself. The modular thesis says: split them into specialized layers, and let a rollup mix and match. DA is the layer most worth specializing, precisely because it is the bottleneck — so a market of dedicated DA layers has grown up to sell availability more cheaply than Ethereum blobs.
Celestia is a chain that does only consensus and data availability — no smart contracts, no execution. It erasure-codes every block, organizes data with namespaced Merkle trees so a rollup can fetch just its own slice, and lets light nodes perform DAS directly. A rollup posts its data to Celestia and only a tiny commitment to its settlement layer. EigenDA takes a different route: built on restaking via EigenLayer, it is an actively validated service where operators with restaked ETH attest to holding erasure-coded data. It is not its own consensus chain; its security is crypto-economic, backed by slashable restaked ETH.
The bottom line
Walk back through the rung and the shape is clear. Execution scaled by moving off-chain into rollups. Correctness scaled by compressing whole batches into a succinct proof or a challengeable state root. But the raw data scales linearly with usage and is the one thing you cannot compress away — every byte a rollup processes is a byte that must land on a secure, sampled, sufficiently decentralized DA layer. You can prove a computation in 200 bytes; you cannot prove a megabyte of inputs exists in fewer than the inputs themselves, you can only make checking them cheap.
That is why the whole L2 story — calldata → blobs → danksharding → modular DA — is, underneath, a data-availability story. Make data cheap, abundant, and verifiable-by-sampling, and the scalability trilemma finally starts to bend: you get throughput without forcing every node to download everything, and so without sacrificing the decentralization that made the chain worth using. The bottleneck was never the computer. It was always the data.