Storage modes
Choose unlogged or logged mode for durability and throughput trade-offs.
PostRESP supports two storage modes. The same modes work for both the in-process gateway and the standalone service.
| Mode | Backing | Restart | Crash | Role |
|---|---|---|---|---|
| unlogged (default) | Postgres UNLOGGED tables |
Preserved after clean restart | Table may be truncated; not replicated | Single-instance only |
| logged | Normal Postgres tables | Preserved | Recovered through WAL; replicable | Crash recovery / HA via Postgres |
HA and clustering
The Docker image and default unlogged mode are for a single Postgres
instance. They are not an HA topology.
unlogged does not work in a replicated cluster. Postgres UNLOGGED
tables skip table WAL, so changes are not shipped by physical streaming
replication or logical replication. After failover or on a standby, replicas
will not have those keys (and a crash on the primary can truncate the
unlogged heaps). Use logged whenever you need Postgres-level HA,
standbys, or logical subscribers.
| Goal | Mode | Notes |
|---|---|---|
| Local / Docker / demos | unlogged (default) |
Fast shared SQL storage; no replica story |
| Crash recovery, streaming HA, logical replication | logged |
Data follows normal Postgres WAL / publications |
HA for PostRESP means Postgres is the cluster (primary + standbys, operator
failover, one write endpoint) — not Redis Cluster hash slots or multi-primary
RESP. Pub/Sub delivery is still process-local today: multiple RESP gateway
processes against one DB do not share live subscriptions until a cross-process
bus lands (see Commands › Pub/Sub). Practical constraints
when you do run logged on a primary/standby setup:
- Serve RESP (and schedule
pg_cronTTL jobs) on the primary only; standbys are recovery and do not run those writers until promoted. - Point clients at a stable primary endpoint (k8s Service, Patroni / CloudNativePG VIP, etc.).
- Do not put
cron.*job metadata into a logical publication that would make two writable nodes both execute the same sweeper.
Configuring the mode
Set via StorageMode in SetupConfiguration.json or the
PG_RESP_STORAGE_MODE environment variable:
{
"StorageMode": "unlogged"
}
PG_RESP_STORAGE_MODE=logged
SQL helpers pgresp.storage_mode() /
pgresp.set_storage_mode('logged'|'unlogged') change table persistence.
Memory cache after restart
After a Postgres restart, its in-memory table cache starts empty. Docker /
compose enable pg_prewarm autoprewarm by default so recently used
pgresp.* data is loaded back after restart. Details, disable switch, and
manual pgresp.prewarm(): Buffer cache prewarm.
TTL / expiry
TTL uses both lazy and active purge:
- Lazy — expiry checked on read/write paths.
- Active — a
pg_cronjob periodically deletes expired keys.
Active expiry is intentionally naive today (not Redis-style random sampling). Details and tunable GUCs live under Commands › TTL and Configuration.