Skip to main content
Batch data processing model employed by Squid SDK relies on the following principles:
  • Minimize the number of database hits by grouping multiple single-row transactions into multi-row batch transactions.
  • Transform the data in memory using vectorized operators.
  • Use the MakerDAO Multicall contract to batch EVM state queries.
  • Use XXX.getMany() to batch Substrate state queries.
In practice, batching is a more flexible (compared to handler parallelization) way to speed up the inherently sequential indexing of on-chain transactions and logs. To illustrate, assume the processor must infer the current state of an on-chain record. It is configured to listen to the two on-chain events, Create and Update, that are emitted once the record is created or updated. The data batch received by the processor is then an array of event items, i.e.
Following the principles above, a processor would update the intermediary entity states in memory, persisting only the final state:
in a single transaction. Let’s see the batch processing principles in action.

Patterns

An idiomatic use of processor.run() is as follows:
For a full implementation of the above pattern, see EVM squid example or Substrate squid example.

Anti-patterns

Avoid loading or persisting single entities unless strictly necessary. For example, here is a possible antipattern for the Gravatar example:
Instead, use an in-memory cache, and batch upserts:

Migrate from handlers

Batch-based processing can be used as a drop-in replacement for the handler-based mappings employed by e.g. subgraphs. While the handler-based processing is significantly slower due to excessive database lookups and writes, it may be a good intermediary step while migrating an existing subgraph to Squid SDK. One can simply re-use the existing handlers while looping over the ctx items:

Block hooks

Similarly, one can implement pre- and post- block hooks: