What Is Blockchain Event Indexing and Why Every dApp Needs It
How blockchain event indexing turns on-chain logs into queryable data, and how to evaluate an indexing approach.
A dApp may need transaction histories, balances, or aggregates that are expensive to assemble from RPC calls at request time. Event indexing processes blockchain data into a store designed for those reads.
Choose the indexing approach based on the events, query patterns, freshness, and correctness requirements of the product.
What Blockchain Event Indexing Means
When a smart contract executes a function that emits an event, the EVM writes a structured log entry to that block's receipt. Each log contains the contract address, up to four indexed topics (used for filtering), and an ABI-encoded data payload.
An indexer is a process that:
- Connects to an RPC endpoint and subscribes to new blocks
- Reads each block's transaction receipts and extracts matching logs
- Decodes the ABI-encoded data into typed fields
- Writes the result into a structured database — typically PostgreSQL
The database is then served via a GraphQL or REST API. Your frontend queries the indexer, not the node.
That shift from "read from chain" to "read from indexed database" is the core idea. Everything else — subgraphs, custom indexers, managed services — is implementation detail layered on top.
Why Blockchains Are Bad at Being Read Databases
Blockchains are optimized for write integrity, not read performance. A node stores data in a Merkle Patricia Trie designed for cryptographic proofs, not for range queries, aggregation, or joins. When you call eth_getLogs with a broad filter, the node may scan millions of storage slots. With a narrow filter over a short range it works. At scale, across history, it fails.
The practical symptoms developers hit:
eth_getLogscalls timing out on public RPC endpoints- No way to query "all Transfer events where recipient = X" efficiently
- No aggregated state (e.g., total volume for a pool over the last 30 days)
- Re-fetching the same data repeatedly because there is no cache
An indexer gives you persistent, queryable state that updates as blocks arrive.
The Core Components of an Indexing Pipeline
A minimal indexing setup has four layers:
Ingestion: A process that pulls blocks from an RPC endpoint (or a firehose-style stream) and feeds raw receipts into the pipeline.
Decoding: The ABI for each contract is applied to raw log data, producing human-readable event structs with typed fields.
Storage: Decoded events are written to a relational or columnar database. Entities are updated based on handler logic — for example, a Swap event increments a pool's cumulative volume.
API: A GraphQL or REST layer exposes the processed data for frontends, bots, and analytics tools.
What Indexing Is Not
Indexing is not a replacement for the RPC. You still need an RPC for submitting transactions, reading live contract state for a single address, and any write operation. Indexing handles the read side of the stack.
When Your dApp Needs an Indexer
Not every project needs a full indexer immediately. A useful heuristic:
- You do not yet need one if your UI only reads a handful of contract storage variables and you have no historical query requirements.
- You need one as soon as you display event history, leaderboards, aggregate protocol stats, or any data that requires filtering across more than a few hundred blocks.
- You need a robust one the moment you have more than a few hundred daily active users, or your product's correctness depends on complete event coverage (e.g., a DEX, a lending protocol, a game with on-chain state).
The cost of retrofitting indexing into a live protocol is high. Teams that defer it end up with missing historical data that cannot be backfilled cleanly, or brittle custom scripts that break on reorgs.
Choosing Your First Indexing Approach
The practical options for most teams today:
- The Graph / subgraphs: Declarative, GraphQL-native, battle-tested. Good default for EVM-compatible contracts.
- Managed alternatives (Goldsky, Envio, SubQuery): Subgraph-compatible APIs with faster sync, lower maintenance, or multi-chain support.
- Custom framework (Ponder, self-built): Full control over handler logic, schema, and deployment. Appropriate when your data model diverges significantly from what subgraph mappings can express.
Evaluate a hosted subgraph against your query and chain requirements. A custom indexer may be needed where those requirements exceed the platform’s capabilities.
Reorg Handling Is Non-Negotiable
One detail that catches teams off guard: blockchains reorganize. A block that appeared finalized can be replaced by a competing fork. An indexer that does not handle reorgs will silently write incorrect state.
Well-designed indexers track block hashes alongside block numbers and roll back entity state when a reorg is detected. When evaluating any indexing solution, ask explicitly how it handles chain reorganizations.
If your protocol involves significant financial state, test reorg behavior before launch.