Architecture
The typical Thru indexing stack looks like this:Tech Stack Assumptions
The current@thru/indexer runtime assumes:
- PostgreSQL-backed tables generated through Drizzle
- a Drizzle database client passed as
db - a
clientFactorythat returns aChainClientfrom@thru/replay
- Hono for generated stream routes via
mountStreamRoutes(...) - Drizzle Kit for migrations
- a standalone Node service to run the indexer continuously
@thru/indexer and validate whether the current runtime fits your stack.
Runtime Setup
What Each Runtime Option Does
| Option | What it controls |
|---|---|
db | The Drizzle client used for inserts, updates, checkpoints, and generated route queries. |
clientFactory | Fresh replay client creation for backfill and live streaming. |
eventStreams | Append-only streams for event rows. |
accountStreams | Current-state streams for account rows. |
defaultStartSlot | Starting slot when no checkpoint exists yet. |
safetyMargin | How far behind the live tip replay should stay during backfill-to-live switchover. |
pageSize | How many records to request per backfill page. |
logLevel | Runtime verbosity. |
Checkpoints And Schema
Your Drizzle schema needs the checkpoint table plus every stream table.checkpointTable, the runtime cannot resume safely after restarts.
Process Shape
In practice, most apps run the indexer as its own long-lived service:- load environment and connect to Postgres
- run or verify migrations
- build the
Indexer - call
await indexer.start() - stop gracefully on
SIGTERMorSIGINT
Generated API Routes
If you want a read API over indexed rows,@thru/indexer can mount generated routes into a Hono app: