Skip to main content
A reorg — short for chain reorganization — happens when a blockchain discards blocks it had already produced and replaces them with a different, competing sequence. Every transaction in the discarded blocks is un-included. Some of them get re-included in the new blocks, often at a different position; some never make it back at all. Reorgs are normal. They are how a decentralized network resolves the case where two validators produce a block at nearly the same moment and part of the network sees each one first. The network converges on one branch, and the other is dropped.

What a reorg looks like

Two validators propose a block at height 100. Half the network builds on block A, half on block B.
When the network converges on the B branch, block 100A and everything in it never happened as far as the chain is concerned. If you read block 100A and stored its transactions, your copy of history is now wrong. Depth is how many blocks got replaced. The overwhelming majority of reorgs are one or two blocks deep and resolve in seconds. Deeper reorgs are rare and usually indicate a real problem: a client bug, a network partition, or an attack. Frequency varies enormously by chain. Chains with sub-second blocks and probabilistic finality reorg many times a day; BFT chains with deterministic finality never reorg at all, because a block is committed by a validator supermajority before the next one is built. See Consensus mechanisms.
A reorg is not the same as a failed transaction. A failed transaction is permanently recorded onchain with a failure status and it consumed gas. A reorged transaction leaves no record on the canonical chain.

Why reorgs break naive pipelines

If you poll an RPC node for new blocks and append every result to a table, a reorg leaves you with:
  • Phantom records — transactions, transfers, and trades that are not on the canonical chain
  • Duplicates — the same transaction hash appearing twice, once from each branch, often with a different block number
  • Broken balances — a transfer counted that never happened, so every balance derived from it is off
  • Silent drift — no error is raised. Your pipeline looks healthy and your numbers are wrong
This is the single most common source of disagreement between a home-rolled indexer and a production dataset.

How Allium handles reorgs

Allium treats reorg handling as a property of the platform, not something you configure.
Allium’s scrapers track the parent hash of every block they ingest. When a newly fetched block does not descend from the block we already hold at the previous height, that is a reorg: we walk back to the common ancestor and re-fetch the replaced range from the canonical branch.
For the confirmed feeds, Allium waits a per-chain number of confirmations before publishing a block at all, so the vast majority of reorgs are resolved before the data is ever served. Depths are tuned per chain and listed in Transaction finality.
On the Realtime APIs, Allium captures reorgs as they happen and immediately corrects the affected entities — blocks, transactions, and everything derived from them. Records superseded by a reorg are removed or replaced rather than left in place.
Batch data in the Data Catalog and Datashares is continuously re-verified against the chain by existence and consistency checks. Any range that disagrees with the canonical chain is re-ingested and republished, which is why batch freshness can degrade slightly on chains that reorg frequently.

What this means for each product

If you consume a latest stream, design for it. Key your storage on (block_number, transaction_hash) and make writes idempotent so a replaced block overwrites rather than duplicates, or treat latest as a low-latency signal and reconcile against a confirmed source before you act on money.

Building your own reorg-safe pipeline

Whatever source you consume, these rules keep you correct:
1

Store the block hash, not just the number

A block number is not a unique identifier across branches. A block hash is.
2

Make writes idempotent

Upsert on a natural key so a re-delivered or corrected record replaces the old one instead of adding a row.
3

Recompute derived state rather than incrementing it

A balance derived by summing transfers self-corrects when a transfer is removed. A balance stored as a running counter does not.
4

Set your confirmation threshold by exposure, not by habit

Match the wait to what a reversal would cost you. See Transaction finality.

Next steps