Configuration

PgCache supports three configuration methods: a TOML config file, CLI arguments, and Docker environment variables. These can be combined — CLI arguments override TOML file values, and Docker environment variables are mapped to CLI arguments by the container entrypoint.

Configuration Methods

MethodUsageBest For
Environment variablesUPSTREAM_URL=postgres://...Docker deployments (recommended)
CLI argumentsPassed via Docker commandOverriding specific values
TOML fileMounted into containerVersion-controlled config

TOML Configuration Reference

[origin] — Origin Database Connection

The PostgreSQL database that PgCache caches queries for.

FieldTypeRequiredDefaultDescription
hoststringyesOrigin database hostname
portintegeryesOrigin database port
userstringyesDatabase user
passwordstringnoDatabase password
databasestringyesDatabase name
ssl_modestringnodisableTLS mode: disable, require, or verify-full

[replication] — Replication Connection (Optional)

Override connection settings for CDC logical replication. Every field is optional and cascades from [origin] when not specified. This is useful when your application connects through a connection pooler like PgBouncer, but CDC replication needs a direct connection to PostgreSQL.

FieldTypeDefaultDescription
hoststringorigin hostReplication host
portintegerorigin portReplication port
userstringorigin userReplication user
passwordstringorigin passwordReplication password
databasestringorigin databaseReplication database
ssl_modestringorigin ssl_modeTLS mode: disable, require, or verify-full

[cdc] — Change Data Capture

Settings for PostgreSQL logical replication. PgCache creates and manages the publication and replication slot automatically on the origin database using these names.

FieldTypeRequiredDefaultDescription
publication_namestringyesName of the publication PgCache creates on the origin
slot_namestringyesName of the logical replication slot PgCache creates on the origin

[listen] — Proxy Listener

FieldTypeRequiredDefaultDescription
socketstringyesAddress and port to listen on (e.g., 0.0.0.0:5432)

[metrics] — Prometheus Metrics (Optional)

FieldTypeRequiredDefaultDescription
socketstringyesAddress and port for the metrics HTTP endpoint

Top-Level Settings

General

FieldTypeRequiredDefaultDescription
num_workersintegeryesNumber of worker threads for handling connections
log_levelstringnoLog level filter. Supports simple levels ("info", "debug") and module-specific filters ("pgcache_lib::cache=debug,info")
telemetrybooleannotrueAnonymous telemetry reporting. Set to false to disable. See Telemetry for details on what is collected

Cache Behavior

The fields in this section plus log_level can be changed at runtime via the HTTP admin API (PUT /config) without restarting. See Monitoring for the admin endpoints.

FieldTypeRequiredDefaultDescription
cache_sizeintegernoDeprecated and ignored. Superseded by disk_limit; setting it logs a deprecation warning and has no effect
cache_policystringnoclockEviction policy: clock (second-chance) or fifo (oldest first)
admission_thresholdintegerno1Number of times a query must be seen before cache admission (clock policy only; 1 admits on first occurrence)
mv_size_ratiointegerno10Materialized result size gate (row-reduction test). A shape-eligible query (aggregate, GROUP BY, DISTINCT, etc.) passes this gate when result_rows × mv_size_ratio ≤ source_rows at first population — i.e. the result is at least this many times smaller than the input. A query is materialized if it passes either this gate or mv_compute_min_rows. Window functions materialize unconditionally
mv_compute_min_rowsintegerno1000Materialized-view compute-avoidance gate. A shape-eligible query passes this gate when its population source-row count is at least this value — so large inputs aren’t recomputed from source rows on every serve, regardless of how much the result reduces them. A query is materialized if it passes either this gate or mv_size_ratio
memo_cache_sizeintegerno67108864Total byte budget for the in-process result memo, an in-memory tier that serves the hottest queries inline without a cache-database round-trip. Default 64 MiB; 0 disables it
memory_limitintegernoAbsolute ceiling (bytes) on pgcache’s total memory footprint (the pgcache process plus the cache Postgres it manages). When unset, the ceiling is 80% of detected RAM (cgroup-aware in containers). As whole-system used memory approaches the ceiling, registration of new distinct queries is throttled — they are forwarded to origin instead of cached — bounding memory under high query cardinality. A configured value can only lower the effective ceiling, never raise it above 80% of RAM
disk_limitintegernoCap (bytes) on space used on the cache volume — the disk analogue of memory_limit. When the volume’s used space exceeds it, registration of new queries is throttled and cache tables are dropped to reclaim space. When unset, the limit auto-derives from the cache volume’s live free space, keeping a reserve free
allowed_tablesarraynoOnly cache queries referencing these tables. Supports unqualified ("orders") and schema-qualified ("audit.orders") names. If omitted, all tables are cacheable

Pinned Queries

FieldTypeRequiredDefaultDescription
pinned_queriesarraynoSQL queries to pin in cache at startup. Pinned queries are pre-populated, protected from eviction, and auto-readmitted after CDC invalidation
pinned_tablesarraynoTables to pin in cache. Each table is expanded to SELECT * FROM {table} and merged with pinned_queries

TLS

FieldTypeRequiredDefaultDescription
tls_certstringnoPath to TLS certificate (PEM) for client connections
tls_keystringnoPath to TLS private key (PEM) for client connections

Full Example Configuration

num_workers = 4
# disk_limit = 10737418240     # max cache-volume bytes used; unset auto-derives from free space
# cache_policy = "clock"       # or "fifo"
# admission_threshold = 1      # clock policy only
log_level = "info"

# Optional: restrict caching to specific tables
# allowed_tables = ["users", "orders", "products"]

# Optional: pin queries in cache at startup
# pinned_queries = [
#     "SELECT * FROM settings",
#     "SELECT * FROM categories",
# ]

# Optional: pin entire tables (shorthand for pinned_queries)
# pinned_tables = ["settings", "categories"]

[origin]
host = "db.example.com"
port = 5432
user = "app_user"
password = "secret"
database = "myapp"
ssl_mode = "require"

# Optional: override replication connection
# Useful when origin is behind PgBouncer
[replication]
host = "db-direct.example.com"
port = 5432

[cdc]
publication_name = "pgcache_pub"
slot_name = "pgcache_slot"

[listen]
socket = "0.0.0.0:6432"

[metrics]
socket = "0.0.0.0:9090"

CLI Arguments Reference

All TOML fields can be set via command-line arguments. CLI values override TOML values.

FlagDescription
-c, --configPath to TOML configuration file
--config_createCreate the config file if missing and persist dynamic (PUT /config) changes to it; a missing file is not an error
--origin_hostOrigin database host
--origin_portOrigin database port
--origin_userOrigin database user
--origin_passwordOrigin database password
--origin_databaseOrigin database name
--origin_ssl_modeOrigin TLS mode (disable, require, or verify-full)
--replication_hostReplication host override
--replication_portReplication port override
--replication_userReplication user override
--replication_passwordReplication password override
--replication_databaseReplication database override
--replication_ssl_modeReplication TLS mode override
--cdc_publication_nameLogical replication publication name
--cdc_slot_nameLogical replication slot name
--listen_socketListen address and port
--num_workersNumber of worker threads
--cache_sizeDeprecated and ignored; use --disk_limit
--cache_policyEviction policy (clock or fifo)
--admission_thresholdQuery admission threshold (clock policy only)
--mv_size_ratioMaterialized result size gate (default 10)
--mv_compute_min_rowsMaterialized-view compute-avoidance gate — also materializes any input of at least this many source rows (default 1000)
--memo_cache_sizeIn-process result memo byte budget (default 64 MiB; 0 disables)
--memory_limitAbsolute RSS ceiling in bytes for registration throttling (default: 80% of RAM; can only lower)
--disk_limitCap (bytes) on cache-volume space used before throttling + table drops (default: auto from free disk)
--tls_certTLS certificate file path
--tls_keyTLS private key file path
--metrics_socketPrometheus metrics listen address
--log_levelLog level filter
--allowed_tablesComma-separated list of tables to cache
--pinned_queriesSemicolon-separated queries to pin in cache
--pinned_tablesComma-separated tables to pin in cache
--telemetry_offDisable anonymous telemetry reporting

Docker Environment Variables

When running the PgCache Docker image, these environment variables are available. They map to the entrypoint’s CLI options.

The origin database can be given either as a single UPSTREAM_URL or as individual ORIGIN_* fields; when both are set, the individual fields override the URL. The same applies to the replication connection (REPLICATION_URL vs the REPLICATION_* fields). Individual fields avoid URL-encoding credentials that contain special characters.

VariableDescriptionDefault
UPSTREAM_URLOrigin database URL (postgres://user:pass@host:port/db)— (required unless ORIGIN_HOST or CONFIG_FILE set)
ORIGIN_HOSTOrigin host (alternative to UPSTREAM_URL; overrides the URL)
ORIGIN_PORTOrigin port5432
ORIGIN_USEROrigin userpostgres
ORIGIN_PASSWORDOrigin password
ORIGIN_DATABASEOrigin database
ORIGIN_SSL_MODEOrigin TLS mode (disable, require, verify-full)disable
CONFIG_FILEPath to TOML config file (mounted into container)
CONFIG_CREATESet to 1/true to create CONFIG_FILE if missing and persist dynamic (PUT /config) changes across restarts
REPLICATION_URLReplication connection URL (defaults to upstream)
REPLICATION_HOSTOverride replication host
REPLICATION_PORTOverride replication port
REPLICATION_USEROverride replication user
REPLICATION_DATABASEOverride replication database
REPLICATION_PASSWORDOverride replication password
REPLICATION_SSL_MODEOverride replication TLS mode
LISTEN_PORTProxy listen port5432
METRICS_PORTPrometheus metrics port9090
NUM_WORKERSNumber of worker threadsauto (≈1 per allocated CPU, min 2)
PUBLICATIONPublication namepgcache_pub
SLOTReplication slot namepgcache_slot
CDC_SUFFIXSuffix appended to publication and slot names
CACHE_SIZEDeprecated and ignored. Superseded by DISK_LIMIT
DISK_LIMITCap (bytes) on cache-volume space used before disk-pressure reclaim engagesauto from free disk
CACHE_POLICYCache eviction policy: clock or fifoclock
ADMISSION_THRESHOLDNumber of times a query must be seen before caching1
MV_SIZE_RATIOMaterialized result size gate (row-reduction test): a shape-eligible query passes when result_rows × MV_SIZE_RATIO ≤ source_rows10
MV_COMPUTE_MIN_ROWSMaterialized-view compute-avoidance gate: a shape-eligible query is also materialized when its source-row count reaches this value1000
MEMO_CACHE_SIZEIn-process result memo byte budget (0 disables)67108864 (64 MiB)
MEMORY_LIMITAbsolute RSS ceiling in bytes for registration throttling (can only lower)80% of RAM
ALLOWED_TABLESComma-separated list of tables to cache (default: all)
PINNED_QUERIESSemicolon-separated queries to pin in cache
PINNED_TABLESComma-separated tables to pin in cache
LOG_LEVELLog level filter (e.g., debug, info, pgcache_lib::cache=debug)
PGCACHE_TELEMETRYSet to off to disable anonymous telemetry reporting
PGCACHE_TLS_CERTBase64-encoded TLS certificate
PGCACHE_TLS_KEYBase64-encoded TLS private key

Docker Examples

Basic:

docker run -d -p 5432:5432 pgcache/pgcache \
  --upstream postgres://user@db:5432/myapp

With replication override (origin behind PgBouncer):

docker run -d -p 5432:5432 pgcache/pgcache \
  --upstream postgres://user@pgbouncer:6432/myapp \
  --replication-host db-direct.example.com \
  --replication-port 5432

With environment variables:

docker run -d -p 5432:5432 \
  -e UPSTREAM_URL=postgres://user@db:5432/myapp \
  -e NUM_WORKERS=8 \
  -e REPLICATION_HOST=db-direct.example.com \
  pgcache/pgcache

With individual origin fields (avoids URL-encoding credentials with special characters):

docker run -d -p 5432:5432 \
  -e ORIGIN_HOST=db.example.com \
  -e ORIGIN_DATABASE=myapp \
  -e ORIGIN_USER=app_user \
  -e ORIGIN_PASSWORD='p@ss/w:rd' \
  -e ORIGIN_SSL_MODE=require \
  pgcache/pgcache

With a mounted TOML config file:

docker run -d -p 5432:5432 -p 9090:9090 \
  -v ./pgcache.toml:/etc/pgcache/config.toml:ro \
  -e CONFIG_FILE=/etc/pgcache/config.toml \
  pgcache/pgcache

With table allowlist and pinned tables:

docker run -d -p 5432:5432 \
  -e UPSTREAM_URL=postgres://user@db:5432/myapp \
  -e ALLOWED_TABLES=users,orders,products \
  -e PINNED_TABLES=users,products \
  pgcache/pgcache

With pinned queries:

docker run -d -p 5432:5432 pgcache/pgcache \
  --upstream postgres://user@db:5432/myapp \
  --pinned-queries "SELECT * FROM config;SELECT * FROM lookup"