RDS Proxy in Production: What the Docs Don't Tell You

A year of RDS Proxy under 16M orders: multiplexing that works, the pinning trap that silently disables it, and the failover win nobody markets.

#aws#rds#rds-proxy#databases#postgres
Cover image for the article: RDS Proxy in Production: What the Docs Don't Tell You

When our Auto Scaling Group learned to grow from 6 to 22 instances, our database learned to hate deploys. Every scale-out event and every rolling deployment sent a wave of new connections at Postgres, and Postgres treats each connection as a process with real memory attached. We put RDS Proxy in front of it a year ago, and it fixed problems the documentation barely mentions while introducing a few it does not mention at all.

Here is what I wish someone had told me before we started.

The problem, in one number

Twenty-two app instances, each holding a pool of up to 200 connections, is a theoretical 4,400 connections pointed at a database that was configured for 1,600. Most of those connections sit idle most of the time. Postgres pays for them anyway.

Bar chart showing RDS Proxy multiplexing: 4,400 client connections held by application pools become only 240 real connections to the database

RDS Proxy sits between the pools and the database and multiplexes: our 4,400 client connections become roughly 240 real ones. That is an 18:1 ratio, and it means a deploy or a scale-out event is invisible to the database. That alone justified the project.

What the docs don't tell you

1. Pinning silently turns the proxy off

Multiplexing only works when a connection is stateless between transactions. The moment your session does something stateful, the proxy "pins" that client connection to a dedicated database connection, and your 18:1 ratio quietly becomes 1:1 for that session.

What causes pinning in practice: session-level SET statements, advisory locks, temporary tables, and, the one that got us, prepared statements created explicitly by an ORM configuration nobody remembered choosing. Our pin rate was 40% for two weeks before we noticed, because nothing fails when pinning happens. It just stops helping.

Watch DatabaseConnectionsCurrentlySessionPinned in CloudWatch from day one. Our alert fires above 5%.

2. The failover story is the real product

Everyone buys RDS Proxy for connection pooling. The bigger win is failover. Without the proxy, a Multi-AZ failover meant every client connection died, every pool reconnected through DNS propagation, and we measured 60 to 90 seconds of errors. With the proxy holding client connections open and re-routing behind the scenes, our last failover test measured 8 seconds of degraded service and zero connection errors in the app logs.

If you run Multi-AZ and care about failover time, that is the feature you are actually paying for.

3. You pay per database vCPU, not per proxy

The pricing surprised our finance review: RDS Proxy charges per vCPU of the target database instance, whether or not the proxy is busy. In front of our 8-vCPU primary it costs the same at 3 a.m. as at dinner rush. It is not expensive for what it does, but model it as a fixed percentage on top of your instance cost, not as a usage-based service.

4. There is a latency tax, and it is fine

Every query now makes an extra network hop. We measured the overhead at 2 to 3 ms on p99, which for us is noise. But if you have a hot path doing hundreds of sequential single-row queries, that tax multiplies, and you should batch those queries anyway.

5. IAM auth is great, until you read the connection limit

The proxy can authenticate apps with IAM instead of passwords, which we loved for eliminating credentials from config. The footnote: IAM auth on the proxy has its own connection-establishment rate limits. Our burst-heavy batch jobs hit them. Those jobs went back to Secrets Manager credentials, and everything else stayed on IAM.

The results

| Metric | Before proxy | After proxy | |---|---|---| | Real DB connections (peak) | 1,400+ | ~240 | | Deploy-time connection errors | dozens per deploy | zero | | Multi-AZ failover impact | 60-90 s of errors | ~8 s, no errors | | p99 latency | baseline | +2-3 ms | | Pin rate (after ORM fix) | 40% | under 2% |

Should you use it?

Yes, if you have an autoscaling app tier, care about failover time, or run serverless functions against a relational database. No, if you run a small static fleet with well-tuned pools and single-AZ tolerance, where it adds cost and a hop for little gain.

And whichever way you go: check your pin rate this week. If you already run RDS Proxy and have never looked at that metric, there is a decent chance you are paying for a proxy that pinning has quietly turned into a pipe.

Comments

    No comments yet. Be the first to share your thoughts.