> For the complete documentation index, see [llms.txt](https://docs.envio.dev/llms.txt).

# Understanding and Handling Chain Reorganizations

:::info Short answer
HyperIndex detects chain reorganizations and rolls back your indexed data automatically. It's on by default (`rollback_on_reorg: true`) and covers reorgs up to `max_reorg_depth` blocks below the chain head. That's 200 on most chains and 0 on Arbitrum and OP Mainnet (see the [defaults](#default-confirmation-thresholds)). You don't need any rollback logic in your handlers.

Detection is guaranteed when you read from [HyperSync](#guaranteed-detection) and has some [edge cases on RPC](#rpc-limitations). Side effects outside the database, such as calls to external APIs, are [not rolled back](#scope-of-rollbacks).
:::

## What Are Chain Reorganizations?

Chain reorganizations (reorgs) occur when the blockchain temporarily forks and then resolves to a single chain, causing some previously confirmed blocks to be replaced by different blocks. This is a normal part of blockchain consensus mechanisms, especially in proof-of-work chains.

When a reorg happens:

- Transactions that were previously considered confirmed may be dropped
- New transactions may be added to the blockchain
- The order of transactions might change

For indexers, this presents a challenge: data that was previously indexed may no longer be valid, requiring a rollback and reprocessing of the affected blocks.

## Automatic Reorg Handling in HyperIndex

HyperIndex includes built-in support for handling chain reorganizations, ensuring your indexed data remains consistent with the blockchain's canonical state. This feature is **enabled by default** to protect your data integrity.

## Configuration Options

### Enabling or Disabling Reorg Support

You can control reorg handling through the `rollback_on_reorg` flag in your `config.yaml` file:

Enable reorg handling (the default):

```yaml
rollback_on_reorg: true
chains:
  # chain configurations...
```

Or disable it (not recommended for production):

```yaml
rollback_on_reorg: false
chains:
  # chain configurations...
```

### Configuring Confirmation Thresholds

You can customize the number of blocks required before considering a block "confirmed" and no longer subject to reorgs:

```yaml
rollback_on_reorg: true
chains:
  - id: 137 # Polygon
    start_block: 0
    max_reorg_depth: 250
  - id: 1 # Ethereum
    start_block: 0
    # Using default threshold
```

The `max_reorg_depth` field (renamed from V2's `confirmed_block_threshold`) defines how many blocks below the chain head are considered safe from reorganizations. Any reorg deeper than this threshold won't trigger a rollback in your indexer.

## Default Confirmation Thresholds

Most chains default to a threshold of **200 blocks**. Arbitrum and OP Mainnet networks default to **0**, which means HyperIndex doesn't track reorgs on those chains, so a reorg there is not detected or rolled back. Set `max_reorg_depth` on those chains if you want rollbacks there.

| Chains | Default Threshold |
| --- | --- |
| Arbitrum One, Arbitrum Nova, OP Mainnet | 0 blocks (no rollback) |
| Arbitrum and OP testnets, Citrea Testnet, Citrea Devnet | 0 blocks (no rollback) |
| All other chains | 200 blocks |

## Technical Details and Limitations

### Guaranteed Detection

Reorg detection is guaranteed when using [HyperSync](https://docs.envio.dev/docs/HyperIndex/hypersync.md) as your data source. HyperSync returns the logs and blocks for a queried range atomically, so block hashes and parent hashes always match the data returned, and any reorganization is detected and handled.

### RPC Limitations

When using a [custom RPC endpoint](https://docs.envio.dev/docs/HyperIndex/rpc-sync.md) as your data source, there are some edge cases where reorgs might go undetected. RPC queries aren't atomic, so if the logs come from a reorged block but the block header comes from the canonical block, the indexer may not see that the logs came from a reorged block.

### Scope of Rollbacks

During a reorg-triggered rollback:

✅ **What is rolled back:**

- All entities defined in your schema
- All data that your handlers read or write to the database

❌ **What is not rolled back:**

- Side effects in your handler code (API calls, external services)
- Custom caching mechanisms outside of HyperIndex
- Logs or external files written by your handlers

## Best Practices

1. **Keep reorg support enabled** for production indexers
2. **Use HyperSync** when possible for guaranteed reorg detection
3. **Avoid external side effects** in your handlers that cannot be rolled back
4. **Consider higher thresholds** for high-value applications or chains with historically deep reorgs

## Example Configuration

Here's a complete example showing reorg handling configuration for multiple chains:

```yaml
rollback_on_reorg: true
chains:
  - id: 1 # Ethereum Mainnet
    start_block: 0
    # Using default threshold (200)
    # other chain config...

  - id: 137 # Polygon
    start_block: 0
    max_reorg_depth: 250 # Higher threshold for Polygon
    # other chain config...

  - id: 42161 # Arbitrum One
    start_block: 0
    max_reorg_depth: 200 # Arbitrum defaults to 0, so set it to enable rollbacks
    # other chain config...
```

By properly configuring reorg support, you ensure that your indexed data remains consistent with the blockchain, even when the chain reorganizes.

## Using HyperSync Directly? Handle Reorgs with the Rollback Guard

If you use [HyperSync](/docs/HyperSync/hypersync-query#rollback-guard) directly, without HyperIndex, you have to handle reorg detection and rollback yourself using the optional **rollback guard** that HyperSync returns with query responses near the chain head.

HyperSync validates block parent hashes internally and re-syncs when it detects a fork, so it always serves canonical chain data. Data you have already fetched can still go stale after a reorg, though. To detect that, compare the `first_parent_hash` of the current response against the `hash` you stored from the previous response. If they differ, a reorg has occurred and you need to re-fetch the affected range.

For full details, including a pseudocode example, see the [HyperSync Rollback Guard documentation](/docs/HyperSync/hypersync-query#rollback-guard).

:::tip
HyperIndex automates all of this: it fetches recent block hashes to pinpoint exactly where a reorg occurred and automatically rolls back database state. Unless you need the full flexibility of raw HyperSync, HyperIndex saves significant implementation effort.
:::

---
