Skip to main content

Railway's May 2026 GCP Blackout: What an 8-Hour Outage Reveals About a Control Plane That Never Actually Left Google Cloud

11 min readDora NodaDora Noda
Share
On this page

The servers were fine. The routes were gone. On May 19, 2026, workloads running on Railway's own bare-metal hardware — machines Google had no access to and no power over — went unreachable for hours, returning 404s while their processes kept running. The outage wasn't caused by failed hardware, bad deploys, or a misconfigured firewall. It was caused by a single automated action, on a single cloud account, against a control plane that the "we run our own hardware" story had quietly left behind on Google Cloud.

That is the sentence this whole post exists to unpack: your blast radius is your control plane, not your compute. Railway had spent the prior year migrating workloads onto Railway Metal, its own hardware in its own sites. But the network control-plane API that told edge proxies where those workloads lived still ran on GCP. When Google suspended the account, the compute survived and the reachability didn't — and reachability is the only part your customers ever see.

Eight hours, layer by layer: what actually happened

At 22:10 UTC on May 19, Railway's monitoring detected API health-check failures and paged the on-calls. A minute later the dashboard was returning 503s — "no healthy upstream," "unconditional drop overload" — and users couldn't log in. By 22:19 the team had the root cause: Google Cloud had placed Railway's production account into suspended status. A P0 ticket went in at 22:22, the GCP account manager was engaged directly, and at 22:29 — just ten minutes after identification — account access was restored.

Here is the part that should rewire how you think about cloud-account risk: restoring the account did not restore the services. Every compute instance stayed stopped. Every persistent disk stayed inaccessible. Networking stayed down. Each layer had to be recovered separately, and the timeline shows how long that takes when the failure is account-shaped rather than machine-shaped:

Time (UTC)Event
May 19, 22:10Monitoring detects API failures, pages on-calls
May 19, 22:19Root cause identified: GCP production account suspended
May 19, 22:29Account access restored — but instances stopped, disks inaccessible
May 19, 22:35Cached network routes begin expiring; Metal and AWS workloads return 404s
May 19, 23:54All persistent disks restored to ready state; network still down
May 20, 01:30Compute recovering; edge traffic served again
May 20, 01:57Orchestration and builds restored; deploys paused to drain backlog safely
May 20, 02:47GitHub starts rate-limiting Railway's OAuth and webhook calls
May 20, 04:00API, dashboard, and OAuth confirmed operational
May 20, 06:14Incident moved to monitoring (~8 hours after onset)

Total platform-wide impact ran roughly 22:20 UTC to 06:14 UTC — about eight hours across a platform reportedly powering around 10 million hosted services. Founder Jake Cooper's public reaction captured the disbelief: he was, in his words, gobsmacked that a provider could shut down with no notice an account spending $2 million a month with tens of millions in lifetime spend. Google, for its part, described the suspension as enforcement against flagged activity, with prior violation notices on record but no notice before this particular action. The automated suspension reportedly swept up many accounts at once, which is exactly why there was no per-customer outreach: nobody at Google made a decision about Railway specifically. A classifier did.

The cascade: how a GCP suspension reached servers Google never hosted

This is the mechanism worth studying, because it generalizes far beyond one vendor. Railway's edge proxies don't inherently know where workloads live. They maintain a cache of routing tables populated from the network control-plane API — which was hosted on Google Cloud. The moment of suspension, that cache was the only thing standing between "GCP workloads down" and "everything down."

It held for about fifteen minutes. At 22:35 UTC the cached routes began expiring, and the edge could no longer resolve routes to active instances. Workloads on Railway Metal and AWS burst capacity — still running, still healthy — started returning 404s. At peak impact, every Railway workload in every region was unreachable, including on infrastructure Google had never touched.

Railway's own postmortem is admirably blunt about the architecture. The network is a mesh ring with high-availability fiber interconnects between Metal, GCP, and AWS. The mesh itself kept operating for roughly an hour. But workload discoverability was tied to the control-plane API running on GCP machines, so when the route cache expired, the mesh couldn't repopulate its routing tables. A ring with one brain is not a mesh; it's a hub-and-spoke network with extra steps.

Then came the second-order cascades that always follow a control-plane outage and never appear in anyone's migration spreadsheet. With caches cleared across the board, the burst of retried requests got Railway's GitHub OAuth and webhook integrations rate-limited, blocking logins and builds during recovery. Deploys had to be deliberately paused and then drained gradually to avoid overwhelming the build systems with the queued backlog. Even Terms-of-Service acceptance records were reset, so users had to re-accept on their next dashboard visit. None of these were the outage. All of them were the outage, as experienced by customers.

Why own hardware wasn't enough

The uncomfortable part for the "just run your own hardware" crowd is that Railway had already done that part. The company has run its own hosts since 2024, scaled the practice through 2025, completed the GCP-to-Metal migration in June 2025, and by the time of the incident operated hardware across 8 sites in 4 locations. Egress got cheaper, the free plan came back, the economics of owning machines worked exactly as advertised.

But two things eroded the independence story. First, demand growth in early 2026 pushed Railway to burst back onto AWS and GCP for compute capacity — the honest, normal thing a growing platform does, and also the thing that quietly re-entangles you with the vendor you declared independence from. Second, and far more consequentially, the migration moved workload compute while the control plane stayed put: the dashboard, the API, parts of the network infrastructure, the databases, and above all the network control-plane API feeding the edge proxies.

This is the pattern to internalize. Compute migrations are visible, measurable, and satisfying — you can point at a dashboard showing what percentage of workloads run on your own iron.

Control-plane dependencies are invisible until they're load-bearing. Nobody celebrates "we moved 40% of route discoverability off GCP" because route discoverability isn't a workload you can watch migrate. It sits in the architecture diagram as one small box with arrows going everywhere, and those arrows are the actual blast radius.

Railway is not an outlier here. The same year gave us an AWS DNS/DynamoDB disruption and an Azure Front Door misconfiguration that both traced back to a handful of control-plane primitives. Industry analysis keeps converging on the same observation: control-plane failures are increasingly at the center of cloud outages, and the fix is architectures that keep operating safely when upstream control systems degrade — site-level autonomy, local survivability during control loss, fault domains that bound the orchestration blast radius.

The own-the-control-plane audit: 7 questions for your platform (or your vendor)

Whether you self-host on bare metal or evaluate a managed PaaS, run this checklist. Each question comes straight from a link in the May 19 cascade.

1. Where does route and service discovery live? Name the system that maps "this hostname" to "that running instance," and name the machines and account it runs on. If your edge, ingress, or proxy layer populates its tables from a control-plane API on a vendor you could lose, you have Railway's exact dependency. The fix is discoverability that survives the loss of any one site or account — not just redundant links between sites that all phone home to the same brain.

2. Where is database quorum? Railway's databases spanned multiple availability zones, which protects against losing machines — not against losing the account that owns all the zones. Ask which failure unit your quorum actually survives: dead hosts, dead zones, or a dead vendor relationship. Railway's stated fix is extending high-availability database shards across AWS and Metal so quorum survives any single cloud disappearing instantly.

3. How long does your cache outlive your control plane? Railway's route cache bought about fifteen minutes; full edge recovery took over three hours. Compute the ratio for your own stack: cache TTL on routing, DNS, auth tokens, and feature flags versus worst-case control-plane recovery time. If the cache expires first, the cache is not a resilience strategy — it's a countdown.

4. Is the cloud account itself a single point of failure? Account suspension, quota automation gone wrong, billing disputes, compliance holds — these are account-shaped failures, and they ignore every availability zone you paid for. Railway had already been burned by GCP automation once before, when quotas were lowered automatically in 2023. Ask what happens to each layer — compute, disks, networking, identity — if the account, not a machine, is what disappears. Then verify the recovery path, because as May 19 showed, "access restored" and "services restored" can be hours apart.

5. Can deploys and builds drain safely after recovery? The outage doesn't end when traffic flows again; it ends when the queued backlog of builds, deploys, and webhook deliveries drains without thundering-herding your own systems. Railway had to pause deploys deliberately and resume gradually. If your recovery runbook ends at "traffic restored," it's missing the second half.

6. Which third-party integrations cascade? GitHub rate limits turned a GCP incident into a login-and-builds incident. Map every external API on your control-plane hot path — OAuth providers, git webhooks, container registries, DNS, status and secret stores — and ask what each one does under a 10x retry burst with cold caches. Your incident's blast radius includes every vendor your recovery procedure calls.

7. Can you demonstrate control-plane loss without customer impact? This is the only question that validates the other six. Railway notes its control plane had been tested against machine and component loss in staging and live traffic — but the tested failure was losing pieces, not losing the whole GCP-hosted brain at once. Game-day the account-shaped failure: revoke the vendor, kill the site hosting the control plane, expire every cache simultaneously. If that exercise is too scary to run, you've found your real architecture.

What Railway is changing — and what self-hosters should steal

Railway took full ownership — "we ultimately own this one" — and committed to three structural fixes: removing the discoverability dependency to make the mesh a true mesh, extending database shards across AWS and Metal for vendor-independent quorum, and taking Google Cloud services off the data plane's hot path entirely, keeping them only for secondary and failover roles. Summer 2026 became a "reliability foundation" quarter, with second-generation Metal hardware and four new datacenter sites on the roadmap.

If you self-host, don't read this as someone else's problem. A Cluster-API-managed fleet on owned machines has the same audit to pass with different nouns: etcd quorum placement, API-server reachability from every node, the CNI and DNS your pods need to find each other, the container registry your kubelets pull from, the single Hetzner or cloud account that could theoretically suspend the project owning your control-plane VMs.

Owning the machines is necessary. It was never sufficient. The May 19 outage is what "necessary but not sufficient" looks like at 22:35 UTC, when the caches expire and the 404s start.

So the next time a migration plan shows you a compute dashboard trending beautifully toward zero vendor workloads, ask to see the other dashboard — the one showing where the control plane lives. If nobody has drawn it, that's your answer. And that's the audit worth running this week, before a classifier somewhere runs it for you.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with the control plane living on your infrastructure instead of someone else's account. Star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex