Docker
PgCache is distributed as a Docker image. The container bundles an embedded PostgreSQL instance for the cache database, so there is nothing else to run. For the fastest path to a working proxy, see Getting Started; this page covers production deployment.
Image and Ports
docker run -d -p 5432:5432 -p 9090:9090 pgcache/pgcache \
--upstream postgres://user:password@your-db-host:5432/myapp| Port | Purpose |
|---|---|
| 5432 | PostgreSQL wire protocol — point your application here |
| 9090 | HTTP endpoint for Prometheus metrics and health checks |
Security: the metrics/health port is unauthenticated. Publish it only to trusted/internal networks, not the public internet. See Monitoring.
Checking the Origin
Before the first run, ask the image whether the origin is ready. It connects with the same settings the proxy would use and reports each requirement with a fix:
docker run --rm pgcache/pgcache check \
--upstream postgres://user:password@your-db-host:5432/myapppgcache check: origin user@your-db-host:5432/myapp
PASS connection PostgreSQL 18.1
PASS server version PostgreSQL 18.1
FAIL wal_level wal_level is 'replica'; logical replication needs 'logical'
fix: ALTER SYSTEM SET wal_level = logical;
then restart PostgreSQL (a reload is not enough).
PASS replication slots 0 of 10 replication slots and 0 of 10 wal senders in use
PASS role privileges user has REPLICATION and CREATE on the database
...
WARN primary keys 2 of 17 tables have no primary key and are forwarded, never cached: ...
9 passed, 1 warnings, 1 failed
Origin is not ready for pgcache. Fix the failures above and run the check again.
A failure exits with status 1 and means the proxy would not start or would not be safe to run; a warning means it starts but the named tables are forwarded rather than cached. Remediations are worded for the detected host: self-managed PostgreSQL, Amazon RDS and Aurora, Cloud SQL, or Neon. The checks are: connection, server version, wal_level, replication slot and WAL sender capacity, role privileges, existing publication and slot, a logical replication connection, table ownership, primary keys, views, row-level security, and pg_stat_statements. ALLOWED_TABLES scopes the table checks to the tables you intend to cache.
No embedded PostgreSQL is initialised in check mode, so the command is quick and leaves nothing behind. The same report is available from the binary as pgcache --check.
Docker Compose
services:
pgcache:
image: pgcache/pgcache
restart: always
ports:
- "5432:5432"
- "9090:9090"
environment:
UPSTREAM_URL: postgres://user:password@db:5432/myapp
NUM_WORKERS: 4
PUBLICATION: pgcache_pub
SLOT: pgcache_slot
healthcheck:
test: ["CMD", "wget", "-qO", "/dev/null", "http://127.0.0.1:9090/healthz"]
interval: 10s
timeout: 3s
retries: 3
Environment variables map to PgCache’s CLI options — see the Configuration reference for the full list.
Mounting a TOML config
For version-controlled configuration, mount a TOML file and point CONFIG_FILE at it:
services:
pgcache:
image: pgcache/pgcache
restart: always
ports:
- "5432:5432"
- "9090:9090"
volumes:
- ./pgcache.toml:/etc/pgcache/config.toml:ro
environment:
CONFIG_FILE: /etc/pgcache/config.toml
CLI arguments and environment variables override values from the mounted file, so you can keep a base config in TOML and override per-environment values through the environment.
Mounting TLS certificates
To terminate TLS for client connections, mount the certificate and key and reference them in config (tls_cert / tls_key), or pass them as base64-encoded environment variables (PGCACHE_TLS_CERT / PGCACHE_TLS_KEY). See TLS Support.
volumes:
- ./certs/server.crt:/etc/pgcache/server.crt:ro
- ./certs/server.key:/etc/pgcache/server.key:roHealth Checks
The HTTP port exposes two probes for orchestrators and load balancers:
GET /healthz— liveness; returns200whenever the process is running.GET /readyz— readiness; returns200when the cache is running,503otherwise.
The image declares its own HEALTHCHECK against /healthz (10 s interval, 3 s timeout, 3 retries); the compose healthcheck block above overrides it and is only needed to change those values. The image ships BusyBox wget, not curl. Use /healthz for the container healthcheck and /readyz to gate traffic in a load balancer or Kubernetes deployment. See Monitoring → Health Checks.
Restart Policy
Use restart: always (or unless-stopped) so the container recovers from crashes. Note the interaction with the replication slot: PgCache drops its slot on a graceful stop, but a crash leaves the slot behind on the origin, where it retains WAL until the container restarts and resumes consuming it. An automatic restart policy keeps that window short. Understand this behavior — and how to detect a stuck slot — before running in production: see Operations → The Replication Slot.
Resource Sizing
- CPU / workers: set
NUM_WORKERSto match the connection concurrency you expect; it defaults to a small value suitable for getting started. - Memory & disk: the cache holds hot data in the embedded PostgreSQL instance. PgCache bounds itself automatically — by a memory budget (80% of detected RAM by default, lower it with
MEMORY_LIMIT) and by cache-volume disk pressure (auto-derived from free space, or cap it withDISK_LIMIT). Give the container enough RAM and disk for your working set. See Configuration → Cache Behavior. - Cold start: the cache is reset on every container start and warms from scratch. For planned cutovers, pre-populate hot queries with
pinned_queries— see Operations → Cache Warm-Up.