> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monad.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# MIP-8 Activation and Page Storage Migration

## Introduction

This document covers the operational side of activating MIP-8: migrating a node's database from **slot to page encoding**, live and without resyncing from genesis. Each node **dual-writes** both encodings until the fork flips the network to **page-encoded** database, then drops the old **slot-encoded** database.

## Background

### MIP-8

[MIP-8](https://monad.xyz/blog/mip-8) reorganizes the EVM state trie to be page-aware: storage slots are grouped into 4 KB pages instead of being scattered independently across disk by hashing. For node operators, what matters is that this changes the on-disk trie layout — which is why a migration is required.

### TrieDB timelines

A **timeline** is a full copy of the trie state on disk, built by writing every committed block into it in a given encoding. A node can run one or two timelines at once, each in its own encoding:

* **Slot-encoded timeline** uses the current trie layout, where each storage slot's disk location is determined independently by hashing. This is the pre-MIP-8 format.
* **Page-encoded timeline** uses the MIP-8 layout, where slots are packed into pages of 128 consecutive slots. This is the post-MIP-8 format.

**Dual mode** is a transitional state where a node runs both encodings at once, as two timelines on disk, and writes every committed block to both. A node stays in dual mode for the whole window between activating the page timeline and decommissioning the slot timeline.

**Primary** and **secondary** just label the two timelines on disk. They have no effect on execution or consensus. Over the course of the migration, primary and secondary swap, then the secondary is dropped (see [Migration plan](#migration-plan)).

### State machine kinds

The node's database tooling (`monad-mpt`, `monad-cli`) refers to slot and page encoding as state-machine kinds:

| Kind on CLI | Encoding |
| ----------- | -------- |
| `ethereum`  | slot     |
| `monad`     | page     |

What matters for execution is which timeline is **canonical** versus **shadow**. The canonical timeline is the one whose `state_root` is used for blocks on the canonical chain; the shadow timeline computes the same blocks on the other encoding in parallel, without its `state_root` being used anywhere.

MIP-8 activation is exactly the flip between the two:

* before activation, `ethereum` (slot) is canonical and `monad` (page) is the shadow
* this swaps at the hard fork, `monad` (page) becomes canonical and `ethereum` (slot) becomes the shadow.

This is why activation happens by network-wide consensus.

## Migration plan

The migration runs in three phases: two operator actions and one hard fork. Phase A activates the page timeline on each node. Phase B is the MIP-8 hard fork: at a fixed timestamp, the canonical chain switches from the slot timeline to the page timeline. Phase C decommissions the now-legacy slot timeline.

<img src="https://mintcdn.com/monadfoundation-40611fb6/BP6rYLBOYSsAWjlK/static/img/node-ops/upgrade-instructions/mip8-migration-timeline.svg?fit=max&auto=format&n=BP6rYLBOYSsAWjlK&q=85&s=b66540eb00f1a9d210b5b6e95c98d6b6" width="900" style={{marginLeft: "auto", marginRight: "auto"}} data-path="static/img/node-ops/upgrade-instructions/mip8-migration-timeline.svg" />

<Steps>
  <Step title="Initial">
    DB mode is Legacy/Slot — a single slot timeline. Execution is Pre MIP-8 Activation.
  </Step>

  <Step title="Phase A — Page activation">
    Operators activate the page secondary, bringing DB mode to Dual. Execution is still Pre MIP-8 Activation — nothing changes at the execution level yet.
  </Step>

  <Step title="Phase B — Hard fork">
    At the fork timestamp, MIP-8 activates network-wide: the page timeline becomes canonical and the slot timeline becomes its shadow. The node stays in Dual mode.
  </Step>

  <Step title="Phase C — Slot decommission (Final)">
    Operators promote the page timeline as primary, and decommission the now secondary slot timeline. DB mode flips to Page — a single page timeline. The node is now fully migrated.
  </Step>
</Steps>

## Operations

### Network status

| Network | Phase   | Current release | Hard fork timestamp | MIP-8 activated |
| ------- | ------- | --------------- | ------------------- | --------------- |
| Testnet | Initial | TBD             | TBD                 | No              |
| Mainnet | Initial | TBD             | TBD                 | No              |

### Get the current status

Check a node's current on-disk state directly with `monad-mpt`:

```bash theme={null}
monad-mpt --storage /dev/triedb
```

**Legacy/Slot** — migration not started:

```
Active timelines:
     Primary:
        State machine kind: ethereum
```

**Dual** — migration in progress:

```
Active timelines:
     Primary:
        State machine kind: ethereum
     Secondary:
        State machine kind: monad
```

**Page** — migration complete:

```
Active timelines:
     Primary:
        State machine kind: monad
```

### Migration tasks

<Warning>
  **Do not run this procedure yet.** Wait for the official Monad Foundation announcement — the steps below preview what running the migration will look like.
</Warning>

This applies to both full nodes and validators. **Validators migration will occur in cohorts.** The migration runs in three phases. Phases A and C are actions you take on each node; phase B is a network-wide hard fork that happens on a schedule.

<Steps>
  <Step title="Phase A — Activate the page timeline (operator action)">
    Run this on every node to bring the node into dual mode.

    1. Stop the Monad services.

    2. Activate the page secondary:

       ```bash theme={null}
       monad-mpt --activate-secondary --state-machine monad --storage /dev/triedb
       ```

    3. Dump a binary snapshot of the current (slot) primary:

       ```bash theme={null}
       monad-cli --version latest_finalized --dump-binary-snapshot /path/to/snapshot --db /dev/triedb
       ```

    4. Load that snapshot into the page secondary — this re-encodes the state from slot to page:

       ```bash theme={null}
       monad-cli --version latest_finalized --load-binary-snapshot /path/to/snapshot --secondary --db /dev/triedb
       ```

    5. Restart the Monad services. It's now in dual mode, dual-writing to both timelines.

    Every node must complete this phase before the MIP-8 hard fork timestamp.
  </Step>

  <Step title="Phase B — MIP-8 activation (hard fork)">
    Phase B is a scheduled protocol upgrade, not an operator action. Its timestamp is encoded in a chain-wide release and is identical for every node — it only ships once the whole network has completed phase A.

    At that timestamp, MIP-8 activates at the execution level and the canonical `state_root` flips from the slot timeline to the page timeline, network-wide, in the same block:

    * **Before the fork** — the slot timeline is canonical; the page timeline shadows it.
    * **At and after the fork** — the page timeline is canonical; the slot timeline shadows it.

    Which timeline is on-disk primary is independent of which one is canonical.
  </Step>

  <Step title="Phase C — Decommission the slot timeline (operator action)">
    Run this on each node any time after the fork.

    1. Stop the Monad services.

    2. Promote the page secondary to primary:

       ```bash theme={null}
       monad-mpt --promote-secondary --storage /dev/triedb
       ```

    3. Deactivate the now-stale slot timeline, reclaiming its disk space:

       ```bash theme={null}
       monad-mpt --deactivate-secondary --storage /dev/triedb
       ```

    4. Restart the Monad services. It's now a single page timeline.

    Future releases of Monad will enforce having the slot-encoded timeline decommissioned.
  </Step>
</Steps>

### Hard reset a node

The hard reset process itself doesn't change — still follow the [Hard Reset Instructions](/node-ops/node-recovery/hard-reset). The DB mode logic below happens automatically inside that same `restore-from-snapshot` step; there's no new manual procedure to learn.

A hard reset doesn't migrate your existing database — it wipes it and rebuilds from a snapshot. That means the reset tooling can't look at your node's prior on-disk state to decide what to rebuild (the reset truncates the DB before anything else runs), so it picks the target DB mode with this logic:

* If the MIP-8 hard fork has already passed, it creates a page timeline only, and imports the snapshot into it.
* If the fork hasn't passed yet and it can also create a page timeline, the result is Dual mode, with the snapshot imported into both timelines.
* If the fork hasn't passed yet and it can't create a page timeline, the result is Legacy/Slot, with the snapshot imported into the slot timeline only.

| MIP-8 Activation timestamp | Page timeline creation supported | Resulting DB mode |
| -------------------------- | -------------------------------- | ----------------- |
| MIP-8 Active               | —                                | Page              |
| Inactive                   | Yes                              | Dual              |
| Inactive                   | No                               | Legacy/Slot       |

The first row is deliberate: once MIP-8 is active on the network, there's no reason to stand up a slot timeline just to decommission it again in the very next phase — a reset node goes straight to page-only.

## Further reading

* [Engineering runbook](https://github.com/category-labs/monad/blob/max/page-store-migration-runbook/docs/page_store_migration_runbook.md#5-failure-handling-rollback-and-guard-rails) — full operator procedure, including failure handling, rollback, and guard rails
* [Network info](https://docs.monad.xyz/networks.json) — current network status and fork timestamps
* [MIP-8](https://monad.xyz/blog/mip-8) — the proposal behind page-aware storage
* [Mipland](https://mipland.com/mip-8) — MIP-8 tracking and discussion
* [MIP-8: page-ified storage state](https://forum.monad.xyz/t/mip-8-page-ified-storage-state/407) — forum discussion
