Documentation
Production
Deploy

Deploy

You can deploy your Ponder app to any cloud environment that supports Node.js.

Railway

Railway's general-purpose cloud platform is a great starting point for most Ponder apps.

Log in to Railway

Connect your GitHub account, and make sure that your Ponder app has been pushed to remote.

Create a Ponder app service

From the Railway console:

  1. Click New ProjectDeploy from GitHub repo and select your repo from the list
  2. Click Add variables, then add RPC URLs (e.g. PONDER_RPC_URL_1) and other environment variables
  3. Create a public domain. In SettingsNetworking, click Generate Domain
  4. Set the healthcheck path and timeout. In SettingsDeploy, set the Healthcheck Path to /ready and the Healthcheck Timeout to 86400 seconds (1 day)
⚠️

Monorepo users: Configure the Root Directory and Start Command such that ponder start runs at the Ponder project root. For example, set the root directory to packages/ponder or set the start command to cd packages/ponder && pnpm start.

Create a Postgres database

From the new project dashboard:

  1. Click CreateDatabaseAdd PostgreSQL
  2. Open the Variables tab for the Ponder app service, click New VariableAdd Reference → select DATABASE_URL and click Add

After a moment, the Ponder app service should redeploy successfully. Check the Build Logs and Deploy Logs tabs to debug any issues.

Self hosting

In general, hosting a Ponder app is similar to hosting a normal Node.js HTTP server. Rather than offer a step-by-step guide, this section describes the key Ponder-specific quirks to consider when self-hosting.

Health checks & probes

Use the /health and /ready endpoints to configure health checks or probes.

  • /health: Returns an HTTP 200 response immediately after the process starts.
  • /ready: Returns an HTTP 200 response once indexing progress has reached realtime across all chains. During the historical backfill, the endpoint returns an HTTP 503 response.

Database connection

⚠️

You app will have performance issues if the roundtrip database latency exceeds ~20 milliseconds. This is common when using a database in different private network or region.

In production, Ponder works best with a Postgres database in the same private network. Set the DATABASE_URL environment variable to the connection string of your Postgres database, or manually override the database.connectionString option in ponder.config.ts.

ponder.config.ts
import { createConfig } from "@ponder/core";
 
export default createConfig({
  database: {
    kind: "postgres",
    connectionString: "postgres://user:password@mycloud.internal:5432/database",
  },
  // ... more config
});

Table names and live views

When a Ponder app starts up, it creates a table in the database for each table exported from ponder.schema.ts. To avoid naming conflicts with prior instances of the same app, the tables are prefixed with a random four-character instance_id.

When the app finishes the historical backfill (or immediately after startup when using ponder dev) it creates a view for each table in ponder.schema.ts using this command.

CREATE VIEW {table_name} AS ( SELECT * FROM {instance_id}__{table_name} );

The live view mechanism is essential for zero-downtime deployments, horizontal scaling, and direct SQL queries.

Example

Here's a zero-downtime redeployment scenario, where views continously serve data from the most recent instance to go live.

  1. App 1234 starts up. It creates and begins writing to a table named 1234__account.
  2. App 1234 completes the historical backfill. It creates a view named account that points at 1234__account.
  3. App 5678 starts up. It creates and begins writing to a table named 5678__account.
  4. App 5678 completes the historical backfill. It updates the account view to point at 5678__account.
  5. App 1234 shuts down.
  6. App 5678 continues to serve live data via the account view.

Crash recovery

If a Ponder app running ponder start crashes and restarts, it will attempt to resume indexing where it left off. Read more about the instance lifecycle and crash recovery mechanism.