Run Django on Amazon Aurora PostgreSQL and Aurora Serverless v2
Run Django on Amazon Aurora PostgreSQL: choose provisioned or Serverless v2 capacity, use writer and reader endpoints with a database router, add RDS Proxy for connection pooling and faster failover, set minimum ACUs, and plan upgrades and backups.
Problem statement
Your Django app on AWS has outgrown a single RDS instance, or you want faster failover, many read replicas, or capacity that follows traffic. Aurora PostgreSQL is a PostgreSQL-compatible engine with distributed storage, a writer and up to 15 readers, and a Serverless v2 option that scales in fine-grained capacity units. Django connects with the normal PostgreSQL backend, but you need to decide how to use reader endpoints, how to pool connections, and how to configure Serverless v2 so it does not scale to a painful minimum.
- Create an Aurora PostgreSQL cluster in private subnets; use the cluster (writer) endpoint for Django's
defaultdatabase. - Add the reader endpoint as a
replicaalias and route read-only queries with a database router, keeping read-after-write paths on the writer. - Put RDS Proxy in front for connection pooling and faster failover, especially with many containers or Lambda.
- For Serverless v2, set a minimum ACU that keeps the buffer cache warm (often 1 to 2 ACUs), and a maximum that caps cost.
- Use IAM authentication or Secrets Manager rotation for credentials, and test failover with Django connected.
Step-by-step solution
1. Choose capacity
- Provisioned instances: fixed instance classes for writer and readers. Predictable performance and cost.
- Serverless v2: each instance scales between a minimum and maximum number of Aurora Capacity Units (ACUs), each roughly 2 GB of memory. You can mix serverless and provisioned instances in one cluster.
Serverless v2 suits variable traffic. Setting the minimum too low makes the buffer cache tiny during quiet times, so the first burst after idle is slow. Newer engine versions support scaling to 0 ACUs with automatic pause for dev environments; avoid it for production, because resuming takes seconds.
2. Configure Django
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"HOST": "shop.cluster-abc123.eu-central-1.rds.amazonaws.com",
"NAME": "shop", "USER": "shopapp", "PASSWORD": os.environ["DB_PASSWORD"],
"OPTIONS": {"sslmode": "require"},
"CONN_MAX_AGE": 60, "CONN_HEALTH_CHECKS": True,
},
"replica": {
"ENGINE": "django.db.backends.postgresql",
"HOST": "shop.cluster-ro-abc123.eu-central-1.rds.amazonaws.com",
"NAME": "shop", "USER": "shopapp", "PASSWORD": os.environ["DB_PASSWORD"],
"OPTIONS": {"sslmode": "require"},
"CONN_MAX_AGE": 60, "CONN_HEALTH_CHECKS": True,
"TEST": {"MIRROR": "default"},
},
}
DATABASE_ROUTERS = ["config.routers.ReadReplicaRouter"]
The cluster-ro endpoint load-balances connections across readers. Aurora replica lag is usually tens of milliseconds, but still route reads that must see a just-written row to the writer. See Use Read Replicas With Django.
3. Add RDS Proxy
RDS Proxy keeps a pool of connections to Aurora and multiplexes client connections onto them. Benefits for Django:
- Many ECS tasks or Gunicorn workers share fewer database connections.
- During failover, the proxy holds client connections and reconnects to the new writer, cutting downtime to a few seconds.
- It supports IAM authentication and Secrets Manager credentials.
Point default at the proxy endpoint and replica at a read-only proxy endpoint. Session state such as SET statements can pin connections; Django's normal queries do not.
4. Credentials
Store the password in Secrets Manager with rotation, or use IAM database authentication so tasks generate short-lived tokens from their IAM role. With rotation, make sure Django refreshes credentials on reconnect, for example by reading the secret when opening connections or by restarting tasks after rotation. See Connect Django to AWS RDS With IAM Authentication.
5. Failover, upgrades, and backups
Aurora fails over to a reader in about 30 seconds without RDS Proxy, faster with it. Test it: aws rds failover-db-cluster --db-cluster-identifier shop, and watch Django's error rate. Backups are continuous with point-in-time restore; set retention and test restoring into a new cluster. Major version upgrades can use blue/green deployments to switch with minimal downtime.
Explanation
Aurora separates compute from a storage layer replicated six ways across three availability zones. Readers share that storage, so they need no replication of data files, which keeps replica lag low and makes failover a matter of promoting a reader. For Django, it behaves like PostgreSQL with stable endpoints for the writer and readers. RDS Proxy and Serverless v2 address the two common pain points of containerized Django on AWS: too many connections and capacity that does not match traffic.
Edge cases / notes
- Extensions and versions. Aurora supports most common extensions, but versions lag community PostgreSQL slightly; check before relying on new features.
- Costs. I/O-Optimized pricing suits write-heavy apps; Standard pricing charges per I/O. Compare with your workload.
- Local development. Use standard PostgreSQL locally; Aurora is wire-compatible for Django's purposes.
Next steps
- Route reads correctly with Use Read Replicas With Django.
- Use IAM tokens with Connect Django to AWS RDS With IAM Authentication.
- Plan for failover with PostgreSQL High Availability and Failover for Django.
FAQ
Is Aurora PostgreSQL compatible with Django?
Yes. Use the standard PostgreSQL backend; Aurora is wire-compatible.
Should I use Serverless v2 for production?
It works well for variable traffic. Set a sensible minimum so the cache stays warm and a maximum to cap costs.
Do I need RDS Proxy?
It helps when many containers or functions connect, and it shortens failover impact. Small apps with few connections may not need it.
How do I use Aurora readers from Django?
Add the reader endpoint as a second database and route read-only queries with a database router.