---
cuppy_hub: gcp
cuppy_path: guides/parity/databases.md
cuppy_section: docs
cuppy_doc: JRKM-QZVV
cuppy_doc_uuid: f3f896c2-bcd7-47ae-9ea7-0ff6caaf8b04
cuppy_permalink: https://cuppy.io/gcp/d/JRKM-QZVV
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/gcp/docs/guides/parity/databases
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: e2b96d86cbe51e64fc83e844996b7be8026b055bb1214a8f3a56e2324cc6da49
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Database parity

## 1. The names, with the two honest gaps marked

| Google Cloud | AWS | Azure |
|---|---|---|
| Cloud SQL (MySQL, PostgreSQL) | Amazon RDS, Aurora | Azure Database for MySQL flexible server, Azure Database for PostgreSQL |
| Cloud SQL (SQL Server) | RDS for SQL Server | the **Azure SQL family**: Azure SQL Database, Azure SQL Managed Instance, SQL Server on Azure VMs |
| **AlloyDB** | Aurora PostgreSQL | Azure Database for PostgreSQL (no exact tier match) |
| **Spanner** | Aurora, Aurora DSQL — **no exact counterpart** | Cosmos DB for NoSQL *and* Azure Database for PostgreSQL — **Microsoft's own table gives two, which is the gap** |
| Firestore | DocumentDB, DynamoDB | Cosmos DB |
| Firestore real-time updates | DynamoDB Streams (not equivalent) | Cosmos DB **change feed** |
| Bigtable | DynamoDB; EMR-hosted HBase for the ecosystem | Azure Table Storage (**name match, not capability match**) |
| Memorystore | ElastiCache | Azure Managed Redis |

**Two rows deserve the warning they carry.** Microsoft's table maps Spanner to *two* unrelated Azure services,
and both tables map Bigtable to *Table Storage* — a product that is not a petabyte-scale HBase-ecosystem store.
A name table is the right tool for finding a starting point and the wrong tool for sizing a migration. These
two rows are where that shows most.

## 2. Managed relational — the availability model, not the engine, is the difference

| | Google Cloud | AWS | Azure |
|---|---|---|---|
| HA shape | **a standby VM in another zone**, within one region | Multi-AZ instance or Multi-AZ cluster | zone-redundant HA within a region |
| editions | Cloud SQL **Enterprise** and **Enterprise Plus** (PostgreSQL, MySQL) | RDS vs Aurora, plus instance classes | Flexible Server tiers; the Azure SQL family is three products |
| what a maintenance update costs | an **instance restart**, with downtime; **Enterprise Plus can achieve "sub-second downtime"** | a maintenance window with failover | a maintenance window |
| the credential-free path | **IAM database authentication** + a connector + `roles/cloudsql.client` | IAM authentication for RDS | Microsoft Entra authentication |

**Three estimate-bearing readings.**

1. **All three put managed relational HA inside one region.** A cross-region requirement is a read replica, a
   secondary, or a different product on every cloud — so a promise of "the same RPO" has to name the mechanism,
   not the service.
2. **The SQL Server row is one-to-three on Azure.** Cloud SQL for SQL Server maps onto the Azure SQL family,
   and *which member* you land on determines the compatibility surface: SQL Managed Instance is near-complete
   SQL Server, Azure SQL Database is not. Deciding that row is a workload-by-workload assessment, and it is
   usually the single largest unknown in a SQL Server migration either way.
3. **The maintenance-restart question is edition-shaped on Google Cloud.** If the application cannot absorb a
   restart, the answer is Enterprise Plus, and it belongs in the estimate as an edition line rather than as an
   operational risk.

## 3. Spanner has no like-for-like counterpart — say so in the estimate

Google Cloud's published configurations: **regional** (three read-write replicas across zones, **99.99%**),
**dual-region** and **multi-region** (both **99.999%**, both Enterprise Plus, multi-region accepting writes in
more than one location at higher write latency).

The combination — relational semantics, horizontal write scaling, and a published multi-region *write*
capability — is not matched by a single service on either other cloud. Aurora DSQL and Cosmos DB each cover
part of it. So:

- **onto Spanner:** a possible **simplification** for an application that currently shards manually, and an
  **application change** otherwise.
- **off Spanner:** an **architecture change**, costed as one. Any estimate that lines Spanner up against a
  counterpart and multiplies by instance count is wrong before it starts.

Also carry the edition fact: two of the three configurations require **Enterprise Plus**, so a later move from
regional to multi-region is an edition change as well as a topology change.

## 4. Document and wide-column — where the lift exists, and where it does not

| | The lift | The work |
|---|---|---|
| **Firestore native mode** | **MongoDB compatibility** means a MongoDB-driver application has a path that is not a rewrite (native mode only, **not** Datastore mode) | its **real-time updates** and direct client libraries have no single counterpart — on the far side that is a change feed **plus** an API tier **plus** a new authorisation model. Two or three components, routinely missed |
| **Bigtable** | **HBase ecosystem integration** — an HBase application moves with a client-library change. The cleanest lift in this family | everything else is a **data-model exercise**: one index, the row key, no secondary indexes and no joins |
| **Firestore Datastore mode** | — | it exists for a dependency on the Datastore APIs. Nothing elsewhere has them; a move off is a rewrite of the data layer |

**And one trap that is not a migration cost at all but presents as one.** Bigtable is **strongly consistent on
a single cluster and eventually consistent by default on multiple clusters**. A team that adds a cluster for
availability during a migration changes the consistency model mid-move, and then attributes the resulting bugs
to the migration. Configure read-your-writes or strong consistency explicitly
(`reference/databases/errors.md` §5).

## 5. Pricing dimension (never a price)

| | Google Cloud | AWS | Azure |
|---|---|---|---|
| managed relational | instance size (vCPU/memory) + storage + backups + **edition**; network egress | instance class + storage + I/O (or Aurora's I/O-optional) + backups | vCPU + storage + backup, by tier |
| the Google-built relational | **AlloyDB**: nodes per instance, plus storage | Aurora: capacity + I/O or Aurora Serverless ACUs | — |
| horizontally scaling relational | **Spanner**: compute capacity in **nodes / processing units**, plus storage; configuration changes the replica count | Aurora DSQL: request units | Cosmos DB: **request units** + storage |
| document | Firestore: operations + storage + network | DynamoDB: RCU/WCU or on-demand requests + storage | Cosmos DB: RUs + storage |
| wide-column | Bigtable: **nodes** + storage on Colossus | DynamoDB: as above | Table Storage: transactions + storage |

**The structural trap in this table:** Google Cloud mostly meters **provisioned capacity** (nodes, processing
units, instance size) where DynamoDB and Cosmos DB meter **request units**. Those are not convertible without
a workload profile. A migration estimate that converts an RU/s figure into node count by ratio is guessing;
the only honest conversion runs through measured read/write volumes and item sizes.
`guides/parity-and-migration-method.md` treats that as a required input, not an optional one.

## 6. What this guide cannot tell you

Whether a given SQL dialect, extension or stored-procedure estate ports. On the relational side that is the
whole of the work and it is per schema. Use the migration family's assessment tooling
(`reference/migration/database-migration-service.md`) rather than a table.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 91 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/gcp/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
