AWS Marketplace
The PgCache AMI is a pre-built Amazon Machine Image that runs PgCache as a systemd service on Amazon Linux 2023 (ARM64/Graviton). It includes an embedded PostgreSQL 18 instance for the cache database — no additional infrastructure is needed.
On first boot, a bootstrap script fetches your database credentials from AWS Systems Manager (SSM) Parameter Store, configures PgCache, and starts the service automatically.
Prerequisites
- Origin PostgreSQL database with
wal_level = logicalenabled - Database user with
REPLICATIONrole attribute or superuser - AWS CLI installed and configured (
aws configure) - A subscription to PgCache on the AWS Marketplace — required before the AMI can be launched in your account
See Getting Started for detailed origin database setup.
Quick Start
1. Store your database URL in SSM
aws ssm put-parameter --name "/pgcache/prod/upstream-url" \
--type SecureString \
--value "postgres://user:password@host:5432/dbname?sslmode=require"
The path prefix (/pgcache/prod) is passed to the instance at launch — use any naming convention you like.
2. Create an IAM role
The EC2 instance needs permission to read SSM parameters:
# Create the role
aws iam create-role \
--role-name pgcache-ec2 \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# Grant SSM read access
aws iam put-role-policy \
--role-name pgcache-ec2 \
--policy-name pgcache-ssm-read \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["ssm:GetParameter"],
"Resource": "arn:aws:ssm:*:*:parameter/pgcache/*"
}]
}'
# Create an instance profile and attach the role
aws iam create-instance-profile --instance-profile-name pgcache-ec2
aws iam add-role-to-instance-profile \
--instance-profile-name pgcache-ec2 \
--role-name pgcache-ec2
Adjust the Resource ARN if you use a prefix other than /pgcache/.
3. Create a security group
PgCache listens on port 5432 (proxy) and 9090 (metrics). Restrict access to your application’s network:
aws ec2 create-security-group \
--group-name pgcache \
--description "PgCache proxy"
# Allow PostgreSQL traffic from your application subnet
aws ec2 authorize-security-group-ingress \
--group-name pgcache \
--protocol tcp --port 5432 \
--cidr 10.0.0.0/16
# Allow metrics scraping
aws ec2 authorize-security-group-ingress \
--group-name pgcache \
--protocol tcp --port 9090 \
--cidr 10.0.0.0/16
Replace the CIDR ranges with your actual network addresses.
4. Launch the instance
Create a user-data script that calls the bootstrap with your SSM prefix:
cat > /tmp/userdata.sh <<'EOF'
#!/bin/bash
/opt/pgcache/bootstrap.sh --ssm-prefix /pgcache/prod
EOF
The AMI ID differs per region. Resolve the latest PgCache AMI in your configured region by its Marketplace product code:
AMI_ID=$(aws ec2 describe-images \
--owners aws-marketplace \
--filters "Name=product-code,Values=847qeaa809vzwhz2n1dtfyuwh" \
--query 'sort_by(Images, &CreationDate)[-1].ImageId' --output text)
Launch the instance:
SG_ID=$(aws ec2 describe-security-groups \
--group-names pgcache \
--query 'SecurityGroups[0].GroupId' --output text)
aws ec2 run-instances \
--image-id "$AMI_ID" \
--instance-type m6g.large \
--key-name your-keypair \
--iam-instance-profile Name=pgcache-ec2 \
--network-interfaces "AssociatePublicIpAddress=false,DeviceIndex=0,Groups=${SG_ID}" \
--user-data file:///tmp/userdata.sh
Set AssociatePublicIpAddress=true if you need external access.
5. Connect your application
Update your connection string to point at the PgCache instance:
# Before
DATABASE_URL=postgres://user:password@db-host:5432/myapp
# After
DATABASE_URL=postgres://user:password@pgcache-instance:5432/myapp
PgCache passes authentication through to the origin transparently — use the same credentials as before.
SSM Parameters
Store parameters under your chosen prefix. Only the upstream URL is required.
| Parameter | Required | Description |
|---|---|---|
/upstream-url | Yes | Origin database connection URL |
/replication-url | No | Separate URL for CDC replication |
/tls-cert | No | PEM TLS certificate for client connections |
/tls-key | No | PEM TLS private key for client connections |
A separate replication URL is useful when your application connects through a connection pooler but CDC needs a direct PostgreSQL connection.
Bootstrap Options
Non-secret settings can be passed as flags in the user-data script:
/opt/pgcache/bootstrap.sh --ssm-prefix /pgcache/prod \
--workers 4 \
--cache-size 4294967296 \
--allowed-tables users,orders,products| Flag | Default | Description |
|---|---|---|
--ssm-prefix | (required) | SSM Parameter Store path prefix |
--workers | half of vCPUs (min 1) | Proxy worker threads |
--cache-size | unlimited | Max cache size in bytes (enables eviction) |
--cache-policy | clock | Eviction policy: clock or fifo |
--admission-threshold | 2 | Queries seen before caching (clock policy only) |
--allowed-tables | all tables | Comma-separated list of cacheable tables |
--pinned-tables | none | Comma-separated tables to pin in cache |
--pinned-queries | none | Semicolon-separated queries to pin in cache |
--cdc-suffix | EC2 instance ID | Suffix for publication/slot names |
See Configuration for details on all settings.
Recommended Instance Types
The AMI is available on ARM64 Graviton m6g and m6gd instances from medium through 4xlarge. The embedded PostgreSQL is auto-tuned: 25% of RAM for shared_buffers, workers default to half of vCPUs.
| Instance Type | vCPUs | Memory | Workers | Shared Buffers |
|---|---|---|---|---|
| m6g.medium | 1 | 4 GB | 1 | 1 GB |
| m6g.large | 2 | 8 GB | 1 | 2 GB |
| m6g.xlarge | 4 | 16 GB | 2 | 4 GB |
| m6g.2xlarge | 8 | 32 GB | 4 | 8 GB |
| m6g.4xlarge | 16 | 64 GB | 8 | 8 GB (capped) |
Instance Store (NVMe)
Instance types with local NVMe storage — the m6gd variants — are automatically detected at boot. When present, the cache database is stored on the local NVMe disk instead of EBS, providing significantly lower I/O latency. No configuration is needed; the bootstrap script handles detection, formatting, and mounting.
Since cached data is rebuilt from the origin on every startup, the ephemeral nature of instance store is not a concern — there is no data loss risk.
Managing a Running Instance
View status and logs
sudo systemctl status pgcache # Service status
sudo journalctl -u pgcache -f # PgCache logs (live)
sudo tail -f /var/log/postgresql/cache.log # PostgreSQL logsModify configuration
sudo vi /etc/pgcache/config.toml
sudo systemctl restart pgcache
Only PgCache needs to be restarted — the embedded PostgreSQL cache database does not.
Re-run bootstrap from SSM
If you update SSM parameters, regenerate the config:
sudo systemctl stop pgcache
sudo /opt/pgcache/bootstrap.sh --ssm-prefix /pgcache/prodMetrics
Prometheus metrics are available at http://<instance>:9090/metrics. See Monitoring for the full list of available metrics.
Architecture
The AMI runs two systemd services:
postgresql-cache.service— Embedded PostgreSQL 18 on port 5433 (localhost only). Stores cached query results.pgcache.service— PgCache proxy on port 5432. Accepts client connections, serves cached results, forwards non-cacheable queries to the origin.
Each instance automatically uses its EC2 instance ID as a CDC suffix, so multiple PgCache instances can run against the same origin database without publication or slot name conflicts.
File locations
| Path | Description |
|---|---|
/usr/local/bin/pgcache | PgCache binary |
/etc/pgcache/config.toml | Configuration file |
/etc/pgcache/pgcache.env | Environment variables for systemd |
/etc/pgcache/tls/ | TLS certificates (if configured) |
/opt/pgcache/bootstrap.sh | Bootstrap script |
/var/lib/pgsql/18/data/ | PostgreSQL data directory |
/var/log/postgresql/cache.log | PostgreSQL log |
Security
- Credentials are stored as SecureString in SSM and fetched at boot — never passed through user-data.
- The config file (
/etc/pgcache/config.toml) is readable only by root and the postgres user. - The embedded PostgreSQL listens on
127.0.0.1:5433only — not externally accessible. - Use security groups to restrict access to port 5432 and 9090 to trusted networks.
- For encrypted client connections, store TLS certificates in SSM using the
/tls-certand/tls-keyparameters.