Moving a production stack from Azure to Google Cloud

Jesse James Richard
|
|
8 min read
#Method
#Architecture
#AI & Agents

I ran two years of production on Azure. Giant Context has run on Google Cloud since its first commit. The industry treats a cloud as a career specialisation that goes on a CV and rarely changes. Most of it is the same set of services under a different set of names.

That Azure stack was twenty-one function apps, a service bus, a Kusto cluster for analytics, a key vault, B2C identity, blob storage and App Insights watching all of it. The whole mapping to Google Cloud came to this:

AzureGoogle Cloud
FunctionsCloud Run
API ManagementAPI Gateway
Service BusPub/Sub
Data Explorer (Kusto)BigQuery
Key VaultSecret Manager
AD B2CIdentity Platform
Blob StorageCloud Storage
App InsightsCloud Logging + Monitoring
Azure OpenAIGemini on Vertex

Cold starts, dead letters, log retention, key rotation, what to do when a queue backs up at two in the morning. All of that is knowledge about queues and processes and secrets, and every bit of it transferred from the left column to the right.

Cloud skills transfer

Cloud skills get treated, by hiring pipelines and by engineers themselves, as though the platform were the skill. A CV says Azure engineer or GCP certified, and a company says it is an AWS shop.

The vendor-specific layer takes a few weeks to learn. What took two years was the instinct for queues, identity, blast radius, cost and observability, and none of that belongs to a vendor. Converting one into the other needed no course, no certification and no consultant, and the mapping was one table long.

Capability is a tie

Across two years on one and the whole of this project on the other, I have not hit a wall where the platform could not do what I needed. Both of them host, queue, store, secure and observe anything I can conceive of building.

Who each cloud is built for

Azure is built for an organization. Subscriptions arranged in management groups, procurement, portals inside portals and governance to configure before anything deploys. All of that exists because its customer has a compliance team and a budget owner who are not the person writing the code.

Google Cloud assumes a project ID and a terminal. The unit of everything is a project, a project is free to create, and a person working alone never has to model an org chart before deploying a container.

A CLI inherits whatever resource model sits under it, so the same job takes a different number of words. Deleting the destination that messages arrive in, on each side:

Deleting the destination messages arrive in

az servicebus queue delete \  --name myqueue \  --namespace-name mynamespace \  --resource-group group1
gcloud pubsub topics delete my-topic

A Service Bus queue lives inside a namespace inside a resource group inside a subscription, so the command names all three every time. A Pub/Sub topic lives in a project, the project is set once in configuration, and everything after it inherits that. The gap repeats on everything typed in a day.

The overhead Azure asks for is doing real work in a company of two hundred, and it is pure cost in a project of one.

The meters

Every service in the stack, at list price, with the free tier attached:

ServiceAzureGoogle Cloud
ComputeFunctions Consumption: $0.20 per million executions plus $0.000016 per GB-second. First 1M executions and 400,000 GB-seconds free.Cloud Run: $0.000024 per vCPU-second, $0.0000025 per GiB-second, $0.40 per million requests. First 2M requests and 180,000 vCPU-seconds free.
MessagingService Bus Standard: $0.0135 per hour for the namespace, about $9.86 a month before a single message, plus operations. First 13M operations free.Pub/Sub: $40 per TiB of throughput. First 10 GiB free. No standing charge.
AnalyticsData Explorer: the full VM cost of the cluster plus a $0.11 per vCore-hour markup on engine nodes. It cannot scale to zero.BigQuery: $6.25 per TiB scanned, first 1 TiB each month free. Storage $0.023 per GiB-month, first 10 GiB free.
IdentityB2C: first 50,000 monthly active users free, then $0.03 each.Identity Platform: first 50,000 monthly active users free, then $0.0055 each.
SecretsKey Vault: $0.03 per 10,000 operations. No charge to hold a secret.Secret Manager: $0.06 per version per month, plus $0.03 per 10,000 accesses. First 6 versions free.
Object storageBlob Storage Hot: $0.0208 per GB-month.Cloud Storage Standard: $0.020 per GiB-month. First 5 GB free.
LogsAzure Monitor: $2.30 per GB ingested. First 5 GB a month free.Cloud Logging: $0.50 per GiB ingested. First 50 GiB a project each month free.

Identity is five and a half times cheaper on Google above an identical free tier. Logging is four and a half times cheaper with ten times the free allowance, which on a platform that writes a log line per request is the difference between a line item and nothing. Service Bus Standard charges $9.86 a month before a single message arrives, where Pub/Sub charges for throughput and nothing else. Data Explorer needs a cluster that exists whether or not anyone queries it, and BigQuery has nothing to provision. Object storage and secrets land within a fraction of a cent of each other.

Cloud Run bills for instance time, and an instance can serve many requests at once. Google publishes two worked examples for the same workload, ten million requests a month at four hundred milliseconds each on one vCPU and 512 MiB of memory. At twenty requests per instance it estimates $13.69 a month. At one request per instance it estimates $81.72.

Six times the bill for identical traffic on an identical machine. Nothing changed except whether the container was allowed to handle more than one request at a time.

This platform is seven services, each with modest traffic, all mostly idle, all thread-safe enough to take concurrent requests. Billed per invocation that is seven meters running at once. Billed as instance time with concurrency, the same seven services are containers asleep most of the day.

With steady load at scale, provisioning is often the cheaper answer and Azure is right. Early, with spiky load and long idle stretches, it is the expensive one. Azure has hosting plans that behave like Cloud Run, and where a service is saturated the two converge.

Identity

I have run identity in production on Azure and on Google Cloud. B2C has user flows for the ordinary cases, configured in the portal, and they are fine. Anything outside them lands in the Identity Experience Framework, where an authentication journey is expressed as custom policies. Microsoft's own documentation describes those as multiple XML files referring to each other in a hierarchical chain, defining claims schemas, claims transformations, content definitions, claims providers, technical profiles and user journey orchestration steps. The starter pack is three files inheriting from one another: a base nobody is supposed to edit, an extensions file where the work happens, and a relying-party file the application actually invokes.

The documentation is candid about the cost, saying developers must define the trusted relationships in careful detail, including metadata endpoints, exact claims exchange definitions and the secrets, keys and certificates each identity provider needs. That is why the B2C integration on that platform was built by a specialist rather than by the team using it, and why nobody else could confidently change it afterwards.

Identity Platform is enabled from a console page, and the client-side integration is four calls: sign in with a provider, sign in with a password, send a reset email, sign out. The server verifies a token with the provider's library. There is no policy language, and nothing to inherit from.

B2C can express authentication journeys Identity Platform cannot, and an enterprise federating a dozen identity providers with bespoke claims mapping needs exactly that. A platform that needs Google sign-in and email with a password does not, and paying for the expressive version means paying for the specialist who understands it.

The AI bet

I thought Google would lead on AI, and choosing a cloud meant choosing whose models the platform would live next to. Keeping models, data, identity and billing on one provider was already the pattern, set a month earlier when the database moved off Firebase to Postgres on Cloud SQL. Gemini running in that same cloud made the decision for me. Whether that guess was right is not settled, and I will find out the same way everyone else does.

What Giant Context runs on:

The decision

Four things decided it. The instincts transferred, so the switch cost weeks rather than a career. The meters favoured what I was building, many small services mostly idle, where a standing charge is what hurts. Models, data, identity and billing sit with one vendor and arrive on one bill. And I think Google will lead on AI, which is the only one of the four I cannot check yet. Azure would have run this platform perfectly well, and it would have asked more of the one person running it.

Permissions borrowed from Amazon and Google

#Method
#Access Control
#Testing

A permission model that is almost right is wrong, so this one is borrowed from the giants. Action grammar from Amazon, resource hierarchy from Google,...

Jesse James Richard

|

Feb 5, 2026
Read previous

Hiring an early engineer, or building something like this

Remote, Pacific time, full-time or contract. Get in touch.

Contact Jesse
Home
About
Contact
Sitemap
Privacy Policy
Terms of Service
Cookie Policy