AWS PostgreSQL

RDS/Aurora performance without defaulting to “scale the instance.”

Use workload evidence to separate expensive statements, plan problems, connection amplification, waits and configuration from genuine capacity constraints.

Workload concentration

Which statements, calls and I/O patterns actually account for database time?

Capacity vs inefficiency

Distinguish a real resource ceiling from a workload that would simply consume the larger instance too.

Upgrade/support risk

Combine managed-service timelines with application and performance validation rather than treating upgrades as a checkbox.

Evidence

What AWS already records, and what each source answers.

Most RDS and Aurora teams already have the evidence. It is spread across consoles and rarely lined up on the same timeline.

SourceWhat it answers
CloudWatch Database Insights (formerly Performance Insights)Database load by wait event and by SQL statement over time. Shows whether the instance is busy on CPU, I/O, locks or client waits, and which statements drive it. Advanced mode adds execution plans and lock analysis.
pg_stat_statementsTotal time, calls, rows and buffer use per normalized statement. Ranks the workload by total cost instead of by the slowest single query.
CloudWatch instance metricsCPU, freeable memory, read/write IOPS and latency, disk queue depth, connections and replica lag. On burstable classes and gp2 storage, CPU credit and burst balance show whether the ceiling is real or a credit drain.
Enhanced MonitoringOS-level view at up to one-second granularity: per-process CPU and memory, load and swap. This separates PostgreSQL work from the operating system and AWS agents.
Parameter group and pg_settingsNon-default settings and what changed. For example work_mem, autovacuum thresholds, random_page_cost, max_connections and logging settings.
PostgreSQL logs (exported to CloudWatch Logs)Slow statements via log_min_duration_statement, plans via auto_explain, lock waits via log_lock_waits, checkpoints and autovacuum activity.
RDS Proxy metrics, if usedClient and database connection counts, and sessions pinned to a backend connection. Pinning can quietly cancel the pooling you are paying for.
RDS eventsFailovers, maintenance, minor-version upgrades, parameter changes and storage scaling. Use them to line up a regression with what changed.

All of this is read-only. Your team exports it; no credentials or production write access are needed.

Common patterns

Where RDS and Aurora performance problems usually hide.

“Scale up” that only buys time

CPU climbs and the instance class goes up a size. Database Insights still shows the same three statements dominating load, so the bigger instance fills again as data grows.

Connection pressure, not query cost

Connection counts spike after a deploy or a retry storm. Each query is fast; there are just too many backends competing. Pool sizing, RDS Proxy pinning and idle-in-transaction sessions matter more than indexes.

Storage and I/O limits

Latency rises with disk queue depth while CPU looks fine. Check provisioned IOPS and throughput, burst balance, and whether the working set still fits in memory.

Aurora I/O and cost surprises

On Aurora, read and write I/O is part of the bill on the Standard storage configuration. Scan-heavy workloads can show up in cost before they show up in latency.

PostgreSQL 14 deadline:Community fixes end 12 November 2026. On Amazon RDS and Aurora, standard support ends 28 February 2027, with Extended Support year-1 pricing starting 1 March 2027. Some 14.x minor versions lose standard support sooner.See the dates →
Production evidence

Need an independent PostgreSQL investigation?

Start with the problem and the evidence you already have. You will get a direct answer on whether a scoped investigation is the right next step.

Prefer to talk first? Book a 20-minute triage call.