Skip to content
PostRESP
Esc
navigateopen⌘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 PG_RESP_PORT

Environment variables override the JSON file when set. Typical Docker installs ship a config that listens on 0.0.0.0:6379 and connects to Postgres as redis / redis / pg_resp.

Prefix rules

  1. Product / RESP endpointPG_RESP_
    Settings that belong to the Redis-facing gateway (listen port, storage mode).
  2. PostgreSQL backendPOSTGRESQL_
    Host, port, and database the gateway uses to reach Postgres.
  3. Auth — unprefixed USERNAME / PASSWORD
    Postgres role the gateway uses for SQL. Redis AUTH verifies against the same roles. Wire auth is required by default; set REQUIRE_CLIENT_AUTH=false to allow unauthenticated clients. See Authentication.
  4. Behavior flags — plain verbs, no product prefix when they are not product-specific: REQUIRE_POSTGRES, REQUIRE_CLIENT_AUTH, ALLOW_EXTERNAL_CONNECTIONS, ASYNC_RUNTIME_WORKER_THREADS.
  5. Do not invent aliases. One name per setting.

Environment ↔ JSON map

Environment JSON field Default
PG_RESP_PORT GatewayListenPort 6379
PG_RESP_STORAGE_MODE StorageMode (unlogged | logged) unlogged
POSTGRESQL_HOST PostgresHostName 127.0.0.1
POSTGRESQL_PORT PostgresPort 5432
POSTGRESQL_DATABASE PostgresDatabase pg_resp
USERNAME PostgresSystemUser redis
PASSWORD PostgresPassword redis
REQUIRE_POSTGRES RequirePostgres unset / false
REQUIRE_CLIENT_AUTH RequireClientAuth true
ALLOW_EXTERNAL_CONNECTIONS inverts UseLocalHost unset
ASYNC_RUNTIME_WORKER_THREADS AsyncRuntimeWorkerThreads 2

Booleans accept 1 / true / yes (and 0 / false / no).

# Example: listen on 6380 and point at a non-default Postgres port
PG_RESP_PORT=6380 POSTGRESQL_PORT=5433

Example config file

{
  "GatewayListenPort": 6379,
  "UseLocalHost": false,
  "PostgresHostName": "127.0.0.1",
  "PostgresPort": 5432,
  "PostgresDatabase": "pg_resp",
  "PostgresSystemUser": "redis",
  "PostgresPassword": "redis",
  "RequirePostgres": true,
  "RequireClientAuth": true,
  "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 = 'pg_resp'
redis_gateway.setup_configuration_file = '/etc/pg_resp/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 make postgres-up 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

These are not gateway config names; do not reuse them as new public APIs:

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

Was this page helpful?