LO

local-cluster-manager

A management tool for local multigres clusters that handles service orchestration, logs, and backup testing.

Install

mkdir -p .claude/skills/local-cluster-manager && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/2700" && unzip -o skill.zip -d .claude/skills/local-cluster-manager && rm skill.zip

Installs to .claude/skills/local-cluster-manager

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Manage local multigres cluster components (multipooler, pgctld, multiorch, multigateway) - start/stop services, view logs, connect with psql, test S3 backups locally
165 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Start and stop multigres cluster components
  • View logs for individual multigres components
  • Connect to multipooler or multigateway with psql
  • Check status and topology of multigres cluster
  • Initialize multigres cluster with S3 backup configuration
  • Create, list, and restore S3 backups for multigres

How it works

This skill executes shell commands to manage multigres cluster components, including starting/stopping services, checking status, viewing logs, and performing S3 backup operations.

Inputs & outputs

You give it
User commands for cluster management or S3 backup operations
You get back
Execution of cluster commands, log output, or S3 backup results

When to use local-cluster-manager

  • Start or stop local cluster
  • View cluster component logs
  • Connect to services with psql
  • Test S3 backup configurations

About this skill

Local Cluster Manager

Manage local multigres cluster - both cluster-wide operations and individual components.

When to Use This Skill

Invoke this skill when the user asks to:

  • Start/stop/restart the entire cluster or individual components
  • Start cluster with observability (OTel, Grafana, Prometheus)
  • Teardown and restart the full stack (cluster + observability)
  • View logs for any component
  • Connect to multipooler or multigateway with psql
  • Check status of cluster components
  • Check multipooler topology status (PRIMARY/REPLICA roles)
  • Check if PostgreSQL instances are in recovery mode
  • Test S3 backups (initialize cluster with S3, create/list/restore backups)
  • Configure or troubleshoot S3 backup settings

Performance Optimization

Parse ./multigres_local/multigres.yaml once when this skill is first invoked and cache the cluster configuration in memory for the duration of the conversation. Use the cached data for all subsequent commands. Only re-parse if the user explicitly asks to "reload config" or if a command fails due to stale config.

Cluster-Wide Operations

Start entire cluster:

./bin/multigres cluster start

Stop entire cluster:

./bin/multigres cluster stop

Stop entire cluster and delete all cluster data:

./bin/multigres cluster stop --clean

Check cluster status:

./bin/multigres cluster status

Initialize new cluster:

./bin/multigres cluster init

Get all multipoolers from topology:

./bin/multigres getpoolers

Returns JSON with all multipoolers, their cells, service IDs, ports, and pooler directories.

Get detailed status for a specific multipooler:

./bin/multigres getpoolerstatus --cell <cell-name> --service-id <service-id>

Returns detailed status including:

  • pooler_type: 1 = PRIMARY, 2 = REPLICA
  • postgres_role: "primary" or "standby"
  • postgres_running: Whether PostgreSQL is running
  • wal_position: Current WAL position
  • consensus_term: Current consensus term
  • primary_status: (for PRIMARY) connected followers and sync replication config
  • replication_status: (for REPLICA) replication lag and primary connection info

Example:

./bin/multigres getpoolerstatus --cell zone1 --service-id thhcdhbp

Check PostgreSQL recovery mode directly:

psql -h <pooler-dir>/pg_sockets -p <pg-port> -U postgres -d postgres -c "SELECT pg_is_in_recovery();"

Returns t (true) if in recovery/standby mode, f (false) if primary.

S3 Backup Testing

Test S3 backups using AWS S3. When the user wants to test S3 backups:

Configuration Caching: When S3 configuration values are first provided, cache them in memory for the duration of the conversation. Reuse these cached values for all subsequent S3 operations. Only re-prompt if:

  • The user explicitly asks to change the configuration
  • A command fails due to invalid/expired credentials
  • The values have never been provided in this conversation
  1. Prompt for S3 configuration using AskUserQuestion (only if not already cached):

    • Path to AWS credentials file (e.g., ./.staging-aws or ~/.aws/credentials)
    • S3 backup URL (e.g., s3://bucket-name/backups/)
    • AWS region (e.g., us-east-1)
  2. Check/source credentials:

# Check if AWS credentials are already set
env | grep AWS_

# If not, source the credentials file (path from user)
source <credentials-file-path>

# Verify credentials are now set
env | grep AWS_

IMPORTANT:

  • NEVER commit AWS credentials files to git
  • Avoid printing credentials to the terminal
  • Credentials file should contain: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN (if using temporary credentials)
  1. Initialize cluster with S3:
./bin/multigres cluster stop --clean
rm -rf multigres_local
./bin/multigres cluster init \
  --backup-url=<s3-url-from-user> \
  --region=<region-from-user>
  1. Start cluster (use standard cluster start command)

  2. Verify S3 configuration:

grep -r "aws_access_key_id\|aws_secret_access_key\|region\|repo1-s3" ./multigres_local/data/pooler_*/pgbackrest.conf

Should see AWS credentials and S3 configuration in all pgbackrest.conf files.

Backup Commands

Create backup:

./bin/multigres cluster backup

List all backups:

./bin/multigres cluster list-backups

Restore from backup:

./bin/multigres cluster restore --backup-label <label>

Troubleshooting S3 Issues

Missing/expired credentials:

# Re-source credentials file
source <credentials-file-path>

# Verify they're set
env | grep AWS_ | wc -l  # Should show 3+ environment variables

# Reinitialize cluster to pick up new credentials
./bin/multigres cluster stop --clean
rm -rf multigres_local
./bin/multigres cluster init --backup-url=<s3-url> --region=<region>

Check pgbackrest logs for errors:

# View recent errors
tail -100 ./multigres_local/data/pooler_*/pg_data/log/pgbackrest-*.log

# Follow logs in real-time
tail -f ./multigres_local/data/pooler_*/pg_data/log/pgbackrest-*.log

Verify S3 bucket access:

# Use AWS CLI to test bucket access (if installed)
aws s3 ls <s3-bucket-path> --region <region>

Observability Stack

Start the observability stack (Grafana + Prometheus + Loki + Tempo) for metrics, traces, and logs visualization.

Start cluster with observability:

# 1. Start observability stack (separate terminal, runs in foreground)
demo/local/run-observability.sh

# 2. Start cluster with OTel export (separate terminal)
demo/local/multigres-with-otel.sh cluster start --config-path <config-path>

Generate traffic with pgbench:

Run pgbench init synchronously first, then start the workload in a background Agent so the user sees the output when it completes (do NOT use run_in_background on Bash — that hides output).

The local cluster runs one multigateway per cell (zone1/zone2/zone3 by default), each on its own pg-port (15432/15433/15434). Each gateway maintains independent in-memory state — its own query registry, consolidator, and connection pool.

That means a single-port -h localhost -p 15432 workload only exercises one gateway and leaves the other two idle. That hides per-instance bugs and means the per-gateway diagnostic pages on the other gateways stay empty.

To exercise all gateways, pass a libpq multi-host conninfo string with load_balance_hosts=random (PostgreSQL 16+; the pgbench and psql shipped with PG 17 honor it). Each new connection picks a gateway at random; with -c 9 clients you typically land ~3 connections per gateway. Connections are sticky for their lifetime, so distribution evens out across connections, not within.

Discover the gateway pg-ports from the cluster's cached config (every multigateway entry has its own pg-port) and build the conninfo string from there.

# Conninfo with all multigateway pg-ports — substitute the actual ports
# from the cluster config (default local layout shown).
CONNSTR='host=localhost,localhost,localhost port=15432,15433,15434 dbname=postgres user=postgres password=postgres load_balance_hosts=random'

# Step 1: Init (synchronous; init's single connection picks one gateway
# at random — either route ends up at the same primary postgres).
PGPASSWORD=postgres pgbench -i "$CONNSTR"

# Step 2: Workload (run in a background Agent). -c is a multiple of the
# gateway count for even distribution.
pgbench -c 9 -j 3 -T 300 -P 5 "$CONNSTR"

Set -j (pgbench worker threads) to spread the clients across threads — use roughly min(clients, NumCPU). A single pgbench thread cannot drain a high-client-count result stream fast enough; the slow drain backs result data up into the multigateway and multipooler (inflating their memory and skewing the numbers), so the load generator itself becomes the bottleneck. pgbench requires -j <= -c.

If the user only wants to drive a single gateway on purpose (e.g. reproducing a specific instance's bug), fall back to -h localhost -p <port> and call out the choice — don't silently single-target.

View telemetry:

Teardown (stop in this order to avoid OTel export errors):

# 1. Stop the cluster first
./bin/multigres cluster stop --config-path <config-path>

# 2. Stop the observability stack
docker rm -f multigres-observability

Full restart:

# Teardown
./bin/multigres cluster stop --config-path <config-path>
docker rm -f multigres-observability

# Start
demo/local/run-observability.sh          # terminal 1
demo/local/multigres-with-otel.sh cluster start --config-path <config-path>  # terminal 2

Observability ports:

ServicePort
Grafana3000
OTLP (HTTP)4318
Prometheus9090
Loki3100
Tempo3200

Individual Component Operations

Configuration

  1. Parse the config: Read ./multigres_local/multigres.yaml to discover available components and their IDs

  2. Component ID mapping:

    • multipooler IDs: extracted from .provisioner-config.cells.<zone>.multipooler.service-id
    • pgctld uses the same IDs as multipooler
    • multiorch has separate IDs for each zone
    • multigateway has separate IDs for each zone
  3. If no ID provided: Use AskUserQuestion to let the user select which instance to operate on

    • Show available IDs with their zone names
    • Example: "xf42rpl6 (zone1)", "hm9hmxzm (zone2)", "n6t8hvgl (zone3)"

Commands

Stop pgctld:

./bin/pgctld stop --pooler-dir <pooler-dir-from-config>

Start pgctld:

./bin/pgctld start --pooler-dir <pooler-dir-from-config>

Restart pgctld (as standby):

./bin/pgctld r

---

*Content truncated.*

How it compares

This skill provides a centralized interface to manage local multigres cluster components and S3 backups, simplifying operations compared to running individual scripts manually.

Compared to similar skills

local-cluster-manager side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
local-cluster-manager (this skill)225dReviewIntermediate
aws-aurora14moReviewIntermediate
supabase-webhooks-events126dCautionAdvanced
supabase-load-scale126dCautionAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

Search skills

Search the agent skills registry