Substreams

Feed your database, analytics pipeline, or event processor with standard Substreams package output over gRPC.

Interface
gRPC · Resumable streams
Best for
Historical backfills and ordered block pipelines into your own database or processor.
Substreams
Your app Cursor Cursor
GraphOps Substreams Substreams
Ethereum New blocks Blocks

filtered_events

USDC transfers · decoded by this collector

Loading response data

What you get

  • Continuous block and event streams
  • Deterministic historical range processing
  • Reusable packages and output modules
  • Cursors for resuming and undo signals for reorgs

Choose Substreams when

  • The consumer must process every relevant block or event in order.
  • You need a historical backfill that continues as a live stream.
  • Cursor recovery forms part of the production design.

Use another service when

  • You need direct node calls, contract state reads, or transaction submission.

    RPC
  • You want to query indexed GraphQL entities without running your own materializer.

    Subgraphs

What you can build with Substreams

Substreams delivers package output over gRPC, and your consumer turns it into state. These patterns cover the decisions that keep that state complete and correct.

  1. 01 start block · stop block · cursor

    Historical backfill that continues live

    Load a protocol's event history into your database, then keep it current from the same consumer. Backfills and live streaming use the same stream protocol: start at the block your history needs, leave the stop block open, and the stream continues as new blocks arrive. Historical ranges can use parallel package execution within your organization's worker concurrency.

    1. Pin a package version and choose its output module.
    2. Set the start block your history needs. Omit the stop block to continue live.
    3. For very large histories, split the backfill into bounded ranges you can retry independently.
    You own
    The start block, the range plan, and destination writes.
    Plan for
    Backfill throughput is bounded by your organization's worker concurrency and output limits. Chunk large ranges and checkpoint progress.
    Backfill a range(opens in a new tab)
    Historical blocks stream first, then live blocks follow on the same stream. Your consumer receives output in block order and saves a cursor as it commits.
  2. 02 BlockScopedData · cursor

    Cursors committed with your data

    Every block-scoped message carries output and a cursor. Write both in one database transaction where you can, so the stored cursor always matches committed data. After a disconnect, reconnect with backoff and resume from the latest committed cursor. Replays from that point must be safe, so make writes idempotent.

    1. Apply the BlockScopedData output to your tables.
    2. Save its cursor in the same transaction as the output.
    3. On restart, resume from the latest committed cursor.
    You own
    Cursor storage and idempotent writes.
    Plan for
    A cursor saved before its output commits can skip data after a restart. A cursor kept only in memory replays work from an earlier block.
    Resume with cursors(opens in a new tab)
    Rows and cursor commit together. After a restart, the consumer resumes from the committed cursor without skipping a block.
  3. 03 BlockUndoSignal · last valid block

    Reorg corrections with undo signals

    Near the chain head, a block can be replaced. Substreams then sends a BlockUndoSignal with the last valid block and its cursor. Your consumer reverts what it wrote after that block, saves the new cursor, and continues with the replacement blocks.

    1. Keep enough history to revert recent reversible writes.
    2. On BlockUndoSignal, revert rows above the last valid block.
    3. Save the signal's cursor, then apply the replacement blocks.
    You own
    Reversible writes and the choice of finality mode.
    Plan for
    If your workload cannot revert writes, stream final blocks only with final_blocks_only, so output trails the chain head. The stream example at the top of this page follows live blocks and applies undo signals.
    Cursors and reorgs(opens in a new tab)
    Blocks N+1 and N+2 were replaced. The undo signal names N as the last valid block, and the consumer rewinds before applying the new blocks.
  4. 04 .spkg · db_out · substreams sink

    Package output in tables you own

    Reuse a package from the Substreams registry or run your own .spkg, then choose the output module your pipeline needs. Standard sinks write it to Postgres, ClickHouse, files, or Pub/Sub, or your application consumes the stream directly. The database stays yours to query, join, and retain.

    1. Find a package on substreams.dev or reference your own .spkg, and pin its version.
    2. Choose an output module, such as db_out for the SQL sink.
    3. Run the sink in your infrastructure with your GraphOps endpoint and API key.
    You own
    The sink process, its database, and its schema.
    Plan for
    A hosted sink is an enterprise discussion, not an included standard feature. Discuss your project
    Run a sink(opens in a new tab)
    The package runs on GraphOps. The sink and its database run in your infrastructure.

What GraphOps runs and what you own

GraphOps runs the package against chain data and streams its output. Everything after the stream, from cursors to tables, belongs to your consumer.

Your application owns

  • Package choice and version pinning
  • The consumer or sink and its database
  • Cursor persistence and undo handling
  • Range planning for large backfills

GraphOps runs

  • Standard Substreams gRPC endpoints on supported networks
  • Package execution for your streams, including historical ranges
  • Organization API keys, usage metering, and credits

Networks

Each network has its own endpoint, listed below from the live catalog. Package compatibility depends on the chain data model.

See supported networks

Limits to plan for

  • Concurrent streams, worker concurrency, output throughput, and message size are shared across your organization.
  • Authenticate with an x-api-key header or SUBSTREAMS_API_KEY. Route-token authentication is not supported.
  • Confirm a package supports a chain's data model before running it against another network.
Usage and limits(opens in a new tab)

Supported networks

Each network has its own endpoint, listed below from the live catalog. Package compatibility depends on the chain data model.

Loading the live network catalog

Plan your integration

Go from a new organization to a first response, then prepare for production traffic.

  1. 01

    Create an organization and add credits

    Choose your monthly credits or buy a top-up. Streams consume credits by the current billable components.

  2. 02

    Create an API key for Substreams

    The CLI reads SUBSTREAMS_API_KEY. Raw gRPC clients send an x-api-key header.

  3. 03

    Choose a package and network

    Pick a package and output module, then the endpoint for the chain it supports.

  4. 04

    Stream your first events

    Run the pinned Ethereum package over six blocks to inspect USDC Transfer events.

  5. 05

    Prepare for production

    Pin package versions, persist cursors durably, handle undo signals, and test recovery before processing a larger range.

Endpoint

gRPCStreams, backfills, and cursor resumes
https://<CHAIN_ID>.evm.substreams.graphops.xyz

Use standard Substreams tooling with this endpoint. Its hostname starts with the decimal EVM chain ID of a supported network.

Prerequisites

  1. Install the Substreams CLI.

  2. Set GRAPHOPS_API_KEY to your GraphOps API key.

CLI · Substreams CLI

# The CLI sends SUBSTREAMS_API_KEY to GraphOps in the x-api-key header.
export SUBSTREAMS_API_KEY="${GRAPHOPS_API_KEY}"

# Stream USDC Transfer events (--params) for six blocks from 18000002 as JSON lines.
substreams run \
  -e "https://1.evm.substreams.graphops.xyz" \
  "https://spkg.io/v1/packages/ethereum-common/v0.4.0" \
  "filtered_events" \
  --params "filtered_events=evt_addr:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 && evt_sig:0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" \
  --start-block 18000002 \
  --stop-block +6 \
  -o jsonl
Stream your first events(opens in a new tab)

Stream your first events.

Add credits and follow the quickstart, then test cursor recovery and undo handling before processing a larger range.