Skip to content
pg_redis
Esc
navigateopen⌘Jpreview
On this page

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:

  1. Lazyexpires_at columns + redis.ensure_alive on read/write.
  2. Active (SQL modes)pg_cron job pg_redis_ttl_task calls redis.delete_expired_keys().
  3. 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.

Was this page helpful?