Skip to main content

Railway Shipped a Free CDN, but Your Egress Bill Didn't Get the Memo

8 min readDora NodaDora Noda
Share
On this page

Some telecom engineer in Tokyo should not have to wait for your JavaScript bundle to travel from us-west. That sentence is nearly a direct quote from Railway's own changelog — and it announces the opposite of what the rumor mill told you. Railway never killed its CDN. In March 2026 it finally shipped one: a free, one-click, Fastly-powered edge cache, after years of telling users to bring their own Cloudflare.

So why do asset-heavy apps on Railway still get egress bills that sting? Because the new CDN is opt-in and off by default, HTML is always treated as dynamic, and every byte the edge does not serve still leaves your origin at $0.05 per GB. The meter did not go away. It got a bypass lane — and most traffic never uses it.

This post runs the actual numbers: what a typical 500 GB-a-month asset workload costs on Railway at realistic edge-hit ratios, where the breakeven against flat Hetzner bandwidth sits, and the sensitivity case (server-rendered HTML) where the CDN barely helps at all.

The correction first: Railway added a CDN, it did not remove one

The timeline matters, because the wrong version of it is load-bearing for a lot of cost takes. In January 2025, Railway's own support answer to "do you plan to add a CDN?" was no — use Railway plus Cloudflare caching. Then on March 27, 2026, changelog #0283 shipped a built-in CDN: Fastly under the hood, 100-plus points of presence on six continents, enabled with one click per service, at no additional cost. A July 2026 changelog entry extended the same controls to the CLI via railway cdn. The docs describe it as a live, maintained surface today.

There is no May 2026 removal. Anyone budgeting around a disappearance is budgeting around an event that never happened — and that misdiagnosis hides the real mechanism, which is less dramatic but more expensive: the CDN exists, is free, and still leaves most origin egress fully metered. That is the thing worth pricing.

What the free CDN actually covers (and the four ways bytes escape it)

Railway's CDN documentation reads like a well-designed cache with deliberately narrow defaults. The rules that determine whether a request costs you egress:

  • Off by default, enabled per service. Nothing is cached until someone flips the toggle on that service. Every deployment that nobody configured is a deployment serving 100 percent of bytes from origin.
  • HTML is always dynamic. Server-rendered pages are fetched from origin every time, by design, so they stay fresh. A Next.js or SSR-heavy app gets edge caching for its bundles and images — and full origin egress for every page view.
  • Static assets get a 2-hour default TTL when the origin sends no cache headers. Images, fonts, JS, CSS, audio, and video are cached automatically once the toggle is on; Cache-Control headers are respected when present.
  • Personalized responses bypass the cache. Set-Cookie, Cache-Control: private or no-store, Vary: Cookie, and any Authorization header send the request straight to origin. Sensible — and it means authenticated apps, the kind with the most traffic, cache the least.

Only a cache HIT avoids origin egress. A MISS still fetches from your service (and bills), first-fill repeats per point of presence, and DYNAMIC responses bill every single time.

There is a fifth, human reason bytes escape: teams leave the toggle off deliberately. Three days after the CDN launched, a misconfigured deploy accidentally enabled edge caching for domains that had it disabled, potentially serving authenticated content to the wrong users before a full revert and global purge. The blast radius was small and the postmortem was prompt — but the lesson stuck. If your app serves anything personalized, "leave the CDN off" is the conservative default, and the conservative default bills at $0.05 per GB.

The uncomfortable part is how few teams know their own hit ratio. Railway's docs suggest requesting an asset twice and watching for the x-cache: HIT header — a fine smoke test, but a spot check is not instrumentation. The number that matters is the share of origin egress your dashboard attributes to MISS and DYNAMIC over a full week, across all POPs, after a deploy has churned every cached object at once. Until you measure that, any assumption above 80 percent is optimism, and optimism at $0.05 per GB compounds monthly.

The worked number: 500 GB of assets, three hit ratios, one flat box

Take a typical mid-traffic app serving 500 GB a month of static assets — bundles, images, fonts, video thumbnails. Railway meters origin egress at $0.05 per GB. A Hetzner CX22 cloud box (2 vCPU, 4 GB RAM, 40 GB disk) costs about €3.79 a month before VAT — roughly $4.10 — with 20 TB of included traffic, so the marginal cost of these 500 GB is zero.

Edge-hit ratioOrigin GB billed on RailwayRailway egress billHetzner CX22 bandwidth bill
0% (CDN off — the default)500$25.00$0 marginal ($4.10 flat box)
70% (mediocre caching)150$7.50$0 marginal ($4.10 flat box)
90% (excellent caching)50$2.50$0 marginal ($4.10 flat box)

Two things pop out. First, at the default — CDN never enabled — the asset workload alone costs six times the entire Hetzner box. Second, the breakeven is unforgiving: Railway's egress bill drops below the CX22's ~$4.10 flat price only once origin-served bytes fall under about 82 GB a month, which at 500 GB of total traffic demands an edge-hit ratio above 83 percent. Excellent caching wins the month. Anything merely good still loses to flat.

And that is the friendly case, where every byte is cacheable. Now the sensitivity case the title promised: a server-rendered app doing 300 GB a month of HTML page views plus 200 GB of static assets cached at a respectable 85 percent. The HTML is always dynamic — zero percent cacheable by platform rule, not by misconfiguration. Origin egress is 300 GB plus 30 GB of static misses: 330 GB at $0.05, or $16.50 for the month, against the same $4.10 flat box. The CDN performed exactly as designed and the bill still came in at 4x. When someone tells you edge caching solved their PaaS bandwidth problem, ask what fraction of their traffic was HTML.

Why opt-in is the whole story

A free CDN that is off by default is a cost feature most tenants never collect. The failure mode is not dramatic — no removal, no price hike, no incident. It is a toggle nobody flipped, a Set-Cookie header nobody noticed, an SSR framework emitting pages the edge is contractually forbidden to cache. Each one quietly converts would-be HITs into billed origin bytes, and the invoice never explains which rule fired. Railway's own docs tell you to request an asset twice and watch for x-cache: HIT — good advice that almost nobody automates, so drift goes unmeasured for months.

This is the general pattern worth naming: pay-as-you-go platforms keep finding polite ways to meter what used to feel bundled. Fly.io added volume-snapshot and inter-region networking meters in early 2026; Vercel raised bandwidth overage 33 percent. Railway's version is subtler — the CDN genuinely saves money, but only for the traffic profile it was designed around, and everything outside that profile bills at the same per-GB rate as before. The meter did not move. The bypass lane just made the meter feel optional.

The self-hosted side, stated honestly

Flat bandwidth is not a free lunch; it is a different invoice. The Hetzner CX22's 20 TB included traffic absorbs the entire 500 GB workload without blinking, and a dedicated AX41-class box (around €39 a month, unlimited traffic on a gigabit port) absorbs a hundred times that. But no Hetzner box ships with 100 Fastly POPs. Self-hosting the bytes means operating your own edge: cache headers you actually set, a CDN you actually configure — usually Cloudflare in front, which is exactly the setup Railway recommended before it built its own. You trade a per-GB meter for operational surface: TLS, cache purge discipline, and the same authenticated-content caution the March 30 incident demonstrated, except now you own both sides of it.

The honest decision rule: if your traffic is cacheable, high-hit-ratio, and you will actually maintain the toggle, headers, and purge discipline, metered egress with a good edge can beat flat hardware — the 90-percent row of the table is real. If your traffic is SSR-heavy, authenticated, multi-POP-thin (first-fill everywhere, hits nowhere), or maintained by a team that will never flip the toggle, the flat box wins by 4 to 6x and the only question is who operates the edge. Count your HTML before you count your savings.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with flat bandwidth instead of a per-GB meter. 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