Back to Rivet

PostgreSQL

website/src/content/docs/self-hosting/postgres.mdx

2.2.15.9 KB
Original Source
<Warning> PostgreSQL is the recommended backend for multi-node self-hosted deployments today, but it remains experimental. For a production-ready single-node Rivet deployment, use the file system backend (RocksDB-based). Enterprise teams can contact [enterprise support](https://rivet.dev/sales) about FoundationDB for the most scalable production-ready deployment. </Warning>

Basic Configuration

<CodeGroup>
json
{
  "database": {
    "postgres": {
      "url": "postgresql://user:password@host:5432/database"
    }
  }
}
bash
RIVET__database__postgres__url="postgresql://user:password@host:5432/database"
</CodeGroup>

Managed Postgres Compatibility

Some hosted PostgreSQL platforms require additional configuration due to platform-specific restrictions.

<Tabs> <Tab title="PlanetScale">

Use direct connection (not connection pooler).

<CodeGroup>
json
{
  "database": {
    "postgres": {
      "url": "postgresql://pscale_api_<username>.<unique-id>:<password>@<region>.pg.psdb.cloud:5432/postgres?sslmode=require",
      "unstable_disable_lock_customization": true
    }
  }
}
bash
RIVET__database__postgres__url="postgresql://pscale_api_<username>.<unique-id>:<password>@<region>.pg.psdb.cloud:5432/postgres?sslmode=require"
RIVET__database__postgres__unstable_disable_lock_customization=true
</CodeGroup> </Tab> <Tab title="Supabase">

Use direct connection on port 5432 (not connection pooler).

Without SSL

<CodeGroup>
json
{
  "database": {
    "postgres": {
      "url": "postgresql://postgres:<password>@db.<project-ref>.supabase.co:5432/postgres?sslmode=disable",
      "unstable_disable_lock_customization": true
    }
  }
}
bash
RIVET__database__postgres__url="postgresql://postgres:<password>@db.<project-ref>.supabase.co:5432/postgres?sslmode=disable"
RIVET__database__postgres__unstable_disable_lock_customization=true
</CodeGroup>

With SSL

Download the root certificate from your Supabase dashboard and specify its path. See Supabase SSL Enforcement for details.

<CodeGroup>
json
{
  "database": {
    "postgres": {
      "url": "postgresql://postgres:<password>@db.<project-ref>.supabase.co:5432/postgres?sslmode=require",
      "unstable_disable_lock_customization": true,
      "ssl": {
        "root_cert_path": "/path/to/supabase-ca.crt"
      }
    }
  }
}
bash
RIVET__database__postgres__url="postgresql://postgres:<password>@db.<project-ref>.supabase.co:5432/postgres?sslmode=require"
RIVET__database__postgres__unstable_disable_lock_customization=true
RIVET__database__postgres__ssl__root_cert_path="/path/to/supabase-ca.crt"
</CodeGroup> </Tab> </Tabs>

SSL/TLS Support

To enable SSL for Postgres, add sslmode=require to your PostgreSQL connection URL:

<CodeGroup>
json
{
  "database": {
    "postgres": {
      "url": "postgresql://user:[email protected]:5432/database?sslmode=require"
    }
  }
}
bash
RIVET__database__postgres__url="postgresql://user:[email protected]:5432/database?sslmode=require"
</CodeGroup>

The sslmode parameter controls TLS usage:

  • disable: Do not use TLS
  • prefer: Use TLS if available, otherwise connect without TLS (default)
  • require: Require TLS connection (fails if TLS is not available)

To verify the server certificate against a CA or verify the hostname, use custom SSL certificates (see below).

Custom SSL Certificates

For databases using custom certificate authorities (e.g., Supabase) or requiring client certificate authentication, you can specify certificate paths in the configuration:

<CodeGroup>
json
{
  "database": {
    "postgres": {
      "url": "postgresql://user:password@host:5432/database?sslmode=require",
      "ssl": {
        "root_cert_path": "/path/to/root-ca.crt",
        "client_cert_path": "/path/to/client.crt",
        "client_key_path": "/path/to/client.key"
      }
    }
  }
}
bash
RIVET__database__postgres__url="postgresql://user:password@host:5432/database?sslmode=require"
RIVET__database__postgres__ssl__root_cert_path="/path/to/root-ca.crt"
RIVET__database__postgres__ssl__client_cert_path="/path/to/client.crt"
RIVET__database__postgres__ssl__client_key_path="/path/to/client.key"
</CodeGroup>
ParameterDescriptionPostgreSQL Equivalent
root_cert_pathPath to the root certificate file for verifying the server's certificatesslrootcert
client_cert_pathPath to the client certificate file for client certificate authenticationsslcert
client_key_pathPath to the client private key file for client certificate authenticationsslkey

All SSL paths are optional. If not specified, Rivet uses the default system root certificates from Mozilla's root certificate store.

Do Not Use Connection Poolers

Rivet requires direct PostgreSQL connections for session-level features and does not support connection poolers.

Do not use:

  • PgBouncer
  • Supavisor
  • AWS RDS Proxy

Troubleshooting

Permission Denied Errors

If you see errors like:

ERROR: permission denied to set parameter "deadlock_timeout"
ERROR: current transaction is aborted, commands ignored until end of transaction block

Add unstable_disable_lock_customization: true to your configuration:

json
{
  "database": {
    "postgres": {
      "url": "postgresql://...",
      "unstable_disable_lock_customization": true
    }
  }
}

This disables Rivet's attempt to set lock_timeout = 0 and deadlock_timeout = 10ms. Since lock_timeout defaults to 0 in PostgreSQL, skipping these settings is safe. Deadlock detection will use the default 1s timeout instead of 10ms.