Soft vs Hard Finality on L2s: When Is a Transaction Really Done?
You send a transaction on Base or Arbitrum, and a second later your wallet says "confirmed." Job done — right? For showing a user that their swap went through, yes. For releasing $50,000 of inventory on the strength of that transaction, absolutely not. Those are two different questions, and the gap between them is where a lot of bridge hacks and accounting bugs live.
"Finality" on a Layer 2 isn't a single moment. A transaction passes through several stages of increasing certainty, and depending on the rollup type, the distance between "looks done" and "can never be reversed" ranges from a few minutes to seven days. This post walks the stages and shows how to tell, from RPC, which one a transaction has reached.
The stages, from soft to hard
1. Sequencer confirmation (soft). Almost every L2 today runs a single sequencer that orders transactions and hands you a receipt almost instantly. This is a promise: the sequencer says "I've accepted your transaction and I'll include it." It's fast and, in practice, very reliable — but it's a trust assumption. If the sequencer reorders, drops, or hasn't yet posted your transaction to L1, that "confirmation" can still change. (For how this ordering works, see What Is a Sequencer?.)
2. L2 block inclusion (soft). Your transaction lands in an L2 block. Better, but the block still only exists by the sequencer's word until its data reaches Ethereum.
3. Data posted to L1 (settling). The sequencer batches transactions and posts the data to Ethereum — as blobs since EIP-4844, or to an alternative data-availability layer. Once that batch is included and Ethereum itself finalizes it, the data is permanently available. For the chain's state, though, this is where optimistic and ZK rollups diverge sharply.
4. Hard finality (settled). The point past which the transaction cannot be reverted without breaking Ethereum's own guarantees. How you get there depends entirely on the proof system.
Where optimistic and ZK rollups part ways
| Optimistic rollups (Arbitrum, Base, Optimism) | ZK rollups (zkSync, Scroll, Linea, Polygon zkEVM) | |
|---|---|---|
| State validity is established by | Assuming it's valid unless challenged | A validity proof verified on L1 |
| Window before hard finality | ~7-day challenge period | As soon as the proof is verified (minutes to a few hours) |
| Trust-minimized L1 withdrawal | Wait the full challenge window | Wait for proof verification |
| Practical UX confidence | Seconds (sequencer) | Seconds (sequencer) |
The key asymmetry: an optimistic rollup posts a state root to L1 and assumes it's correct, leaving a ~7-day window for anyone to submit a fraud proof and revert it. That's why a trust-minimized withdrawal from Arbitrum or an OP-Stack chain takes about a week (third-party "fast bridges" front you the funds for a fee to skip the wait — but that's a trusted liquidity service, not finality). A ZK rollup instead posts a cryptographic validity proof; once Ethereum verifies it, the state is final with no challenge window — there's nothing to dispute. ZK rollups pay for this with proving cost and latency, but they reach hard finality far sooner.
Underneath all of it sits Ethereum's own finality — roughly two epochs, about 12.8 minutes. No L2 can settle harder or faster than the L1 it posts to. When you read about an L2 being "L1-finalized," that clock is part of the equation.
Checking finality from RPC
Post-Merge, Ethereum exposes block tags beyond latest, and most EVM L2s expose them too:
latest— the newest L2 block (sequencer-confirmed, soft)safe— a block unlikely to be reorgedfinalized— the strongest guarantee the chain will report
You can pull the finalized head with a normal eth_getBlockByNumber:
const finalized = await client.request({
method: "eth_getBlockByNumber",
params: ["finalized", false],
});
// compare finalized.number to your transaction's block number
https://rpc.swiftnodes.io/rpc/arbitrum?key=YOUR_API_KEY
One important caveat: the meaning of finalized is chain-specific on L2s. Some chains map it to "settled on L1," others to the L2's own internal notion of finality, and the lag behind latest varies a lot between an optimistic chain and a ZK chain. Don't assume finalized on an L2 means the same thing it means on Ethereum mainnet — check the specific chain's docs for how it defines the tag. The reliable, cross-chain mental model is still: has the L1 settlement actually happened for this transaction's batch?
What this means in practice
- Normal app UX (showing a confirmation, updating a balance): the sequencer's soft confirmation is fine. Sequencers reorg in practice approximately never, and waiting minutes to update a UI would feel broken.
- Bridging, cross-chain messaging, or moving real value off the rollup: wait for hard finality. On optimistic chains that's the challenge window for trustless transfers; on ZK chains it's proof verification. Treating a soft confirmation as settled here is exactly how cross-chain systems get drained.
- High-value settlement and accounting: key off the
finalizedtag (understanding its per-chain meaning) or track the batch's L1 settlement directly — don't count a transaction as irreversible until its data and state are anchored to Ethereum.
The short version: a soft confirmation answers "did my transaction probably go through?" and hard finality answers "can this ever be undone?" Most of the time you only need the first. The moments you need the second — bridges, large transfers, anything irreversible — are precisely the moments it's expensive to get wrong.
Whichever side of that line you're on, you need an endpoint that reliably serves the block tags. SwiftNodes runs flat-rate RPC across Arbitrum, Base, Optimism, and dozens of other chains — safe and finalized included. Grab a free key at swiftnodes.io and build your finality checks against it.
Related posts
- What Is a Sequencer? How L2 Transactions Get Ordered
On an Ethereum L2, a single component decides the order your transaction lands in and how fast it confirms: the sequencer. Here's what it actually does, why nearly every rollup runs a centralized one today, and what that means when you're reading L2 state over RPC.
- Mantle RPC: Endpoints, EigenDA, and What's Different
Mantle looks like a standard EVM L2 until two things trip you up: gas is paid in MNT, not ETH, and data availability runs through EigenDA instead of Ethereum calldata. Here's what that means for your RPC calls, plus the Mantle endpoints to point at.
- Full Node vs Archive Node: What's the Difference (and Which Do You Need)?
Most developers either overpay for an archive node they don't need or hit a wall on a full node that can't answer their query. The difference comes down to one thing — historical state — and here's the simple test for which one your app actually requires.