Aurora vs Azure vs Cloud SQL: Managed Postgres
Chat2DB TeamEvery major cloud offers managed PostgreSQL, and on the surface they look interchangeable: you get a Postgres endpoint, automated backups, a standby for failover and a bill. The differences that matter show up later — in how replication actually works, what a failover costs you in seconds, which extensions you are allowed to install, and how much control you retain over the server. This is a comparison of the four options most teams actually evaluate: Amazon Aurora PostgreSQL, Amazon RDS for PostgreSQL, Azure Database for PostgreSQL Flexible Server, and Google Cloud SQL for PostgreSQL.
Prices and SLA percentages change constantly and vary by region, so this article deliberately does not quote numbers you would have to re-verify anyway. Check each provider's current pricing page before committing; what follows is the architectural comparison that does not change every quarter.
The architectural split
The single biggest difference is where the storage lives.
RDS, Azure Flexible Server and Cloud SQL all run community PostgreSQL on a network-attached disk. A high-availability configuration means a second instance in another zone with its own copy of the data, kept in sync by streaming replication. Failover means promoting the standby and repointing DNS.
Aurora replaces the storage layer entirely. The Postgres engine is modified to write log records to a distributed storage service that keeps six copies across three availability zones. Replicas do not have their own copy of the data — they attach to the same storage volume. This produces genuinely different properties:
- Replicas are cheap and fast to add, because there is no data copy. Adding a reader takes minutes and adds no write amplification.
- Replica lag is typically milliseconds, since readers consume log records from shared storage rather than replaying a stream onto their own copy.
- Failover is fast, because the new writer attaches to storage that is already current.
- Storage grows automatically and you pay for what you use rather than what you provisioned.
- Backups are continuous, and point-in-time restore works at the storage layer.
The costs of that design: Aurora is AWS-only and cannot be self-hosted, its I/O is billed separately unless you choose the I/O-optimized configuration, it lags the community project by a version or two, and a handful of extensions that touch storage internals are unavailable. You are also, in a real sense, running a fork — behaviour around VACUUM, FREEZE and replication internals is not always identical to community Postgres.
Feature comparison
| Aurora PostgreSQL | RDS PostgreSQL | Azure Flexible Server | Cloud SQL | |
|---|---|---|---|---|
| Storage | Distributed, 6 copies / 3 AZs | EBS volume | Azure managed disk | Persistent Disk |
| HA model | Storage-level; replica promotion | Synchronous standby (Multi-AZ) | Zone-redundant or same-zone standby | Regional (synchronous standby) |
| Readable replicas | Yes, share storage, low lag | Yes, own copy, async | Yes, own copy, async | Yes, own copy, async |
| Cross-region replica | Yes (global database) | Yes | Yes | Yes |
| Storage autogrow | Automatic | Configurable | Configurable | Automatic |
| Serverless option | Aurora Serverless v2 (scales in place) | No | Burstable tier only | Cloud SQL Enterprise Plus editions |
| Superuser | No (rds_superuser) | No (rds_superuser) | No (azure_pg_admin) | No (cloudsqlsuperuser) |
| Built-in pooler | RDS Proxy (separate service) | RDS Proxy (separate service) | PgBouncer, built in | No (run your own) |
| Major version upgrade | In place, with downtime | In place, with downtime | In place, with downtime | In place, with downtime |
Every one of them withholds superuser. This is the constraint that surprises people migrating from self-hosted Postgres: you cannot ALTER SYSTEM, cannot install arbitrary C extensions, cannot read the data directory, and cannot always use tools like pg_repack in every mode. Parameters are set through the provider's own layer — parameter groups on AWS, server parameters on Azure, database flags on Google — and some are simply not exposed.
Extensions
Extension availability is where a migration quietly fails. Each provider maintains an allow-list, and the list differs.
All four support the essentials: pg_stat_statements, pgcrypto, uuid-ossp, postgis, pg_trgm, hstore, btree_gin, btree_gist, and — now universally — vector for embeddings.
Where they diverge:
pg_cronis available on all four but configured differently, and on some it can only schedule jobs in one specific database.pg_partmanis available on RDS, Aurora and Azure; check the current list for Cloud SQL.timescaledbis available on Azure and (in the open-source edition) on some others, but not on Aurora.- Foreign data wrappers are generally limited to
postgres_fdwand a small set of provider-specific ones. Arbitrary FDWs are not installable. pglogical,wal2jsonand other logical decoding plugins vary, which matters if you are building CDC pipelines.
Verify before you migrate, not after:
SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE name IN ('vector','pg_cron','pg_partman','timescaledb','postgis','pg_stat_statements')
ORDER BY name;Connections and pooling
Postgres forks a backend process per connection, so every managed platform caps max_connections based on instance memory. Small instances allow only a few hundred connections, and serverless or horizontally-scaled applications blow through that immediately.
- Azure includes PgBouncer in the service, enabled with a parameter and exposed on port 6432. Simplest of the three.
- AWS offers RDS Proxy as a separate, separately-billed service that also handles IAM authentication and failover-aware connection handling.
- Google offers no built-in pooler; you run PgBouncer yourself, typically as a sidecar or a small dedicated deployment.
Whichever you use, remember that transaction pooling breaks session-scoped features — SET outside a transaction, session advisory locks, LISTEN/NOTIFY, and server-side prepared statements unless the client disables them. That behaviour is identical everywhere; only the deployment differs.
Authentication and networking
All three clouds support their native identity system as an alternative to passwords: IAM database authentication on AWS, Entra ID on Azure, IAM on Google. All three issue short-lived tokens used in place of a password, and all three integrate with workload identity so an application never holds a database credential. If you are starting fresh, use it — it is the single largest security improvement available, and it makes credential rotation a non-event.
Networking follows each cloud's conventions: VPC security groups on AWS, VNet-injected subnets or firewall rules on Azure, and private services access or the Cloud SQL Auth Proxy on Google. One Azure-specific caveat worth repeating: the choice between private and public access on Flexible Server is permanent for the life of the server, so decide before you create it.
Read replicas and scaling reads
Aurora's shared-storage replicas are its strongest practical advantage. Adding readers is fast, lag is small enough that read-your-writes problems are rare, and the reader endpoint load-balances across them automatically. Aurora Serverless v2 scales capacity in place, which suits spiky and unpredictable workloads better than resizing an instance.
The other three use ordinary asynchronous streaming replication. That works well, but replicas take time to create (a full copy), lag varies with write volume, and you handle read/write splitting in the application or through a proxy. Long-running queries on a replica can also delay WAL replay or cause query cancellations depending on hot_standby_feedback and max_standby_streaming_delay — a class of problem Aurora's design mostly sidesteps.
Lock-in and exit cost
RDS, Azure and Cloud SQL run community PostgreSQL. pg_dump and logical replication move your data to any other Postgres, including a self-hosted one, with no translation. The lock-in is operational — IaC, monitoring, IAM — not structural.
Aurora is different. Your data is still Postgres and still dumps cleanly, so migrating out is possible, but you lose the storage-layer properties your architecture may have come to depend on: cheap readers, fast failover, continuous backup. If replica economics are part of your capacity plan, that is a real dependency to acknowledge up front.
How to choose
Choose Aurora when read scale-out is central to your architecture, when failover time is a hard requirement, or when write volume makes the storage design pay for itself. It is the strongest engineering offering of the four, and its constraints are extension availability and AWS lock-in.
Choose RDS PostgreSQL when you are on AWS, want plain community Postgres, and do not need Aurora's replica economics. It is cheaper at the low end, upgrades track the community more closely, and there are fewer surprises for anyone who has run Postgres before.
Choose Azure Flexible Server when your organisation is on Azure — Entra ID authentication, VNet integration and built-in PgBouncer make it the most cohesive option inside that ecosystem, and the bundled pooler saves a whole component.
Choose Cloud SQL when you are on Google Cloud. It is the most conventional of the four, integrates cleanly with GKE and the Auth Proxy, and its Enterprise Plus editions narrow the performance gap with Aurora considerably.
Consider a specialist provider — Neon, Supabase, Crunchy Bridge — when developer experience matters more than deep cloud integration. Neon's branching model, in particular, gives every pull request its own copy-on-write database, which no hyperscaler currently matches.
Whatever you choose, the client is the same
All four speak the PostgreSQL wire protocol, so the same tools work everywhere. That is genuinely useful during a migration, when you need to compare a source and target side by side.
- Chat2DB (opens in a new tab) — a free AI-powered SQL client that connects to Aurora, RDS, Azure and Cloud SQL (plus MySQL, ClickHouse, Oracle and others) from one window. Natural-language-to-SQL, schema browsing, explain-plan viewing and side-by-side connections make cross-cloud comparison practical; there is a browser version at app.chat2db.ai (opens in a new tab) if you would rather not install anything.
- psql — the reference client, always current with the server, and the only one guaranteed to support every new syntax on day one.
- pgAdmin — the long-standing open-source GUI, strong on administration screens.
- DBeaver — a Java-based universal client with broad driver support.
- Cloud consoles — each provider's built-in query editor is fine for a quick look, but none of them are a working environment.
Summary
The decision is usually made for you by where the rest of your infrastructure lives, and that is a defensible reason. Within a cloud, the real questions are: do you need Aurora's shared-storage replicas and fast failover, are the extensions you depend on on the allow-list, how will you pool connections, and have you verified that a restore actually works? Answer those four before you migrate, and the difference between the platforms becomes much smaller than the marketing suggests.
