← Protocols
Ponder
01Description

Open-source TypeScript framework for EVM data indexing. Define contracts in `ponder.config.ts`, schema in `ponder.schema.ts`, and indexing functions that write to a Postgres-backed store; serves a GraphQL and SQL API and runs anywhere Node runs.

02Best for
  • 01self-hosted EVM indexers
  • 02type-safe indexing functions in TypeScript
  • 03custom GraphQL + SQL APIs from one codebase
  • 04local-first development with hot reload
  • 05subgraph replacements with viem ergonomics
03Install
  • pnpm create ponder@latest
  • pnpm add ponder
04Environment variables
VariableScopeDescription
PONDER_RPC_URL_1ServerRPC URL for chainId 1 (Ethereum mainnet). Ponder reads `PONDER_RPC_URL_<chainId>` for each network defined in `ponder.config.ts`. Use a paid provider — public endpoints will rate-limit.
DATABASE_URLServerPostgres connection string for production deployments. SQLite is used by default in dev.
05Prompt snippet
Bootstrap with `pnpm create ponder@latest`. In `ponder.config.ts` define networks (`mainnet: { chainId: 1, transport: http(process.env.PONDER_RPC_URL_1) }`) and contracts with ABIs, addresses, and `startBlock`. In `ponder.schema.ts` use `onchainTable('account', t => ({ address: t.hex().primaryKey(), balance: t.bigint().notNull() }))`. Write indexing functions in `src/index.ts`: `ponder.on('ERC20:Transfer', async ({ event, context }) => { await context.db.insert(account).values({ address: event.args.to, balance: 0n }).onConflictDoUpdate(...) })`. Run `pnpm dev` (hot reload) then deploy. Query the auto-generated `/graphql` and `/sql` endpoints, or add custom routes in `src/api/index.ts` using the provided viem `context.client`.
06Gotchas
  • Free public RPC endpoints will rate-limit a Ponder backfill within minutes — use a paid provider (Alchemy, QuickNode, Ankr) for `PONDER_RPC_URL_<chainId>` or Ponder will stall and retry forever.
  • Indexing functions are NOT parallelized across events for a single contract — heavy on-chain reads (`context.client.readContract`) inside handlers are the #1 cause of slow backfills; cache or move to a precomputed table.
  • Schema drift: changing `ponder.schema.ts` requires a fresh database in dev (`pnpm ponder dev` auto-resets); in production use the migration system or you'll deploy a broken indexer.
  • Reorg handling is automatic up to the configured depth, but if your handler triggers external side effects (webhooks, emails) you must guard against re-execution after reorgs.
  • Ponder is EVM-only — Solana, Sui, Aptos, Bitcoin are out of scope; pick a different indexer for non-EVM chains.
07Alternatives