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 = logical enabled
  • Database user with REPLICATION role 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.

ParameterRequiredDescription
/upstream-urlYesOrigin database connection URL
/replication-urlNoSeparate URL for CDC replication
/tls-certNoPEM TLS certificate for client connections
/tls-keyNoPEM 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
FlagDefaultDescription
--ssm-prefix(required)SSM Parameter Store path prefix
--workershalf of vCPUs (min 1)Proxy worker threads
--cache-sizeunlimitedMax cache size in bytes (enables eviction)
--cache-policyclockEviction policy: clock or fifo
--admission-threshold2Queries seen before caching (clock policy only)
--allowed-tablesall tablesComma-separated list of cacheable tables
--pinned-tablesnoneComma-separated tables to pin in cache
--pinned-queriesnoneSemicolon-separated queries to pin in cache
--cdc-suffixEC2 instance IDSuffix for publication/slot names

See Configuration for details on all settings.

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 TypevCPUsMemoryWorkersShared Buffers
m6g.medium14 GB11 GB
m6g.large28 GB12 GB
m6g.xlarge416 GB24 GB
m6g.2xlarge832 GB48 GB
m6g.4xlarge1664 GB88 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 logs

Modify 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/prod

Metrics

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

PathDescription
/usr/local/bin/pgcachePgCache binary
/etc/pgcache/config.tomlConfiguration file
/etc/pgcache/pgcache.envEnvironment variables for systemd
/etc/pgcache/tls/TLS certificates (if configured)
/opt/pgcache/bootstrap.shBootstrap script
/var/lib/pgsql/18/data/PostgreSQL data directory
/var/log/postgresql/cache.logPostgreSQL 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:5433 only — 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-cert and /tls-key parameters.