DocsConfiguration

Configuration

All environment variables and configuration options for Postrust.

Database

VariableRequiredDefaultDescription
DATABASE_URLYes-PostgreSQL connection string
PGRST_DB_SCHEMASNopublicSchemas to expose (comma-separated)
PGRST_DB_ANON_ROLENo-Role for unauthenticated requests
PGRST_DB_POOL_SIZENo10Connection pool size

Authentication

VariableRequiredDefaultDescription
PGRST_JWT_SECRETNo-JWT signing secret
PGRST_JWT_SECRET_IS_BASE64NofalseIf secret is base64 encoded
PGRST_JWT_AUDNo-Required JWT audience claim
PGRST_JWT_ROLE_CLAIM_KEYNoroleClaim key for role

Server

VariableRequiredDefaultDescription
PGRST_SERVER_HOSTNo127.0.0.1Bind address
PGRST_SERVER_PORTNo3000Port to listen on
PGRST_SERVER_CORS_ORIGINSNo*CORS allowed origins

Limits

VariableRequiredDefaultDescription
PGRST_MAX_ROWSNounlimitedMaximum rows returned by one request; caps requests with no limit
PGRST_MAX_BODY_SIZENo10485760Max request body in bytes

Compatibility

VariableRequiredDefaultDescription
PGRST_COMPAT_MODENofalsePostgREST compatibility mode: serves the REST API at the root (/rpc/fn, /table) in addition to /api, and un-wraps RPC responses to PostgREST's shape. Object key order is a build-time choice, not covered by this setting - see below. Alias: POSTRUST_COMPAT_MODE

Logging

VariableRequiredDefaultDescription
PGRST_LOG_LEVELNoinfoLog level (error, warn, info, debug)
RUST_LOGNo-Detailed tracing configuration

Key ordering is a build-time choice

Postrust returns the keys within each object alphabetically. PostgREST returns them in the order of the select list. That difference is decided when the binary is compiled rather than at run time, because it depends on the map type holding a JSON object, so PGRST_COMPAT_MODE cannot switch it on. It is a Cargo feature:

Terminal
cargo build --release -p postrust-server --features compat-key-order

# Default build
curl 'localhost:3000/api/users?select=status,name,id&limit=1'
# -> [{"id":1,"name":"Alice","status":"active"}]

# With compat-key-order
curl 'localhost:3000/api/users?select=status,name,id&limit=1'
# -> [{"status":"active","name":"Alice","id":1}]

It is off by default because it is not free. Measured by running both builds as containers against the same database and alternating between them, a three-column response cost 1% and an eight-column response 15%: for objects this small a few short string comparisons beat hashing every key, so the sorted map is genuinely the faster one. Turn it on when byte-level compatibility matters more.

Running with PGRST_COMPAT_MODE=true on a binary built without the feature logs a warning at startup, so the difference is not left to be found by diffing responses.

Example Configuration

.env
# Required
DATABASE_URL=postgres://user:password@localhost:5432/mydb

# Authentication
PGRST_DB_ANON_ROLE=web_anon
PGRST_JWT_SECRET=your-secret-key-at-least-32-characters

# Server
PGRST_SERVER_HOST=0.0.0.0
PGRST_SERVER_PORT=3000
PGRST_SERVER_CORS_ORIGINS=https://myapp.com

# Limits
PGRST_MAX_ROWS=100
PGRST_LOG_LEVEL=info