Skip to main content

Indexer Architecture

A production indexer is a state machine with a durable cursor. It backfills historical data, switches to live sync, handles reorg or finality rules, and writes idempotently to a query database such as Postgres.

ComponentResponsibility
Source adapterCalls JSON-RPC, REST, GraphQL, gRPC, or WebSocket APIs.
Cursor storeRecords block height, slot, checkpoint, ledger version, or stream offset.
DecoderConverts raw chain payloads into typed domain events.
WriterPerforms idempotent inserts/upserts in Postgres.
ReconcilerDetects gaps, reorgs, missed stream messages, and node lag.
API layerServes product queries from indexed tables, not from hot node RPC.
backfill worker ---> decoder ---> postgres tables ---> product API
| ^ ^
v | |
cursor store live stream ----- reconciler

Polling is simpler and reliable for backfill. Streaming reduces latency for live updates but needs reconciliation because connections can drop. Sui's event indexer example is a useful chain-specific pattern for cursor-based event ingestion (Sui event indexer). Aptos transaction stream gRPC and Solana WebSocket subscriptions follow the same durable-consumer principle even though the APIs differ.

:::tip Store raw identity Keep chain, height/slot/checkpoint/version, transaction hash or digest, event index, and source block hash where applicable. Those fields make dedupe, rollback, and audits possible. :::

Use /developer/event-processing for decoding and ordering rules, and /developer/reorg-finality-handling for finality behavior.