# Consistency and finality

Source: https://docs.graphops.xyz/rpc/concepts/consistency-and-finality

A balance, price, and transaction count read at different blocks may not describe the same state.
Pin related calls to one block so your application compares like with like. Choose finality based
on whether the result can tolerate a later chain reorganization.

## Block references

| Reference    | Use it when                                                                                    |
| ------------ | ---------------------------------------------------------------------------------------------- |
| `latest`     | You want the freshest available view and can tolerate best-effort consistency across requests. |
| `safe`       | You want a safer recent block for user-visible reads.                                          |
| `finalized`  | You want finalized data and can tolerate additional latency.                                   |
| Block number | You need repeatable reads across multiple requests.                                            |
| Block hash   | You need to anchor work to one exact block.                                                    |

_The latest block is the newest. The safe block trails it and is unlikely to be reorganized, and the finalized block will not change. Distances between them vary by network, so pin related reads to one block number or hash._

- `finalized`: block N-5 in this example.
- `safe`: block N-3 in this example.
- `latest`: block N in this example.

## Repeatable read pattern

When multiple calls must observe the same state:

1. Select a block with `eth_blockNumber`, or with `eth_getBlockByNumber` and a tag such as `safe`
or `finalized`.
2. Store the block number or block hash.
3. Pass that same reference to follow-up `eth_call`, `eth_getLogs`, `eth_getBalance`,
`eth_getStorageAt`, or `eth_getCode` requests.

For example, these two reads can describe different blocks, because each `latest` resolves when
its request arrives:

```json
[
  { "method": "eth_getBalance", "params": ["0x...", "latest"] },
  { "method": "eth_call", "params": [{ "to": "0x...", "data": "0x..." }, "latest"] }
]

```

These two reads describe the same block, `18000000`:

```json
[
  { "method": "eth_getBalance", "params": ["0x...", "0x112a880"] },
  { "method": "eth_call", "params": [{ "to": "0x...", "data": "0x..." }, "0x112a880"] }
]

```

Sending the reads in one batch does not pin them; only the explicit block reference does.
[Read contract state](../guides/read-contract-state#read-several-values-at-one-block) shows the
pattern in client code.

## Choose finality

A pinned block can still be reorganized if it is newer than `finalized`. Pick the reference by
what a reorganization would cost you:

* Use `latest` for displays that refresh and can show a brief inconsistency.
* Use `safe` for user-visible reads that should rarely change.
* Use `finalized` for settlement, accounting, or any irreversible step.

When you store data from recent blocks, keep enough block identity to undo it.
[Retries and reorgs](../guides/retries-and-reorgs#handle-reorgs) shows how.

## Next steps

* [Read contract state](../guides/read-contract-state): Pin several `eth_call` reads to one finalized block.
* [Retries and reorgs](../guides/retries-and-reorgs): Undo data from replaced blocks and retry on the same block.
* [Supported networks](../networks): Check network notes for L2 finality differences.