Skip to content
L5 Prep

Azure vs Google Cloud

The same distributed-systems primitives, wearing two sets of product names — and the handful of places where the two clouds genuinely disagree.

Design in primitives, not products. A Google interviewer wants "a wide-column store, because every query is a row-key prefix scan" — not a service name. This page is for translating between the two vocabularies and for the follow-up questions, not for the main answer.

Cloud product names drift. Verify anything load-bearing against the vendor docs before you rely on it in an interview — see the system design reference for the vendor-neutral concepts these map onto.

Read this first. In a Google system design round, naming products does not score. “I’d use Bigtable” is a weaker answer than “I need a wide-column store, because every query here is a row-key prefix scan — on GCP that’s Bigtable.” The primitive earns the credit; the product name is a footnote that proves you’ve actually shipped something.

So this file is not a service catalogue to memorize. It exists for three specific jobs:

  1. Translation. If your experience is on Azure, you need to answer “have you worked with anything like Spanner?” without freezing. The concepts transfer; only the nouns change.
  2. The follow-up questions. Interviewers who know cloud will probe: “how would you actually run this?” You need one concrete answer, not a brochure.
  3. The genuine differences. Most services map cleanly and are boring. A handful do not, and those are where an interesting conversation lives. Those are marked ⚠ real difference below.

Volatility warning. Cloud product names drift faster than any other content in this repo. Everything here was verified against vendor documentation on 2026-09-22, with the load-bearing claims fetched directly rather than recalled. Treat specific limits, dates and tier names as probably current and re-check anything you intend to state as fact. The concepts are stable; the nouns are not.

For the vendor-neutral versions of everything here, see 06-system-design-reference.md. That file is the one that actually matters for the interview.


Contents

  1. The five differences that actually matter
  2. Compute
  3. Relational databases
  4. NoSQL, wide-column and key-value
  5. Object storage, durability and the RPO question
  6. Caching
  7. Messaging: the log-vs-queue distinction
  8. Stream processing and analytics
  9. Networking and global entry
  10. Regions, zones and failure domains
  11. Observability
  12. Answering cloud questions in the room

1. The five differences that actually matter

Skip the rest of the file if you’re short on time. These five are the ones worth having an opinion about, because in each case the two clouds made genuinely different architectural choices — which means there’s a tradeoff to discuss, which is what the round is scored on.

# The difference Why it matters
1 Spanner has no Azure equivalent. Globally distributed, horizontally scalable, externally consistent SQL exists on GCP and nowhere else in the same form. It is the reference implementation for “can I have strict serializability across regions?” The answer is yes, and it costs you commit latency.
2 Global load balancing is single-anycast-IP on GCP, layered on Azure. GCP’s global Application Load Balancer is one IP announced worldwide; Azure gets there with Front Door, while its base load balancers are regional. Determines whether cross-region failover involves DNS propagation at all.
3 Cross-region object storage is active-active on GCS, active-passive on Azure. Both replicate asynchronously, but GCS dual/multi-region serves from one namespace with automatic failover; Azure GRS needs an explicit account failover. This is an RTO conversation, and RTO conversations are where senior candidates separate themselves.
4 Pub/Sub is not Kafka. Azure Event Hubs speaks the Kafka protocol and is an offset-addressable partitioned log. GCP Pub/Sub is a topic/subscription system with replay by timestamp — a different consumption model. If your design needs a replayable log, saying “Pub/Sub” without qualification is wrong on GCP.
5 Azure has region pairs; GCP does not. Azure designates partner regions for staggered maintenance and recovery ordering. GCP has regions containing zones, full stop, and pushes all cross-region DR to you. Changes what “multi-region” means by default on each cloud.

Everything after this point is detail.


2. Compute

Mostly symmetric. This is the least interesting section and the one least likely to be probed.

Primitive Azure Google Cloud
Autoscaling VM pool Virtual Machine Scale Sets Managed Instance Groups (zonal or regional)
Serverless functions Azure Functions (Flex Consumption plan) Cloud Run functions
Serverless containers Azure Container Apps Cloud Run
Classic PaaS App Service App Engine
Managed Kubernetes AKS GKE — Standard or Autopilot
Batch/job scheduling Azure Batch GCP Batch

Worth knowing:

  • Cloud Functions is now Cloud Run functions. Google folded 2nd-gen functions into Cloud Run. Using the old name isn’t fatal but dates you.
  • GKE Autopilot vs Standard is a real decision, not a tier. Autopilot bills per-pod and Google owns node management; Standard gives you node pools, instance types and DaemonSets. Autopilot is the closer analogue to “I don’t want to run a cluster” — which usually means you wanted Cloud Run anyway.
  • Azure Functions Flex Consumption is the plan to name if asked, because the classic Consumption plan has no VNet integration. The interesting property is always-ready instances: paying to keep some warm is the explicit cold-start tradeoff, and cold starts are a legitimate design concern worth raising yourself.
  • Cloud Run is broader than it sounds. It covers request-driven services, run-to-completion jobs and queue-consuming worker pools under one product. Container Apps covers similar ground via KEDA.

What scores: treating serverless as a scaling and cost decision, not a fashion. “Traffic is spiky and idles at zero overnight, so scale-to-zero pays for itself; I’d accept the cold start on the first request or keep one instance warm if the p99 requirement forbids it.”


3. Relational databases

Primitive Azure Google Cloud
Managed single-node RDBMS Azure SQL Database; Azure Database for PostgreSQL Flexible Server Cloud SQL (MySQL / PostgreSQL / SQL Server)
Decoupled compute/storage, large + fast restore Azure SQL Database Hyperscale AlloyDB for PostgreSQL
Sharded Postgres (Citus) Flexible Server Elastic Clusters — (use Spanner, or shard yourself)
Globally distributed, strongly consistent SQL — no equivalent — Cloud Spanner

⚠ Real difference: Spanner

Spanner gives external consistency — strict serializability across regions. Transactions get globally ordered commit timestamps derived from TrueTime, an API that returns an interval rather than a timestamp, bounding clock uncertainty using GPS and atomic clocks in every datacenter. To guarantee the ordering, Spanner deliberately waits out that uncertainty interval before committing.

That last sentence is the whole point, and it is the thing to say out loud: Spanner buys global correctness by paying latency on every commit. It is not free, and knowing what it costs is what distinguishes having read about it from having understood it.

Azure has nothing structurally equivalent. Azure SQL Hyperscale scales storage and read replicas but is not a multi-region-write externally consistent system. Cosmos DB offers global distribution and a Strong consistency level — but it’s a NoSQL document store, not a relational engine, and its strong mode carries its own cost (see §4). If you’re asked “what’s the Azure Spanner?”, the correct answer is “there isn’t one, and here’s the closest tradeoff you can actually buy” — not a forced mapping. Saying “there is no equivalent” when there isn’t one is a credibility signal.

Retirement note: Azure Cosmos DB for PostgreSQL (formerly Hyperscale/Citus) is on a retirement path and is not recommended for new work; Microsoft points PostgreSQL sharding at Flexible Server Elastic Clusters. Azure Database for PostgreSQL Single Server is retired in favour of Flexible Server.


4. NoSQL, wide-column and key-value

Primitive Azure Google Cloud
Wide-column, row-key access (Cosmos DB, approximately) Bigtable
Document store Cosmos DB for NoSQL Firestore
Simple entity store Azure Table Storage — (Firestore or Bigtable)
Legacy App Engine datastore Firestore in Datastore mode

Bigtable: the row key is the design

No secondary indexes. Single-row atomicity only. One lexicographically sorted row key, and reading a row range is the fastest operation available. Every access pattern you need must be expressible as a row-key lookup or prefix scan — if it isn’t, you build a second table as a materialized view and maintain it yourself, asynchronously.

This constraint is the source of the classic Bigtable design move: put the access pattern in the key. userId#reverseTimestamp makes “latest N events for this user” a prefix scan returning newest-first. And the matching failure: a key prefixed with a timestamp sends every write to one lexicographic hotspot.

⚠ Worth knowing: Cosmos DB’s five consistency levels

Cosmos DB is unusually instructive here, because it exposes five consistency levels as a runtime choice where most systems hard-code one. Even for a Google interview it is worth knowing, because it’s the cleanest available vocabulary for the spectrum in 06-system-design-reference.md §5:

Level Guarantee
Strong Linearizable. Reads return the most recent committed write. Multi-region strong writes cost roughly 2× the round trip between the two furthest regions.
Bounded staleness Reads lag by at most K versions or T time, whichever comes first — both configurable.
Session Read-your-writes and write-follows-reads within one client session, carried by a session token. The default, and the level most applications actually need.
Consistent prefix You never see writes out of order. You may see stale data, but never a future state before its past.
Eventual No ordering guarantee. A client can even read older values than it previously read.

The reason to know this ladder: it is exactly the “pick consistency per operation, not per system” argument, made concrete by a product that bills differently for each rung. Strong costs latency; Session costs almost nothing and covers most real requirements.

The limits that shape Cosmos DB designs — and the reason partition key choice is the whole game:

  • A logical partition is all items sharing a partition key value. Hard cap: 20 GB.
  • A logical partition maps to exactly one physical partition, capped at 10,000 RU/s — so one partition key value can never exceed 10,000 RU/s, no matter how much throughput you provision.
  • A Request Unit (RU) is the normalized cost currency. Per Microsoft’s own definition, reading a single ~1 KB item by its ID and partition key costs 1 RU. Everything else is priced relative to that.

Both caps are hit the same way: choosing a partition key with too few distinct values. It’s the same hot-shard failure as everywhere else, just with an explicit number attached — which makes it a good concrete example if you’re asked about hot partitions.


5. Object storage, durability and the RPO question

Concept Azure Blob Storage Google Cloud Storage
Hot Hot Standard
Infrequent, 30-day minimum Cool Nearline
Colder, 90-day minimum Cold Coldline
Archive Archive (180-day min, offline — requires rehydration) Archive (365-day min, online)
Automatic tiering Smart tier Autoclass

The archive row is the real difference: Azure archive is offline. Reading a blob requires an explicit rehydration step measured in hours (standard priority up to ~15 hours; high priority under an hour at higher cost). GCS Archive has higher retrieval cost and latency but no rehydration step. If a design says “we archive to cold storage and can retrieve on demand”, that claim is true on GCS and false on Azure — a good detail to get right.

⚠ Real difference: consistency

GCS publishes strong global consistency, and explicitly includes object listing and bucket listing — “you never receive a 404 Not Found response or stale data for an object read-after-write… even for buckets located in dual-regions or multi-regions.” Strongly consistent listing is unusual among object stores, and it’s implemented on top of Spanner. It means the classic “write an object, immediately list the prefix, and your object isn’t there yet” bug does not exist.

Azure Blob Storage is strongly consistent for read-after-write, but Microsoft publishes no dedicated consistency-guarantees page comparable to Google’s, and does not make the same explicit listing claim. I’m stating that as a documentation asymmetry rather than a behavioural one, because I could not verify a behavioural difference. Don’t assert more than that in a room.

⚠ Real difference: replication topology and RPO

This is the most useful storage fact in the file, because it’s an explicit, quantified RPO/RTO tradeoff — exactly the kind of thing §8 of the reference says to raise unprompted.

Azure Google Cloud
Single datacenter LRS — 3 copies, synchronous
Across zones, one region ZRS — synchronous. Write acknowledged only after all three zones have it Region — synchronous across ≥2 zones. Automatic zonal failover, RTO 0
Across regions GRS / GZRS — asynchronous Dual-region / multi-region — asynchronous
Read from secondary RA-GRS / RA-GZRS Inherent — one namespace
Tightened RPO option Geo priority replication → RPO ≤ 15 min (block blobs) Turbo replication (dual-region only) → RPO ≤ 15 min

Both clouds replicate across regions asynchronously, so both have a non-zero RPO by default and both sell essentially the same ~15-minute bounded-RPO upgrade. The difference is what happens during a regional outage:

  • Azure GRS/GZRS is active-passive. The secondary is a copy. Making it writable requires an explicit account failover, which is an operation someone has to trigger. RTO is a real, non-zero number that depends on a human or an automation you wrote.
  • GCS dual-region and multi-region are active-active under a single bucket namespace. There is no failover step and no path change, because there was never a second endpoint. Google documents RTO 0 for this.

Both are defensible. Active-passive is cheaper and gives you an explicit decision point before you cut over — which some compliance regimes actually want. Active-active removes the decision, and the human latency attached to it.

What scores: “Cross-region replication is asynchronous on both clouds, so I have a non-zero RPO — call it 15 minutes with the priority replication option enabled. That’s fine for user uploads and not fine for the transaction ledger, which is why the ledger goes in Spanner and not in object storage.”


6. Caching

Primitive Azure Google Cloud
Managed Redis Azure Managed Redis (built on Redis Enterprise) Memorystore for Redis / Redis Cluster
Managed Valkey Memorystore for Valkey
Managed Memcached Memorystore for Memcached

Azure Managed Redis (AMR) supersedes Azure Cache for Redis. The legacy tiers have published retirement dates: Enterprise and Enterprise Flash on 2027-03-31, and Basic, Standard and Premium on 2028-09-30. If you worked with “Azure Cache for Redis”, that’s still the right thing to say about past work — just know it’s the previous generation.

GCP’s Valkey offering reflects the post-license-change Redis fork; it exists on GCP and not as a first-party Azure product, which is a minor but real asymmetry.

Nothing here changes a design. Cache placement, invalidation and stampede protection are the parts that score (06-system-design-reference.md §6); the product name is not.


7. Messaging: the log-vs-queue distinction

This is the section most likely to produce a wrong answer, because the mapping is not one-to-one.

Primitive Azure Google Cloud
Queue — competing consumers, consume-and-remove Service Bus queues; Queue Storage Pub/Sub; Cloud Tasks
Topic fan-out Service Bus topics Pub/Sub topics + subscriptions
Replayable partitioned log Event Hubs (Kafka-protocol compatible) Managed Service for Apache Kafka
Event routing to serverless Event Grid Eventarc

⚠ Real difference: there is no Pub/Sub ↔ Kafka equivalence

Azure Event Hubs is a Kafka-shaped log. Partitions, consumer groups, retained offsets, and a native Kafka protocol endpoint so most Kafka clients work by changing the bootstrap server. Capture archives the stream to blob storage for long-term retention.

GCP Pub/Sub is not that. It is a topic/subscription system. It has retention and can replay by seeking to a timestamp, but it is not offset-addressable per partition and does not give you the Kafka consumption model. When a design genuinely needs a replayable partitioned log on GCP — reprocessing history after a bug, or multiple independent consumers at different positions — the honest answer is Managed Service for Apache Kafka, not Pub/Sub.

(Pub/Sub Lite was the closer partitioned-log analogue. New access ended 2024-09-24 and it turns down 2026-03-18. Don’t cite it.)

Pub/Sub delivery semantics, since this is exactly the at-least-once discussion from the reference §7:

  • At-least-once is the default, and the only option for push and export subscriptions.
  • Exactly-once delivery is supported — but only on pull subscriptions. This is a genuine constraint, not a footnote: if your design says “push subscription with exactly-once”, it’s wrong.
  • Ordering keys give in-order delivery per key, on both push and pull, with a throughput ceiling per key (~1 MBps). Same tradeoff as a Kafka partition key: ordering is scoped to the key, and the key is therefore also your parallelism limit.

Service Bus ordering works differently again: FIFO requires sessions, enabled at creation time via a SessionId set by the sender. Without sessions, concurrent consumers give you no ordering guarantee. Both Service Bus queues and subscriptions have a built-in dead-letter sub-queue, which does not self-clean — a DLQ nobody drains is an outage in slow motion.

What scores: “I need replay, because a bug in the consumer means reprocessing three days of events. That rules out a plain queue — I want a log. On GCP that’s managed Kafka; Pub/Sub’s timestamp seek isn’t the same consumption model.”


8. Stream processing and analytics

Primitive Azure Google Cloud
Unified batch + stream programming model — (closest: Spark Structured Streaming on Databricks) Dataflow (Apache Beam)
SQL-based stream processing Stream Analytics Dataflow, or BigQuery
Managed Spark Azure Databricks Dataproc
Orchestration / ETL Data Factory; Fabric Cloud Composer; Dataflow
Serverless warehouse Synapse → Microsoft Fabric BigQuery

Both clouds implement the watermark model from reference §7. Stream Analytics defines its watermark as the latest observed event time minus a configured out-of-order tolerance, dropping events beyond it. Dataflow implements the full Beam model — event-time windows (fixed, sliding, session), watermarks as a lower bound on “nothing older than this will arrive”, triggers, and explicit allowed-lateness handling.

Beam is the more complete model and is worth naming for that reason: it was designed around the observation that batch is a special case of streaming, not a separate thing.

BigQuery is the cleaner architecture story: genuinely serverless, storage and compute physically separated, queries executing on dynamically allocated slots, billed either per-byte-scanned on demand or via slot reservations. For ingestion, the Storage Write API replaced legacy streaming inserts — its default stream is at-least-once with immediate query availability, and application-created streams support exactly-once with transactional commits. That’s the same at-least-once-plus-idempotency pattern as everywhere else.

Azure’s analytics story is mid-transition, which is itself the honest comparison: Microsoft is steering new work to Fabric while Synapse remains supported. If you have Synapse experience, say so plainly and note you’re aware Fabric is the current direction. Being current about your own stack is a small credibility signal.


9. Networking and global entry

Primitive Azure Google Cloud
L4 load balancer Azure Load Balancer Network Load Balancer
L7, regional Application Gateway (+ WAF) Regional external Application Load Balancer
L7, global Azure Front Door Global external Application Load Balancer
DNS-based traffic routing Traffic Manager — (the global LB subsumes this role)
CDN Front Door Standard/Premium Cloud CDN; Media CDN
API management API Management (APIM) Apigee (enterprise) / API Gateway (lightweight)

⚠ Real difference: how each cloud achieves “global”

GCP: one anycast IP. The global external Application Load Balancer gets a single global IP address, announced by BGP from Google’s edge POPs worldwide. A client connects to the nearest POP, and traffic crosses Google’s private backbone to a healthy backend region. Cross-region failover involves no DNS change, because the IP never changes. There is nothing to propagate and no TTL to wait out.

Azure: layered. Azure Load Balancer and Application Gateway are regional resources with regional IPs. Global entry comes from one of two things:

  • Traffic ManagerDNS-based. Clients resolve to a different regional IP per policy. This means failover is subject to DNS TTL propagation, with all the usual caching problems. Reference §3 already warns that DNS-based failover is slow; this is that warning, concretely.
  • Azure Front Dooranycast-based, like GCP’s. One global entry point on Microsoft’s edge network, with the backbone carrying traffic onward and automatic failover.

So the capability exists on both clouds. The difference is where it lives: GCP builds anycast into the core load balancer; Azure puts it in a separate edge product, and the base load balancers remain regional. If someone describes global failover via Traffic Manager and doesn’t mention DNS propagation, that’s the gap.

API gateways don’t map one-to-one. APIM is a full-lifecycle enterprise product — policies, developer portal, analytics. Its true GCP counterpart is Apigee. GCP’s API Gateway is a much lighter serverless proxy (OpenAPI, API keys, JWT) with no portal or monetization. Mapping APIM to API Gateway on name similarity is a mistake.

Retirement note: the classic Azure CDN and Front Door (classic) products are being retired — Front Door (classic) on 2027-03-31 and Azure CDN Standard from Microsoft (classic) on 2027-09-30 — with migration to Front Door Standard/Premium.


10. Regions, zones and failure domains

⚠ Real difference: Azure pairs regions, GCP does not

Azure has a two-tier vocabulary:

  • Availability Zones — physically separate datacenters within one region, with independent power, cooling and networking. This is the intra-region failure domain.
  • Region pairs — a designated partner region in the same geography, used to stagger planned maintenance and to prioritize recovery sequencing during a large outage.

Two caveats Microsoft states explicitly and candidates routinely miss: newer Azure regions may be non-paired, relying on zones instead, and deploying to a paired region does not give you automatic failover. Pairing governs how Microsoft sequences maintenance and recovery — you still architect, and test, your own DR.

GCP has one tier. Regions contain three or more zones. There is no formal pairing construct. All cross-region DR is explicitly yours: choose your regions, choose synchronous or asynchronous replication based on your RPO, and use the global load balancer for failover.

Neither is better. Azure’s pairing is a genuine operational benefit that also invites a false sense of safety; GCP’s model is simpler and more honest about where the responsibility sits. The interview-useful version: “availability zones protect against a datacenter failure; nothing protects you from a regional failure except a deliberate multi-region design and a tested failover.”


11. Observability

Primitive Azure Google Cloud
Umbrella brand Azure Monitor Google Cloud Observability (formerly Stackdriver)
Metrics, dashboards, alerts Azure Monitor Metrics Cloud Monitoring
Log store + query language Log Analytics (KQL) Cloud Logging
Distributed tracing Application Insights Cloud Trace
Continuous profiling Application Insights Profiler Cloud Profiler

Cloud Trace is Dapper’s descendant, which is a nice thing to know given Dapper is on the Week 6 reading list — same idea, same sampling-for-overhead tradeoff.

Nothing here differentiates the clouds meaningfully. What differentiates you is §8 of the reference: alerting on symptoms rather than causes, specifying percentiles rather than averages, and knowing that sampling is mandatory at scale.


12. Answering cloud questions in the room

If asked “how would you deploy this?” — answer in one or two sentences with concrete products, then return to the design. It’s a credibility check, not a change of subject. Don’t volunteer a full deployment architecture nobody asked for.

If asked about a service you haven’t used — map it to the primitive and say so. “I haven’t run Spanner in production. I’ve used Azure SQL with read replicas, so I’ve dealt with replica lag and read-your-writes; what Spanner adds is external consistency across regions, paid for with commit latency.” That answer is worth more than a fluent recital, because it demonstrates the transfer is real.

If your experience is Azure and you’re interviewing at Google — this is fine, and pretending otherwise is worse than the gap. Engineers are hired for judgment, not for vendor trivia. Say which cloud you know, speak in primitives, and use the GCP name when you’re confident of it.

Never claim production experience you don’t have. The follow-up is always “what went wrong with it?”, and there is no way to answer that from documentation. Reference §11 calls intellectual humility a screened-for trait — this is where it gets tested for real.

The self-check: could you give this entire design without naming a single product? If not, you’re leaning on vendor names to cover a gap in the underlying reasoning — and that gap is exactly what the deep dive is designed to find.