Storage modes
Choose unlogged, logged, or memory mode for durability and throughput trade-offs.
pg_redis supports three storage modes. The same modes work for both the
embedded BGWorker and the standalone gateway — they share
redis_gateway_core::run_gateway.
| Mode | Backing | Restart | Crash | Role |
|---|---|---|---|---|
| unlogged (default) | Postgres UNLOGGED tables |
Preserved after clean restart | Table may be truncated | Preferred production default |
| logged | Normal Postgres tables | Preserved | Recovered through WAL | When you need crash recovery |
| memory | In-gateway map | Lost unless snapshot landed | Lost (snapshot target is unlogged) | Max throughput / Redis-like comparison |
Configuring the mode
Set via StorageMode in SetupConfiguration.json or PG_REDIS_STORAGE_MODE:
# Switch the containerized host (restarts the gateway when needed)
make storage-mode PG_STORAGE_MODE=unlogged
scripts/set_pg_storage_mode.sh memory
Memory mode requires a gateway restart after changing StorageMode (the
in-process worker loads config once at start).
Memory snapshots
Memory mode optionally snapshots to unlogged redis.* tables on an interval
(MemorySnapshotIntervalSecs, default 60; 0 disables periodic snapshots) and
on clean gateway shutdown when Postgres is reachable. Snapshots use binary
COPY.
SQL helpers: redis.storage_mode() / redis.set_storage_mode('logged'|'unlogged')
(table persistence only — memory is gateway-side).
TTL / expiry
TTL uses both lazy and active purge:
- Lazy —
expires_atcolumns +redis.ensure_aliveon read/write. - Active (SQL modes) —
pg_cronjobpg_redis_ttl_taskcallsredis.delete_expired_keys(). - Active (memory mode) — 1s in-gateway tick calls
MemoryStore::purge_expired().
Active expiry is intentionally naive today (not Redis-style random
sampling). See Commands › TTL and
compat/STATUS.md.
SQL sweeper throughput is tunable via pg_redis.ttl_delete_batch_size /
pg_redis.ttl_delete_max_rounds — see Configuration.