Setup
To index multiple chains, run one processor per source network:1. Create separate entry points
Make a separate entry point (main.ts or equivalent) for each processor:
Alternatively, parameterize your processor using environment variables. You
can set these on a per-processor basis
if you use a deployment manifest.
2. Configure processor commands
Addsqd commands for running each processor to commands.json:
commands.json
See the full
example
in the multichain transfers repository.
3. Configure deployment manifest
If you plan to usesqd run for local runs or deploy to SQD Cloud, list your processors in the deploy.processor section of your deployment manifest:
squid.yaml
PostgreSQL Configuration
When using PostgreSQL, ensure the following:1. Unique state schema for each processor
Each processor needs its own state schema to track sync progress independently:src/bsc/main.ts
src/eth/main.ts
State schemas track the sync progress of each processor independently,
enabling reliable multichain indexing.
2. Shared schema and API
The schema and GraphQL API should be shared among all processors to provide a unified data model. This setup keeps every chain in one shared schema: the entity tables are common to all processors, so a single GraphQL API serves the combined data. As discussed below, this can sometimes lead to write concurrency.For full isolation instead, give each processor its own
DB_SCHEMA — one Postgres schema per chain. The processors’ tables never overlap, which removes cross-chain write concurrency entirely, and each chain can also keep its state in the same schema (set stateSchema to the same value). The cost is on the serving side: an OpenReader instance reads a single DB_SCHEMA, so you expose one GraphQL API per chain (or add a stitching/gateway layer) rather than the unified API above. Choose shared schemas for a unified API, isolated schemas to avoid separating the data per-chain manually.Handling concurrency
-
Cross-chain data dependencies are to be avoided. With the default isolation level used by
TypeormDatabase,SERIALIZABLE, one of the processors will crash with an error whenever two cross-dependent transactions are submitted to the database simultaneously. It will write the correct data when restarted, but such restarts can impact performance, especially in squids that use many (>5) processors. -
The alternative isolation level is
READ COMMITTED. At this level data dependencies will not cause the processors to crash, but the execution is not guaranteed to be deterministic unless the sets of records that different processors read/write do not overlap. - To avoid cross-chain data dependencies, use per-chain records for volatile data. E.g. if you track account balances across multiple chains you can avoid overlaps by storing the balance for each chain in a different table row. When you need to combine the records (e.g. get a total of all balances across chains) use a custom resolver to do it on the GraphQL server side.
-
It is OK to use cross-chain entities to simplify aggregation. Just don’t store any data in them: