Your coding agent’s query_schema tool just opened a new Postgres connection from every Lambda concurrent execution — fifty tenants, three tools each, and RDS max_connections is already rejecting logins while idle sockets pile up in abandoned chat turns. Amazon RDS Proxy is the unfair advantage for agent DB tools: one managed pool in front of Aurora/RDS, IAM auth, and failover that does not force every tool to reinvent pooling. Pair with Secrets Manager rotation for DB secrets and DynamoDB Transactions when the ledger is NoSQL — this post is the relational connection-pooling layer for coding-agent tools.
⚡ TL;DR: Put RDS Proxy between agent runtimes (Lambda, Fargate Spot, CodeBuild) and Aurora/RDS. Prefer IAM DB auth or short-lived Secrets Manager creds; avoid session pinning unless the tool needs temp tables or
SET LOCAL. Cap Proxy client connections and RDSmax_connectionswith Budgets watching Proxy CU. Related: Fargate Spot sandboxes, IAM condition keys, SCPs.
Why agent DB tools thrash RDS without a proxy
Coding-agent database tools are bursty, concurrent, and forgetful:
- Planner calls
describe_table/run_readonly_sql/apply_migration_preview - Runtime opens a connection, runs one statement, returns JSON
- Chat turn ends — connection may linger until GC or Lambda freeze
- Next turn may land on a different execution environment
Without a proxy you get connection storms on every traffic spike, slow failovers during Aurora patching, and credentials baked into every sandbox image. RDS Proxy multiplexes many client connections onto fewer DB connections and handles failover for you.
| Approach | Connection storms | Failover UX | Best agent shape |
|---|---|---|---|
| Direct RDS from Lambda | ❌ Easy to melt | ❌ Clients reconnect blindly | Tiny single-tenant tools |
| App-level pool in Fargate | ✅ If one long process | ⚠️ DIY | Always-on IDE backends |
| RDS Proxy | ✅ Multiplexed | ✅ Transparent | Burst tool fleets |
| DynamoDB / MemoryDB | N/A | Managed | Session/ledger, not SQL schema |
Wire Proxy into agent runtimes
Create a proxy targeting Aurora PostgreSQL (or MySQL), put it in private subnets, and point tools at the proxy endpoint — never at the cluster writer DNS from agent code.
// ✅ CDK sketch: RDS Proxy for coding-agent SQL tools
import * as rds from "aws-cdk-lib/aws-rds";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
const dbSecret = secretsmanager.Secret.fromSecretNameV2(this, "DbSecret", "agent/db/app");
const proxy = new rds.DatabaseProxy(this, "AgentDbProxy", {
proxyTarget: rds.ProxyTarget.fromCluster(auroraCluster),
secrets: [dbSecret],
vpc,
requireTLS: true,
iamAuth: true,
maxConnectionsPercent: 80,
maxIdleConnectionsPercent: 25,
// ✅ borrow timeout beats hanging agent tools
// (engine-specific knobs via CfnDBProxyTargetGroup)
securityGroups: [proxySg],
dbProxyName: "coding-agent-sql",
});
// Lambda tool role: connect via IAM auth to proxy
toolFn.addToRolePolicy(
new iam.PolicyStatement({
actions: ["rds-db:connect"],
resources: [
`arn:aws:rds-db:${region}:${account}:dbuser:${proxy.dbProxyArn}/*`,
],
conditions: {
StringEquals: { "aws:PrincipalTag/tenant_id": "${aws:PrincipalTag/tenant_id}" },
},
})
);
# ✅ tool handler: connect through Proxy with IAM token (psycopg)
import boto3, psycopg
def open_agent_conn(tenant_id: str):
rds = boto3.client("rds")
token = rds.generate_db_auth_token(
DBHostname=PROXY_HOST,
Port=5432,
DBUsername="agent_ro",
Region=REGION,
)
# ❌ Never reuse a global connection across tenants
return psycopg.connect(
host=PROXY_HOST,
user="agent_ro",
password=token,
dbname="app",
sslmode="require",
connect_timeout=5,
options=f"-c statement_timeout=8000 -c application_name=agent:{tenant_id}",
)
Rule: one tool invocation → one short-lived client connection through Proxy. Do not hold sockets across WebSocket chat turns (API Gateway WebSockets sessions are not DB sessions).
Session pinning: when it helps and when it hurts
RDS Proxy pins a client to a DB connection when the session holds state the pool cannot safely share (temp tables, SET, prepared statements in some engines, explicit transactions left open).
For coding agents:
- ✅ Prefer stateless, auto-commit, read-only tools — no pin, max multiplexing
- ✅ Migrations / DDL previews: run in a dedicated sandbox DB or short pinned transaction, then close
- ❌ Leaving
BEGINopen while the LLM “thinks” for 40 seconds — pin + idle timeout = failures
-- ✅ agent tool: single statement, statement_timeout enforced
SET statement_timeout = '8s';
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = $1;
# ❌ pinned forever: agent opens txn, streams tokens, never commits
conn = open_agent_conn(tenant)
cur = conn.cursor()
cur.execute("BEGIN")
cur.execute("CREATE TEMP TABLE preview AS SELECT * FROM orders LIMIT 100")
# ... LLM waits for user confirmation for minutes ...
IAM, secrets, and blast radius
- Store master/app passwords in Secrets Manager with rotation; Proxy consumes the secret
- Prefer IAM DB authentication for agent_ro / agent_migrate roles so tokens expire in minutes
- Tag tool roles with
tenant_id; pair with IAM condition keys and SCPs denyingrds:ModifyDBProxyfrom agent OUs - Authorize which tools may call SQL via Verified Permissions / Cedar
{
"Effect": "Deny",
"Action": ["rds:ModifyDBProxy", "rds:DeleteDBProxy", "rds:CreateDBInstance"],
"Resource": "*",
"Condition": {
"StringEquals": { "aws:PrincipalTag/workload": "coding-agent" }
}
}
Observability and capacity
Watch Proxy ClientConnections, DatabaseConnectionsPercent, QueryDatabaseResponseLatency. Spike + pin rate rising usually means a tool left transactions open. Emit EMF with tenant_id (CloudWatch EMF pattern) so one noisy tenant cannot hide behind fleet averages. Cap spend with Budgets + Cost Anomaly on RDS + Proxy CU.
| Symptom | Likely cause | Fix |
|---|---|---|
too many connections on RDS |
Proxy max % too high or pin storm | Lower maxConnectionsPercent; fix open txns |
| Tool timeouts after failover | Clients cached old writer IP | Always use Proxy endpoint DNS |
| IAM auth failures | Clock skew / wrong resource ARN | Fix rds-db:connect ARN to proxy resource id |
| Cross-tenant data leak | Shared app user + no RLS | Per-tenant DB user or Postgres RLS + SET ROLE |
Production checklist
- [ ] Agent tools connect only to Proxy endpoint (TLS required)
- [ ] IAM DB auth or rotating Secrets Manager creds — no static passwords in images
- [ ] statement_timeout / idle_in_transaction timeouts set server-side
- [ ] Read-only tools use a least-privilege DB user; DDL gated behind Cedar + kill switch (AppConfig)
- [ ] Security groups: Lambda/Fargate → Proxy → RDS only; no public Proxy
- [ ] Alarms on DatabaseConnectionsPercent and ClientConnections
- [ ] Failover drill documented; tools retry idempotently (tool schemas)
- [ ] Ledger/session state stays in DynamoDB/MemoryDB — Proxy is for relational schema tools
FAQ
Q: Do I need Proxy if agents only hit DynamoDB?
A: No — this pattern is for Aurora/RDS SQL tools. Keep transactional ledgers on DynamoDB Transactions.
Q: Can Fargate Spot sandboxes use Proxy?
A: Yes — short-lived clients are exactly what pools love. Just do not pin across Spot SIGTERM (Fargate Spot).
Q: Proxy vs PgBouncer on ECS?
A: Self-managed pools work until failover and IAM auth become your weekend job. Proxy is the managed default for agent fleets on AWS.
RDS Proxy turns coding-agent SQL tools from a connection storm into a multiplexed, IAM-aware path. Keep tools stateless, timeouts tight, and credentials short-lived — then let Aurora scale without drowning in idle sockets.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Spec-First AI Development: OpenAPI Remains the Only Source of Truth
- REST API Design Best Practices: The Patterns That Make APIs a Joy to Use
- Distributed Locks Reality Check: When Redis Redlock Is the Wrong Tool
- Python asyncio vs Threading: The Benchmark That Changes How You Think About Concurrency
Newly added
- AWS IAM Roles Anywhere: Cert-Based Creds for On-Prem Coding-Agent Runners
- Amazon Macie: Scan Coding-Agent Artifact Buckets for Leaked Secrets
- Amazon GuardDuty: Catch Compromised Coding-Agent Credentials Early
- AWS Network Firewall: Egress Filtering for Coding-Agent Sandboxes
- Amazon RDS Proxy: Connection Pooling for Coding-Agent Database Tools
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.