# How the Akash Console Indexer Service Powers Real-Time Blockchain Data

> Explore how the Akash Console Indexer service transforms raw blockchain data into structured tables, powering real-time UI functionality with schema management and caching.

- Repository: [Akash Network/console](https://github.com/akash-network/console)
- Tags: internals
- Published: 2026-02-24

---

**The Indexer service transforms raw Akash blockchain data into structured, queryable database tables that fuel the Akash Console UI, handling schema management, message routing, per-block hooks, and in-memory caching.**

The **Indexer service** serves as the data ingestion engine for the `akash-network/console` repository, continuously processing on-chain events and materializing them into relational tables. Without this service, the Console's dashboards and explorer views would lack the real-time validator, deployment, and provider statistics users rely on. By implementing a pluggable architecture around an abstract `Indexer` base class, the system enables modular data extraction tailored to specific Akash message types.

## Core Responsibilities of the Indexer Service

The Indexer service operates through four primary functional areas, each implemented via specific methods in the abstract base class defined in [`apps/indexer/src/indexers/indexer.ts`](https://github.com/akash-network/console/blob/main/apps/indexer/src/indexers/indexer.ts).

### Database Schema Management

Each concrete indexer manages its own database tables through lifecycle methods that handle creation, destruction, and seeding. The abstract `Indexer` class requires implementations to define `createTables`, `dropTables`, and `seed` methods. For example, the `ValidatorIndexer`, `MessageAddressesIndexer`, and `AkashStatsIndexer` all override these methods to establish tables for validators, address references, and aggregate statistics respectively.

### Message Dispatch and Routing

When the system processes a block, decoded protobuf messages route through the `processMessage` method. This method checks the `msgHandlers` map—populated by each concrete indexer during initialization—to find the appropriate handler for the message type. The handler executes within a benchmark timer, ensuring performance metrics are captured for every processed message.

### Per-Block and Per-Transaction Hooks

Beyond individual message handling, the Indexer service supports lifecycle hooks for broader coordination. Abstract methods `afterEveryTransaction` and `afterEveryBlock` allow indexers to execute logic after each transaction or block completion. The `StatsProcessor` iterates over the `activeIndexers` array and invokes these hooks, enabling operations like account settlement, stats updates, and signer address persistence across all registered indexers.

### Caching and Initialization

To prevent stale reads and optimize performance, the Indexer service implements an in-memory caching layer. The `StatsProcessor` calls `initCache` on each indexer once per run, storing the first unprocessed block height. This initialization sequence ensures that indexers can recover gracefully from failures and resume processing from the correct chain position without re-scanning historical data.

## Orchestration via StatsProcessor

The **StatsProcessor** in [`apps/indexer/src/chain/statsProcessor.ts`](https://github.com/akash-network/console/blob/main/apps/indexer/src/chain/statsProcessor.ts) orchestrates the Indexer service by managing the flow of blockchain data from raw blocks to persistent storage. This processor handles four critical operations:

1. **Table Rebuilding**: The `rebuildStatsTables` method drops and recreates all stats tables, seeds genesis data, and triggers a full reprocessing of the blockchain—functionality exposed through the Console's "re-sync" UI button.
2. **Block Grouping**: The processor queries for unprocessed blocks, groups them efficiently, and fetches raw block data using `getCachedBlockByHeight`.
3. **Message Processing**: For each block, the processor iterates through transactions and messages, decodes protobuf payloads, and dispatches them to the appropriate indexer handlers via `processMessage`.
4. **Atomic Commits**: The system wraps each block group in a single Sequelize transaction, ensuring that either all indexers persist their updates successfully or the entire batch rolls back to maintain data consistency.

## Built-In Indexer Implementations

The [`apps/indexer/src/indexers/index.ts`](https://github.com/akash-network/console/blob/main/apps/indexer/src/indexers/index.ts) file instantiates concrete indexers and filters them based on the active chain configuration (`activeChain.customIndexers`). The resulting `activeIndexers` array determines which processors the `StatsProcessor` invokes for every block.

### ValidatorIndexer

Defined in [`apps/indexer/src/indexers/validatorIndexer.ts`](https://github.com/akash-network/console/blob/main/apps/indexer/src/indexers/validatorIndexer.ts), this indexer tracks validator metadata including creation events and edit transactions. It persists structured validator data to the `Validator` table, enabling the Console's validator explorer and staking interfaces.

### MessageAddressesIndexer

Located in [`apps/indexer/src/indexers/messageAddressesIndexer.ts`](https://github.com/akash-network/console/blob/main/apps/indexer/src/indexers/messageAddressesIndexer.ts), this component extracts sender and receiver addresses from bank-related messages. It also records signer addresses for each transaction, populating the `AddressReference` table to support address-based queries and transaction history views.

### AkashStatsIndexer

The [`apps/indexer/src/indexers/akashStatsIndexer.ts`](https://github.com/akash-network/console/blob/main/apps/indexer/src/indexers/akashStatsIndexer.ts) implementation aggregates deployment, lease, provider, and pricing statistics. It maintains active-lease predictions and counters that power the Console's dashboard analytics, providing real-time insights into network utilization and resource pricing.

## Working with the Indexer Service

Developers interacting with the Akash Console codebase can leverage the Indexer service for both maintenance operations and custom data extraction.

### Rebuilding Statistics Tables

To perform a full re-sync of blockchain data—useful after schema changes or data corruption—invoke the rebuild method:

```typescript
import { statsProcessor } from '@src/chain/statsProcessor';

// Re‑create all tables and seed genesis data, then reprocess every block.
await statsProcessor.rebuildStatsTables();

```

### Processing New Blocks

Background workers periodically call the processing method to catch up with the latest chain state:

```typescript
import { statsProcessor } from '@src/chain/statsProcessor';

// Called periodically (e.g. every few seconds) to catch up with the chain.
await statsProcessor.processMessages();

```

### Creating a Custom Indexer

To extend the system with new message handling capabilities, extend the abstract `Indexer` class and register the implementation:

```typescript
import { Indexer } from '@src/indexers/indexer';

export class MyCustomIndexer extends Indexer {
  constructor() {
    super();
    this.name = 'MyCustomIndexer';
    this.runForEveryBlocks = false;
    this.msgHandlers = {
      '/my.chain.MsgDoSomething': this.handleDoSomething,
    };
  }

  async createTables() { /* … */ }
  async dropTables()   { /* … */ }
  async seed()         { /* … */ }

  private async handleDoSomething(decoded, height, tx, msg) {
    // custom DB logic here
  }
}

```

After implementing the class, register it in [`apps/indexer/src/indexers/index.ts`](https://github.com/akash-network/console/blob/main/apps/indexer/src/indexers/index.ts) and add it to the `activeChain.customIndexers` array to automatically participate in block processing.

## Summary

- The **Indexer service** converts raw blockchain data into structured database tables, powering the Akash Console's real-time UI components.
- **Schema management**, **message dispatch**, **lifecycle hooks**, and **caching** form the four pillars of the indexing architecture implemented in the abstract `Indexer` base class.
- **StatsProcessor** orchestrates all indexers, handling block grouping, message decoding, and atomic transaction commits.
- **Built-in indexers** cover validators (`ValidatorIndexer`), address references (`MessageAddressesIndexer`), and network statistics (`AkashStatsIndexer`).
- The **pluggable architecture** allows developers to add custom indexers by extending the base class and registering new handlers for specific protobuf message types.

## Frequently Asked Questions

### What is the primary function of the Indexer service in Akash Console?

The Indexer service ingests raw blockchain data from the Akash network, decodes protobuf messages, and materializes them into relational database tables. This process enables the Console UI to query real-time information about validators, deployments, leases, and providers without directly accessing the blockchain for every request.

### How does StatsProcessor coordinate multiple indexers simultaneously?

The `StatsProcessor` maintains an `activeIndexers` array and iterates through it for every processed block and transaction. It calls `processMessage` for message handling, `afterEveryTransaction` post-transaction completion, and `afterEveryBlock` after each block, ensuring all registered indexers stay synchronized while wrapping operations in atomic database transactions.

### What types of blockchain data do the built-in indexers handle?

The `ValidatorIndexer` processes validator creation and edit events, the `MessageAddressesIndexer` extracts sender, receiver, and signer addresses from financial transactions, and the `AkashStatsIndexer` aggregates deployment metrics, lease statistics, provider data, and pricing information used for dashboard analytics.

### How can developers extend the Indexer service with custom logic?

Developers create a new class extending the abstract `Indexer` base class in [`apps/indexer/src/indexers/indexer.ts`](https://github.com/akash-network/console/blob/main/apps/indexer/src/indexers/indexer.ts), implementing required methods like `createTables`, `dropTables`, and `seed`, plus message handlers in the `msgHandlers` map. After registering the indexer in [`apps/indexer/src/indexers/index.ts`](https://github.com/akash-network/console/blob/main/apps/indexer/src/indexers/index.ts) and adding it to the chain configuration, the `StatsProcessor` automatically includes it in the block processing pipeline.