Moving a subgraph to a nest.

A nest can answer part of a subgraph's GraphQL, exactly, and refuse the rest by name. It is not a drop-in replacement, and most clients cannot adopt it by changing a URL. Before you move anything, find out which of your queries fall inside the part it answers. This page is how.

Event-shaped fields answer. Mapping-computed ones do not.

A nest is a compiler over decoded chain events, not a second indexer. It does not run AssemblyScript. Whatever a subgraph takes straight from events, it reproduces exactly; whatever a mapping computes in order, carrying state from one event to the next, it refuses. Every field either answers exactly or is refused with a reason. There is no third behaviour: no default, no stale value, no empty list in place of an answer.

Answers exactlyRefused by name
ids, timestamps, block numbers, log indicesprices, and anything derived from one
addresses, token ids, transaction hashespriced totals: volume in USD, fees, TVL
values taken straight from an event's parametersvalues from ordered, stateful mapping code
sums and counts over events, where a view reproduces themday and hour aggregate entities
@derivedFrom relations between the above

From what the compatibility surface is, and what it is not.

Why most clients cannot switch by changing a URL.

GraphQL has no partial answer. A query that names one field a nest cannot answer is refused whole, and the client gets an error rather than the other fields. So field coverage is an upper bound on query coverage, and a loose one.

70 of 184
fields classed exact that a nest answered on the pinned Uniswap V4 port (38%)
41 of 93
on Carbon, the second pinned target (44%), which has no priced fields
0 of 4
fields answered in pools(orderBy: totalValueLockedUSD) with volume and token symbol

All three were measured on 12 September 2026 and are recorded in RFC-0053's measured outcome. For a Uniswap-shaped analytics client, the honest summary is that a nest answers nothing it would ask for. For a bot, a reconciliation job or an audit trail asking for every Swap on a pool since some block, with sender, transaction hash and log index, it answers exactly over the whole history. The shape of the subgraph decides the outcome far more than anything left to build. The programme is parked: what shipped is supported, and nothing further is being added to it.

Port the subgraph, and read the report first.

port-report classifies every entity field against the mappings and writes nothing. init --from-subgraph takes the manifest's data sources, ABIs and start blocks, and port-emit overlays the views and prints a coverage line naming every field it cannot answer. port-emit needs the subgraph's source, its schema.graphql and mappings, because a deployment CID holds only compiled WASM. Check your own queries' fields against that list.

shell
# 1. Report first. Nothing is written.
nuthatch port-report --dir path/to/subgraph > port-report.md

# 2. Scaffold from the manifest, then overlay views, calls and checks.
nuthatch init --from-subgraph <deployment CID> --dir nest
nuthatch port-emit --dir path/to/subgraph --out nest

The default binary has no GraphQL route: POST /graphql answers 404. Serving the Graph dialect needs the separate nuthatch-graph download attached to every release since 4.11.0, described under the graph build. The subgraph port skill walks a coding agent through the same steps.

Start from the contract address instead.

If you own the client, it is often simpler to leave GraphQL behind. Give init the contracts the subgraph indexed and it makes one table per event from the ABI, with no mappings and no schema to write. Then ask in SQL, over HTTP at /sql or from an agent over MCP. Counts, sums and joins over events are a view in views/*.sql, or a maintained entity when it must be fast.

shell
nuthatch init 0xYourContract --chain arbitrum-one
nuthatch dev
nuthatch sql "SELECT count(*) FROM <alias>__<event>"

Prices are the same problem by this route: nothing derives a USD value for you. The worked example goes from address to view to entity, and the agents page connects the result to Claude Code or Cursor.

What carries over

  • Data sources, ABIs and start blocks, read from the manifest by init --from-subgraph.
  • Factory templates, where a parameter names the template; the rest are listed for you to resolve.
  • Introspection, filters, ordering, pagination and _meta, in the graph build.
  • Event-shaped fields, exactly, over the hot store and sealed history alike.
  • Queries at /graphql and /subgraphs/id/<deployment>.

What does not

  • Mapping code. AssemblyScript is never run, in indexing or anywhere else.
  • Prices and priced totals such as derivedETH and totalValueLockedUSD. By design, not by backlog.
  • Day and hour aggregate entities, which have no table.
  • A query that names any refused field: it fails whole.
  • The GraphQL route in the default binary, and any shape not on the accepted dialect.

We can host the port

We port a subgraph that is no longer live on the network to a nest and run it on our servers, with no billing and no accounts. Its event-derived fields answer exactly and the rest are refused by name, so check your app's queries against the port before switching. The hosting offer has the terms, and the BetSwirl BNB Chain handback shows one port end to end: its client's own queries answered exactly.

Beside the network, not instead of it

A subgraph that the network still serves is usually best left there. A nest is for the case where a subgraph has stopped, or where you would rather hold your own contracts' history on your own machine. Nuthatch and The Graph sets out how the two sit together, and the comparison puts Nuthatch beside The Graph, Ponder, rindexer and Envio.