.png)
.png)
Subgraphs or Substreams: Which Blockchain Data Solution Should You Choose?
When building a blockchain application, there are a lot of things you have to get right. Data pipeline ranks near the top of that list. Not just where you source your data, but how. Picking the right data pipeline is one of the most important architectural decisions you'll make, because it defines everything else. Usability. Reliability. Utility.
This data solution should not only meet your current needs but also have the capacity to scale. That way, you won't have to change the tires while the car is moving, so to speak. After all, you may wish to integrate new chains and protocols further down the line, or add new features, each adding to the demand on your data infrastructure.
Within ecosystem, there are two powerful data solutions for blockchain developers: Subgraphs and Substreams. Both are designed to efficiently deliver custom protocol data, but they serve different purposes and excel in different areas. Understanding their core strengths is the key to selecting the data solution that will meet your performance requirements as you grow and, just as importantly, knowing how to move between them when those requirements change.
What Are Subgraphs?
are custom, open APIs that extract and process blockchain data so it can be queried easily via GraphQL. They define which onchain events should be indexed and how the resulting data should be structured, allowing applications to retrieve precise information without scanning entire chains. Subgraphs aggregate application-specific blockchain data and expose it in a queryable format, making them especially useful for frontends and analytics dashboards.
In technical terms, Subgraphs are well understood using the Extract, Transform, Load, and Query (ETLQ) framework. JSON-RPC nodes extract onchain data. This is an approach that works well but relies on serial processing, which limits how fast the data can be indexed. Subgraphs then use AssemblyScript to map, filter, and transform that data before loading it into a PostgreSQL database. Mappings are compiled to WebAssembly (WASM), which Graph Node executes as it indexes each block. Finally, the data is surfaced to users via a GraphQL API. Today, there are published on The Graph Network that can help you get access to some of the most common protocols in web3.
In short, Subgraphs act as persistent indexing layers that maintain historical and current state, enabling applications to access data in real time. If you're developing a dapp with a user interface or some kind of frontend, a Subgraph is likely what you'll need. For the vast majority of small-to-medium applications, a Subgraph is not just sufficient — it's the ideal tool for the job.
What Are Substreams?
are a parallel blockchain indexing technology designed to enhance performance and scalability by processing data in streaming pipelines. They represent a shift from sequential indexing, as popularized by Subgraphs, toward parallelized processing, enabling dramatically faster data extraction and transformation.
Substreams allow developers to extract data and apply custom transformations before sending the output to a destination of their choice, such as analytics dashboards or downstream applications. Because they operate as streaming pipelines, Substreams are particularly well suited to high-throughput environments and real-time processing workflows.
In more technical terms, Substreams re-architect the ETLQ process to incorporate speed through parallel processing. Instead of polling JSON-RPC nodes serially, Substreams extract data from a Firehose stream of flat files, which lets historical blocks be processed in parallel rather than one at a time. Transformations are written in Rust and compiled to WASM modules that filter, decode, and aggregate the data. And rather than loading into a fixed PostgreSQL database, the output can be "sinked" to a , including PostgreSQL, ClickHouse, Kafka, or flat files. Substreams are purely an ETL process; how the data is queried is left to whatever system you sink it into.
Broadly speaking, then, Subgraphs are the go-to solution for blockchain applications and Substreams are the preferred option for more intensive processes like analytics, high-frequency trading, AI/ML, high-TPS chains, and heavy protocols. But it would be a mistake to envisage Substreams as being a more powerful form of Subgraphs. Their underlying architecture is distinctly different, and these differences manifest in the areas where each solution shines.

Subgraphs as State Specialist
If your primary goal is to power a user-facing application, Subgraphs are likely your best friend. They're designed to organize the chaotic history of the blockchain into the orderly current state that users expect to see.
It's not just the output Subgraphs supply that makes them so useful, but the ease with which they can be integrated. Subgraphs speak the language of the web, using a GraphQL API that allows frontend developers to query exactly what they need. This makes integrating blockchain data into React or Vue seamless.
Subgraphs excel at mapping connections. If you need to know who owns a particular token or the composition of assets in a specific pool, Subgraphs handle these relational queries effortlessly. And because Subgraphs have been the backbone of DeFi protocols for years, there's a massive library of existing templates and a rich ecosystem of developer tools.
Substreams as Flow Specialist
If your goal is less focused on showing a user a UI, and more on analyzing or transforming massive amounts of data, Substreams are the powerhouse you need. This streaming-first engine is built for speed and flexibility. Because Substreams can process history in parallel, they're capable of indexing massive histories, such as the entirety of all Aave lending on Ethereum, in a fraction of the time it would take linearly.
That covers the speed part. The flexibility, meanwhile, is derived from the fact that Substreams don't force you to use a specific database. You can "sink" (i.e. output) your data anywhere, be it directly into a SQL database, a Mongo instance, a flat file (e.g. CSV/JSON), or even straight into a Kafka stream.
Written in Rust, Substreams are highly performant modules. They allow for complex transformations, such as calculating realized volatility or tracking specialized derivatives, before the data ever hits your database. Substreams do the heavy lifting for you. Finally, they're fully composable, allowing you to utilize modules built by other developers. If someone has already written a module to "Extract ERC-20 Transfers," you can simply import it and build on top of it.
When Do You Actually Need to Scale to Substreams?
Subgraphs work well, until they don’t. Rather than guessing, watch for a few concrete signals that your project is outgrowing sequential indexing:
- Sync times are getting painful. When a Subgraph has to replay years of history one block at a time, initial syncs and re-syncs start measuring in days rather than hours. Substreams process history in parallel, collapsing that backfill into a fraction of the time. If you’re waiting more than 1-2 days for your Subgraph to sync, it’s probably time to upgrade to Substreams.
- You're indexing a high-throughput or high-TPS chain. On chains like Solana, BSC, or busy L2s like Arbitrum during peak activity, the volume of events can simply arrive faster than a linear indexer can keep up. Substreams are designed for exactly this firehose.
- You need data somewhere other than a GraphQL API. If your roadmap includes feeding a data warehouse, an analytics stack, a trading engine, or an AI/ML pipeline, the "sink anywhere" model of Substreams (Postgres, ClickHouse, Kafka, files, and more) fits where a single GraphQL endpoint doesn't.
- You need heavy server-side transformations. Aggregations, rolling metrics, derivatives math, or cross-protocol joins are cheaper and cleaner computed inside the pipeline than reconstructed client-side on every query.
- Account-level state and fine-grained historical replay matter. Solana-style account state tracking and precise historical backfills are native strengths of Substreams.
None of this means a Subgraph was the "wrong" choice earlier. It usually means the project succeeded and grew. The good news: moving up doesn't mean starting over.
The Features That Help Substreams Excel at Scale
When you do reach that inflection point, a handful of Substreams features do the heavy lifting:
- Parallelized back-processing. Historical data is processed in parallel rather than linearly, turning multi-day backfills into something far shorter. This can mean up to 100x faster in favorable cases.
- Composable, reusable modules. Pipelines are built from .spkg packages that . Don't reinvent an ERC-20 transfer module, just import one.
- Sink anywhere. The same module logic can output to PostgreSQL, ClickHouse, Kafka, files, or a custom destination, so Substreams slot into your existing stack rather than dictating it.
- Cursor-managed reliability and reorg awareness. Substreams track stream position and handle chain reorganizations explicitly, so reconnections don't drop data and forks don't leave stale rows behind. That’s essential on chains with optimistic confirmations.
- Deterministic execution. Compiled to WASM, the same inputs always produce the same outputs on any runner. They are auditable and reproducible, which matters for analytics, compliance, and research.
- Server-side transformations. Filtering, decoding, and aggregation happen inside the pipeline, reducing client complexity and bandwidth.
Migrating a Subgraph to Substreams: Without Starting From Scratch
Historically, the biggest tax on "graduating" to Substreams was the rewrite: a Subgraph is GraphQL plus AssemblyScript, while Substreams are protobuf plus Rust. That conceptual gap is now far smaller, thanks to a new open-source agent skill from core developer StreamingFast: substreams-convert.
substreams-convert is expert knowledge for AI coding assistants, like Claude Code, Cursor, VS Code, and Windsurf, that turns an existing Subgraph (subgraph.yaml + schema.graphql + AssemblyScript mappings) into a working Substreams module pipeline. Instead of hand-translating every handler, you point your assistant at the skill and it understands the mapping between the two systems:
| Concept | Subgraph | Substreams |
|---|---|---|
| Language | AssemblyScript | Rust (compiled to WASM) |
| Schema | GraphQL SDL (schema.graphql) | Protobuf + SQL schema |
| Handler trigger | Event / call template | Block-level map module |
| State persistence | Entity store (auto-managed) | SQL sink via db_out (Postgres / ClickHouse) |
| Output | GraphQL API | SQL, Kafka, MongoDB, and multiple other “sinks” |
| Reorg handling | Automatic | Cursor-based, explicit |
| Backfill speed | Sequential | Parallel |
The SKILL walks an agent through the whole migration: identify the source, map the schema.graphql entities into protobuf types, translate the AssemblyScript handlers into Substreams map and store modules, wire everything together in substreams.yaml (carrying over your original initialBlock), then build and verify. It even pulls in sibling skills automatically: substreams-dev for build setup, and substreams-sql / substreams-sink-deploy when your target is a SQL database.
The practical upshot: the cost of moving from a Subgraph to Substreams is now measured in hours of assisted work, not weeks of manual porting. Your Subgraph investment carries forward instead of being thrown away.
So Which Solution Is Right?
Subgraphs and Substreams each have their own sphere of excellence, and in most cases the optimum solution will be clear:
Choose Subgraphs when you need:
- A fast, low-cost path to ship, which is ideal for most small-to-medium projects
- A user-facing application with real-time state queries and GraphQL API integration for frontend development
- Relational data queries (ownership, pool composition, etc.)
- Access to proven templates and extensive developer tooling
- One of the with pre-indexed data ready to query
Choose Substreams when you need:
- High-throughput data processing at scale
- To consume data from a blockchain with sub-second block times
- Complex transformations before data storage
- Flexibility to output to custom databases or formats
- Parallel processing of massive blockchain histories
- Composable modules for specialized analytics, AI/ML, and trading
Whatever your choice, whether the structured elegance of a Subgraph or the raw horsepower of Substreams, you can be assured that the data you consume is open and decentralized.
Rather than viewing these technologies as competing tools, it's more accurate to see them as components of a broader data stack. You can start with a Subgraph, scale into Substreams when the project demands it, and, thanks to skills like substreams-convert, move between them without throwing away your work. Together, they let developers build performant applications constrained only by their imagination. If you can envision it, with Subgraphs and Substreams, you can create it.
Want to try the migration path yourself? The substreams-convert skill is part of the open-source and works with Claude Code, Cursor, and VS Code. Learn more in .
About The Graph
The Graph is a suite of blockchain data infrastructure products that extract, process, and deliver scalable blockchain data solutions across 60+ networks. The Graph enables application developers, data analysts, AI agents, and enterprise teams that need structured, real-time access to blockchain data. Products include Subgraphs, Firehose, Substreams, and Amp. As of early 2026, The Graph has served over 1.27 trillion queries to more than 75,000 projects, powered by a network of independent Indexers around the world.
Follow The Graph on , , , and . Join the community on The Graph’s , join technical discussions on The Graph’s .
