Grafting, and shipping a fix without a resync

It reuses an existing subgraph's data and carries on from a chosen block, turning a multi-day resync into a deploy. The docs advise against it exactly where you will want it most.

Checked against Graph Horizon (2025-12-11)

Last read 2026-08-30 Due again 2026-11-30

Every protocol claim below was read at these sources on 2026-08-30. Where they disagree with each other, the entry says so.

A subgraph fails at block 5,956,000 because a handler hit a case its author did not expect. The fix is four lines. Applying it normally means reindexing from the start block, which on a long history is hours or days during which your application has no data.

Grafting is the way out. It lets a new deployment “reuse the data from an existing Subgraph and start indexing it at a later block.”

The syntax

features:
  - grafting
graft:
  base: Qm...        # the deployment ID to copy from
  block: 5956000     # copy up to and including this block, then index onward

The documentation describes the mechanic exactly: “The Graph will copy the data of the base Subgraph up to and including the given block and then continue indexing the new Subgraph from that block on.”

So you choose a block you trust the data up to, usually just before the failure, and the new deployment inherits everything before it.

What you are allowed to change

The grafted schema must be a valid schema in its own right, and may differ from the base in specific ways:

  • add or remove entity types
  • remove attributes from entity types
  • add nullable attributes
  • convert non-nullable attributes to nullable
  • add enum values
  • add or remove interfaces
  • modify which entities implement an interface

Read the shape of that list rather than memorising it. Everything permitted is either additive or a loosening. You may add a nullable field, because existing rows can be null for it. You may not add a non-nullable one, because there is no honest value to put in the rows you inherited.

The warning that matters

The documentation is direct: “It is recommended to not use grafting for Subgraphs published to The Graph Network.”

Which is awkward, because a published subgraph with live consumers is exactly where a multi-day resync hurts most, and therefore exactly where grafting is most tempting.

The reasoning is about trust rather than mechanics. A grafted subgraph’s early history was not derived by the deployment serving it; it was copied from another deployment. Any indexer syncing it inherits that data rather than computing it. For something the network is meant to be able to verify independently, that is a meaningfully weaker position.

The suggested pattern is to deploy an initial version without grafting, and use grafting for subsequent updates once the subgraph is “stable and functioning as expected”. In practice that means: graft freely in development and to recover a failure, and think hard before grafting something that becomes the canonical published history.

Its interaction with pruning

You cannot graft at a pruned block height. If grafting is part of how you ship, your pruning setting has to retain enough history to graft from.

That constraint is easy to miss because the two settings live in different parts of the manifest and are decided at different times, usually months apart. prune: auto plus a grafting habit is a combination that works until the day you need it not to.