> For the complete documentation index, see [llms.txt](https://docs.triton.one/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.triton.one/solana/historical-data/accountsdb-storage-file-shrinking.md).

# AccountsDB storage file shrinking

How Agave AccountsDB shrinking works (--accounts-shrink-ratio, shrink\_collect) and why snapshots can lack old account versions.

Shrinking is a process that Agave executes periodically. Its goal is to remove accounts from storage files that are no longer valid because a newer version of the account exists.

This matters if you read Solana snapshots directly: **the shrinking process means a snapshot carries no guarantee that superseded account data is still present.** It might be there, or it might have been compacted away.

## Configuration

Shrinking runs on a hardcoded one-second interval:

```rust
const SHRINK_INTERVAL: Duration = Duration::from_secs(1);
```

Two flags control its behavior:

```bash
--accounts-shrink-ratio                 # defaults to 0.8
--accounts-shrink-optimize-total-space  # defaults to true
```

| Flag                                     | Default | Effect                                                                                                                                                                                                                                                     |
| ---------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--accounts-shrink-ratio`                | `0.8`   | Ratio of live bytes to total bytes. When `--accounts-shrink-optimize-total-space` is true, shrinking stops once the ratio across all candidate files is above this value. When false, a file is a shrink candidate when its own ratio is below this value. |
| `--accounts-shrink-optimize-total-space` | `true`  | When true, shrinking is evaluated globally across all candidates. When false, every candidate file is shrunk individually with no global context in each iteration.                                                                                        |

## How it works

Each second, the bank — inside the `AccountsBackgroundService` — calls `shrink_candidate_slots()`, which:

1. Checks the list of files marked as candidates for shrinking. By default, a file is a candidate when it contains any dead bytes. When `--accounts-shrink-optimize-total-space` is false, a file is a candidate only when its live-byte ratio is below `--accounts-shrink-ratio`.
2. If `--accounts-shrink-optimize-total-space` is true, calculates total live account bytes over total account bytes across the candidates.
3. If true, orders the candidate list by live-byte ratio, starting with the most sparse files.
4. If true, iterates, shrinking files until the overall live-byte ratio rises above `--accounts-shrink-ratio`.

When true, a file that was not shrunk stays in the queue only if its own live-byte ratio is below `--accounts-shrink-ratio`. When false, steps 2-4 are skipped and every candidate is shrunk.

For each shrunk file:

* `shrink_collect()` takes the accounts read from a storage file and returns the ones that are still alive.
* **Shrinking does not modify the original file.** It generates a new file containing only the valid accounts, then repoints to the updated one.

### How an account is determined to be dead

As of Agave v4.3.0, `shrink_collect()` applies these steps in order:

1. **Obsolete-accounts check.** When a newer version of an account is flushed to storage, or when old roots are cleaned, Agave records the old version's offset in that storage file's obsolete-accounts list (`AccountStorageEntry::obsolete_accounts`). Every account whose offset is on the list is filtered out.
2. **Zero-lamport tombstones.** Accounts recorded as tombstones are filtered out too. Tombstones in slots newer than the latest full snapshot are carried forward into the new file, so an incremental snapshot can still propagate the deletion.
3. **Index check.** `load_accounts_index_for_shrink()` looks up each remaining account in `AccountsDb::accounts_index`. The entry must point at the slot being shrunk; this is an assertion, not a filter. A zero-lamport account with a single reference is dropped at this step (and kept as a tombstone if its slot is newer than the latest full snapshot).

## Consequence for snapshot consumers

**Discard every version of an account except the last one before trusting any data read from a snapshot.**

## Source

* [`accounts_background_service.rs`](https://github.com/anza-xyz/agave/blob/v4.3.0/runtime/src/accounts_background_service.rs) — `SHRINK_INTERVAL`, `shrink_candidate_slots()`
* [`accounts_db.rs`](https://github.com/anza-xyz/agave/blob/v4.3.0/accounts-db/src/accounts_db.rs) — `shrink_collect()`, `load_accounts_index_for_shrink()`, `store_accounts_for_flush()`

## What's next

* [Historical data](/solana/historical-data.md) — Triton's archival and historical services
* [Historical data best practices](/solana/historical-data/best-practices.md) — working with archives at scale

***

<i class="fa-life-ring">:life-ring:</i> Contact support by clicking the chat icon in your [customer dashboard](https://customers.triton.one)\ <i class="fa-briefcase">:briefcase:</i> Sales questions? [Contact us](https://triton.one/contact)\ <i class="fa-sparkles">:sparkles:</i> AI agent? Read [llms.txt](https://docs.triton.one/llms.txt)\ <i class="fa-rss">:rss:</i> Follow updates: [Blog](https://blog.triton.one) · [X](https://x.com/triton_one) · [YouTube](https://www.youtube.com/@triton_one_ltd) · [Telegram](https://t.me/tritonone) · [GitHub](https://github.com/rpcpool)
