Skip to content
PostRESP
Esc
↑↓navigate↵open⌘Jpreview
On this page

Configuration

SetupConfiguration.json, environment overrides, GUCs, and naming rules.

Two layers, one vocabulary:

Layer Case Example
SetupConfiguration.json PascalCase GatewayListenPort
Environment overrides SCREAMING_SNAKE_CASE POSTRESP_PORT_NUMBER

Environment variables override the JSON file when set. Prefer POSTRESP_* in examples and docs; Redis/Valkey names are also accepted so you can merge an existing redis/valkey compose service onto the Postgres image. Typical Docker installs listen on 0.0.0.0:6379 and connect to Postgres as postresp / postresp / postgres.

Prefix rules

  1. PostRESP — POSTRESP_ (preferred; wins when set).
  2. Redis / Valkey — REDIS_* / VALKEY_* (+ ALLOW_EMPTY_PASSWORD).
  3. Official Postgres image — POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB for SQL init only (not RESP secret fallbacks).
  4. In-container Postgres dial — POSTGRESQL_HOST / POSTGRESQL_PORT; gateway database is POSTRESP_DATABASE (shares POSTGRES_DB by default).

Priority for overlapping redis-facing settings: PostRESP → Valkey → Redis. Empty values are ignored.

Environment ↔ JSON map

Preferred Also accepted JSON field Default
POSTRESP_PORT_NUMBER VALKEY_PORT_NUMBER, REDIS_PORT_NUMBER GatewayListenPort 6379
POSTRESP_ALLOW_REMOTE_CONNECTIONS VALKEY_ALLOW_REMOTE_CONNECTIONS, REDIS_ALLOW_REMOTE_CONNECTIONS inverts UseLocalHost unset (code: local; Docker JSON: remote on)
POSTRESP_PASSWORD VALKEY_PASSWORD, REDIS_PASSWORD, *_PASSWORD_FILE Password (RESP wire secret; not POSTGRES_PASSWORD) Docker: generate if unset; JSON: postresp
POSTRESP_USERNAME Username postresp
POSTRESP_DATABASE POSTRESP_POSTGRESQL_DATABASE, POSTGRESQL_DATABASE, POSTGRES_DB PostgresDatabase share POSTGRES_DB / postgres
POSTRESP_STORAGE_MODE StorageMode (unlogged | logged) unlogged
POSTRESP_REQUIRE_POSTGRES RequirePostgres unset / false
POSTRESP_ASYNC_RUNTIME_WORKER_THREADS AsyncRuntimeWorkerThreads 2
ALLOW_EMPTY_PASSWORD inverse of RequireClientAuth unset (RequireClientAuth=false)
POSTGRESQL_HOST POSTRESP_POSTGRESQL_HOST PostgresHostName 127.0.0.1 (Docker: unix socket)
POSTGRESQL_PORT POSTRESP_POSTGRESQL_PORT PostgresPort 5432

Booleans accept 1 / true / yes and 0 / false / no (POSTRESP_ALLOW_REMOTE_CONNECTIONS=true|false works).

Bind address: Rust defaults are loopback-only (UseLocalHost: true). The Docker image’s JSON sets UseLocalHost: false so -p 6379:6379 works. POSTRESP_ALLOW_REMOTE_CONNECTIONS=false forces loopback.

Wire auth: off by default (RequireClientAuth: false). Enable with RequireClientAuth: true in JSON or ALLOW_EMPTY_PASSWORD=no (env alone). ALLOW_EMPTY_PASSWORD=yes forces auth off even when JSON has RequireClientAuth: true. On Docker, unset password → random secret on first start (see Authentication). Standalone JSON still defaults to Password: postresp — do not enable wire auth with that value.

Database: same as the official Postgres image — postgres when POSTGRES_DB is unset (schema pgresp). Override with POSTRESP_DATABASE only when you need a separate database.

POSTRESP_PORT_NUMBER=6380
POSTRESP_PASSWORD=secret
POSTRESP_ALLOW_REMOTE_CONNECTIONS=true
POSTGRESQL_PORT=5433

Example config file

{
  "GatewayListenPort": 6379,
  "UseLocalHost": false,
  "PostgresHostName": "/var/run/postgresql",
  "PostgresPort": 5432,
  "PostgresDatabase": "postgres",
  "Username": "postresp",
  "Password": "postresp",
  "RequirePostgres": true,
  "RequireClientAuth": false,
  "StorageMode": "unlogged",
  "AsyncRuntimeWorkerThreads": 2
}

Point Postgres at the file with:

shared_preload_libraries = 'pg_cron,pg_resp_gw_host,pg_prewarm'
pg_prewarm.autoprewarm = on
redis_gateway.database = 'postgres'
redis_gateway.setup_configuration_file = '/etc/postresp/SetupConfiguration.json'

GUCs

In-process host GUCs (require shared_preload_libraries including pg_resp_gw_host):

  • redis_gateway.database
  • redis_gateway.setup_configuration_file
  • pg_resp.ttl_delete_batch_size (default 1000) — SQL TTL sweeper keys/round
  • pg_resp.ttl_delete_max_rounds (default 10) — rounds per delete_expired_keys call

Tune the TTL pair with ALTER SYSTEM / postgresql.conf + pg_reload_conf(), or SET before a manual CALL pgresp.delete_expired_keys().

pg_cron

pg_cron is a Postgres extension that runs scheduled SQL. PostRESP uses it for active TTL expiry: job pg_resp_ttl_task calls pgresp.delete_expired_keys() once a minute.

Docker / compose preload pg_cron and set cron.database_name to the product database. Init creates the extension; CREATE EXTENSION pg_resp schedules the job when pg_cron is present.

Setting Role
shared_preload_libraries includes pg_cron Required for the scheduler
cron.database_name Database where the job runs (must match where you create extensions)

Lazy expiry on read/write still works without pg_cron; without it, expired keys are only removed when touched. Batch size for the sweeper is controlled by the pg_resp.ttl_delete_* settings above — see Commands › TTL.

pg_prewarm

pg_prewarm ships with a standard PostgreSQL install. Docker / compose preload it and leave autoprewarm on by default (see Buffer cache prewarm):

Setting Default Meaning
pg_prewarm.autoprewarm on Remember and reload recently cached table pages across restarts
pg_prewarm.autoprewarm_interval 300s How often to save that page list

Compose convenience (maps to the setting above; not a gateway JSON field):

Environment Effect Default
PG_PREWARM_AUTOPREWARM on | off for pg_prewarm.autoprewarm on

Postgres server settings are a separate surface from gateway env/JSON — prefer the names in postgresql.conf. The compose variable above exists only so compose can toggle autoprewarm without editing the command array.

Memory and buffer cache

Keys live in Postgres heaps and indexes (pgresp.*), not in a dedicated in-process Redis dict. The full keyspace does not need to fit in RAM — only the hot working set should, via shared_buffers and the OS page cache. Cold keys stay on disk until read.

Knob Where Guidance
shared_buffers postgresql.conf Size for the hot set you want resident, not the whole dataset. Default Docker images leave Postgres defaults; raise this when steady-state GET latency matters and the working set is larger than the default.
OS page cache host / VM RAM Postgres relies on the OS to cache table pages beyond shared_buffers. Leave headroom so the kernel can hold warm pgresp.* pages.
pg_prewarm.autoprewarm see above Reloads the previous hot set after restart so you are not starting from an empty cache.
StorageMode gateway env/JSON unlogged vs logged changes WAL and crash behavior (Storage modes); it does not change the dual-table encoding size.
AsyncRuntimeWorkerThreads gateway env/JSON Caps gateway async workers (default 2). Raise only if CPU is idle under concurrent RESP load; storage still dominates SET cost — see Benchmarks.

Disk vs Redis RAM. Tiny string keys are stored twice in spirit (registry row in keys + payload in strings) plus btree indexes, so on-disk bytes per key are typically higher than Redis/used_memory for the same logical shape. That is expected: you trade denser always-RAM encoding for SQL visibility and datasets larger than memory. Do not compare Redis INFO memory to Postgres process RSS — Postgres always carries shared buffers, catalogs, and backends.

Measure schema size when capacity-planning disk:

SELECT pg_size_pretty(SUM(pg_total_relation_size(c.oid))) AS pgresp_total
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'pgresp' AND c.relkind = 'r';

Container / image exceptions

  • POSTGRES_USER — SQL superuser only (default postgres); never the RESP role
  • POSTGRES_PASSWORD / POSTGRES_DB — official Postgres image init only
  • PGPORT — libpq default port inside the container (set from POSTGRESQL_PORT)
  • PG_PREWARM_AUTOPREWARM — compose → pg_prewarm.autoprewarm only (see above)

VALKEY_* / REDIS_* / ALLOW_EMPTY_PASSWORD are accepted Redis/Valkey aliases. Persist data on the Postgres volume (/var/lib/postgresql); there is no separate Redis data directory.

Was this page helpful?