v3.5.0
Factories with Billions of Addresses
Previously, HyperIndex began to struggle when handling 8 million addresses. With this release, we have removed this limitation—now the number of supported addresses is virtually unlimited, constrained only by your available resources.
We achieved this by making HyperIndex automatically switch from server-side to client-side filtering, which drastically reduces the number of queries sent. Additionally, a partial Rust rewrite optimizes resource usage during event processing.
By @DZakh in #1483, #1490, #1493
Deferred Postgres Index Creation
This change led to a 2.5x backfill speedup for some users:
Previously, Postgres indexes defined in schema.graphql were created upfront, which could cause significant write backpressure. In this version, indexes are created just before entering realtime indexing after the backfill is complete. Additionally, when a handler makes a getWhere call, HyperIndex will automatically generate an index for the required field—so you no longer need to define these indexes in schema.graphql. Now, indexes defined in schema.graphql are specifically for your production GraphQL server 👍
Bottleneck Observability
We've expanded our Prometheus metrics suite to more precisely identify where bottlenecks occur:
envio_processing_stalled_on_fetch_seconds— Time spent idle with an empty buffer, waiting for events to be fetchedenvio_processing_stalled_on_storage_write_seconds— Time spent idle due to write backpressure
Combined with the existing counters, these metrics provide a comprehensive view of indexer performance. For more details, refer to the Production Observability guide: https://docs.envio.dev/docs/HyperIndex/observability.
We've also added several utility metrics to make each metrics scrape self-describing—useful for monitoring tools and AI agents:
envio_process_start_time_seconds— Indexer run start time (now surfaced at the top; otherwise unchanged)envio_process_metric_time_seconds— Timestamp when the metrics snapshot was generatedenvio_process_elapsed_seconds— Elapsed seconds since start
The elapsed metric allows you to easily interpret counter values from a single payload—no need for rate() or an external clock. For example, envio_processing_stalled_on_storage_write_seconds / envio_process_elapsed_seconds yields the fraction of the run spent stalled on writes.
Numeric (Int/BigInt) Entity IDs
You can now use Int or BigInt as the id type for entities in schema.graphql. Relationship fields will be correctly inferred, and handler types will be generated as number.
type Chain {
id: Int! # Numeric entity ID
vaults: [Vault!]! @derivedFrom(field: "chain")
}
type Vault {
id: ID!
chain: Chain! # Stored as chain_id (Int)
// ...
}Support Chain IDs Above 2^31
Added for a Tron Testnet user and beneficial for other chains as well.
If your config includes a chain with an ID greater than 2^31, HyperIndex now automatically uses larger database types to support these values.
Other Changes
- Fixed handlers for entities with lowercase name by @DZakh in #1479
- Upgrade TypeScript target to ES2023 for
envio inittemplates by @DZakh in #1497 - Skip ClickHouse-only entities on reorg rollback. Note: This might lead to invalid data, but at least there's not crash. Use mixed Postgres and ClickHouse entities for now for reliable data on reorgs. by @moose-code in #1514
- Suggest viem transport batching in external-calls skill by @DenhamPreen in #1520
Internal Improvements
- Consolidated TypeScript API type tests by @DZakh in #1480
- Improved end-to-end config parsing tests by @DZakh in #1484
- Added end-to-end user-facing indexer tests from config and source strings by @DZakh in #1488
- Preparations to generalize the internal test indexer by @DZakh in #1509
- Document testing strategy and development workflow by @DZakh in #1515
Full Changelog: v3.4.0...v3.5.0