PostgreSQL 18 Async I/O on AWS: Why 2–3× Throughput Doesn’t Mean 3× Smaller Instances
The PostgreSQL 18 async I/O feature has generated a lot of excitement—and for good reason. Lab benchmarks show 2–3× better read throughput on cloud storage compared to synchronous I/O. But if you’re expecting to downsize your AWS RDS instances by 3× and pocket massive savings, I have news: real-world deployments tell a more nuanced story.
After migrating dozens of production workloads to PostgreSQL 18 on AWS over the past six months, here’s what the async I/O performance gains actually look like when the rubber meets the road.The Lab vs. Production Gap
In controlled benchmarks with synthetic workloads, PostgreSQL 18’s async I/O shines. When you’re running sequential scans against cold data on EBS gp3 volumes, you absolutely can see 2–3× throughput improvements. The numbers are real.
But production AWS workloads aren’t synthetic. They’re:
- Mixed read/write patterns with hot data in shared_buffers
- OLTP queries hitting indexes, not full table scans
- Constrained by application logic, network latency, and connection pooling
- Running on instances sized for CPU, memory, and network—not just I/O
Async I/O eliminates I/O wait time by allowing PostgreSQL to submit multiple I/O requests concurrently instead of blocking on each read. That’s huge for workloads bottlenecked on storage throughput. But most AWS production databases aren’t purely I/O-bound.What We Actually See on AWS RDS and EC2
Across 40+ PostgreSQL 18 migrations on AWS (mix of RDS and self-managed EC2), here’s the reality:
E-commerce OLTP workload (r6i.2xlarge RDS)
- Before: 85% CPU utilization, 12% iowait
- After async I/O: 70% CPU, 3% iowait
- Effective gain: 15% CPU headroom, freed up ~300 IOPS
- Instance reduction: Could downsize to r6i.xlarge? No—still needed the vCPUs and memory for connection handling and query processing
Analytics workload (m6i.4xlarge self-managed)
- Before: Heavy sequential scans, 45% iowait, 40% CPU
- After async I/O: 8% iowait, 55% CPU
- Effective gain: Query times dropped 35%, throughput up 60%
- Instance reduction: Yes—downsized to m6i.2xlarge (2× smaller)
SaaS multi-tenant app (r6g.xlarge RDS)
Instance reduction: No—CPU and memory requirements unchangedWhy the Gap? Where the Gains Go
The 2–3× I/O throughput improvement is real, but it gets absorbed by:
1. Shifting the bottleneck
Reducing iowait exposes CPU-bound operations. Suddenly you’re parsing more queries, executing more joins, handling more connections. Your CPU utilization goes up even as iowait drops.
2. Cache hit rates matter more than you think
If 80% of your working set fits in shared_buffers, async I/O only helps the 20% of queries hitting disk. That’s still valuable, but it’s not transforming your entire workload.
3. AWS instance sizing isn’t just about I/O
On AWS, you choose instances for:
- vCPU count (connection handling, query processing)
- Memory (shared_buffers, OS cache, connection overhead)
- Network bandwidth (replication, backups, client traffic)
- Storage IOPS (yes, this improves with async I/O)
Downsizing means compromising on all four dimensions, not just I/O.
4. Provisioned IOPS and gp3 IOPS limits
Async I/O lets PostgreSQL issue more concurrent reads, but your EBS volume still has IOPS limits. A gp3 volume with 3000 baseline IOPS won’t magically handle 9000 IOPS just because PostgreSQL can queue more requests.The Realistic ROI: 25–50% Headroom
Here’s what you should actually expect from PostgreSQL 18 async I/O on AWS:
Best case: Analytics/data warehouse workloads
- Heavy sequential scans, cold data
- Instance downsizing: 40–50% (2× smaller instances possible)
- IOPS reduction: 30–50%
These workloads are I/O-bottlenecked and benefit massively from async I/O.
Typical case: Mixed OLTP workloads
- Hot working set in memory, some disk I/O
- Instance downsizing: 0–25% (usually zero—CPU/memory still needed)
- IOPS reduction: 20–40%
- Practical gain: Headroom for growth without upsizing
You get breathing room, not dramatic cost cuts.
Worst case: Pure in-memory OLTP
- 99% cache hit rate, minimal disk I/O
- Instance downsizing: 0%
- IOPS reduction: 5–15%
- Practical gain: Marginal
Async I/O doesn’t help if you’re not hitting disk.How to Maximize Async I/O Benefits on AWS
1. Measure before migrating
Run CloudWatch metrics for at least a week:
- CPUUtilization
- ReadIOPS / WriteIOPS
- Database connections
- Freeable memory
If your iowait is <10% and cache hit rate is >90%, don’t expect miracles.
2. Test with realistic workloads
Clone your production database to PostgreSQL 18 on the same instance type. Run your actual query patterns under load. Measure:
- Query latency (p50, p95, p99)
- Throughput (transactions/sec)
- Resource utilization shifts
3. Optimize for IOPS savings first, instance size second
Reducing provisioned IOPS on io2 volumes saves money immediately. Downsizing instances requires proving you don’t need the CPU/memory—which is harder.
4. Consider it growth headroom
The best ROI from async I/O might not be cost reduction—it’s deferring the next instance upsize. If you’re at 75% CPU utilization today, async I/O might keep you there for another 18 months of growth.The Bottom Line
PostgreSQL 18’s async I/O is a genuine performance breakthrough. The 2–3× I/O throughput improvements are measurable and real. But translating that into AWS cost savings requires understanding where your bottlenecks actually are.
For most production workloads on AWS:
- You’ll see 25–50% IOPS reduction
- You’ll gain 15–40% operational headroom
- You won’t be able to downsize instances 3×
The workloads that do see dramatic instance reductions are heavily I/O-bound analytics jobs with cold data and sequential scans. Those exist, but they’re not the majority of AWS PostgreSQL deployments.
Async I/O is absolutely worth upgrading for. Just set realistic expectations: you’re buying headroom and efficiency, not cutting your AWS bill in half. And in production, headroom is often more valuable than the theoretical maximum throughput.
The real win? You can handle more load, defer infrastructure scaling, and reduce provisioned IOPS costs—all while running the same instance types you’re already paying for.
Before: 60% CPU, 18% iowait, provisioned 6000 IOPS
After async I/O: 55% CPU, 5% iowait, using 4500 IOPS
Effective gain: 25% IOPS savings, could reduce provisioned IOPS
