all posts

The best Railway alternatives in 2026

Ajay Kumar··8 min read

Railway's pitch is that you shouldn't think about infrastructure, and for a while you don't. The two things that eventually send people looking are the bill behaving in ways they didn't predict, and hitting a ceiling on what a shared-kernel container will let them do.

Both are real. They point at different places. I build PandaStack, which is an answer to the second one and not especially to the first — I'll be specific about that.

Reason one: usage-based billing surprises

Usage-based pricing is genuinely better for intermittent workloads and genuinely worse for a service that runs hot. The surprise usually isn't the model — it's discovering which resource is being consumed.

  • A memory leak bills as memory, continuously, until someone notices. On a fixed-price instance the same leak causes a restart and a monitoring alert. On usage-based pricing it causes an invoice.
  • A busy background worker with a tight polling loop costs CPU around the clock even though it does almost nothing.
  • Egress from an unoptimised asset or an aggressive crawler is real traffic that never touches your application logic.
  • Databases idle at a cost. Several small ones idle at several small costs.

If your bill is surprising, itemise it before you migrate. Frequently the fix is one polling interval, one asset behind a CDN, or one leak — and the platform was never the problem. If the model itself is wrong for you because your services run hot around the clock, a fixed-price container platform (Render, Koyeb, DigitalOcean App Platform, Northflank) is more predictable and you should move for that reason and say so plainly.

Set a spend alert on day one on any usage-based platform, and set it at a number that would annoy you rather than one that would ruin you. The failure mode of usage billing isn't the average month, it's the month where something loops.

Reason two: hitting the container ceiling

Containers share the host kernel. That's fine for the overwhelming majority of apps and a hard stop for a specific set of them: anything wanting nested containers or Docker-in-Docker, kernel modules, a particular kernel version, device access, or a security answer stronger than 'namespaces and seccomp' when a reviewer asks what separates tenants.

This is my category. MicroVM platforms — Fly Machines, PandaStack — give each workload a virtual machine with its own kernel. The practical reason it matters in 2026 is that a lot of products now execute code they didn't write: agent backends running generated Python, CI runners executing pull-request code, data platforms running customer transforms. On a substrate where a machine restores from a snapshot in roughly 179ms at p50, one microVM per job stops being an architectural project.

If you're hosting a CRUD app and a database, none of this applies to you and a container platform is the better answer.

Reason three, less discussed: you outgrew the abstraction

Railway is deliberately opinionated. As a system grows, teams start wanting things the abstraction doesn't surface: fine-grained network policy between services, custom health-check semantics, control over rollout strategy, per-service resource guarantees, or an infrastructure-as-code representation of the whole environment.

At that point the honest options are a more configurable PaaS (Northflank and Koyeb sit further along that axis) or managed Kubernetes with a deploy layer on top. The second is the right answer only if you'd justify a platform team anyway. It is a genuinely bad answer for three engineers who want to ship features, and the Kubernetes migration that stalls halfway is one of the most expensive mistakes in this whole category.

Diagnose before you shortlist

Container platforms are more alike than their landing pages suggest. Moving between them costs real engineering time and lands you somewhere structurally similar, with a different dashboard and a fresh set of small annoyances you have not met yet. That is worth doing when you can name the problem in one sentence, and worth avoiding when you cannot.

So write the sentence down. 'Our staging environment costs money to sit idle' points at consolidation or scale-to-zero, not at a new vendor. 'We cannot run Docker inside our build step' points specifically at microVMs. 'The bill doubled last month and nobody knows why' points at instrumentation before anything else. Each of those has a cheapest correct answer, and only one of the three is a migration.

The shortlist

  • Render — fixed-price instances, predictable, closest like-for-like. Move here if usage billing is the problem and your services run hot.
  • Fly.io — per-machine pricing, real scale-to-zero, machines are closer to VMs than containers. Good middle ground.
  • Koyeb / Northflank / DigitalOcean App Platform — more configuration surface, still a PaaS.
  • PandaStack (mine) — microVM isolation with PaaS-shaped deploys; right when you run untrusted code or need kernel capabilities, not when you want a cheaper container.
  • Managed Kubernetes with a deploy layer — maximum control, becomes a job. Only if you'd staff it anyway.
  • Staying, with the expensive thing fixed — the answer nobody sells you, and often correct.
# Container-PaaS apps are portable: the deploy is three declarations
pandastack apps create --name worker \
  --git-url https://github.com/acme/worker \
  --start-cmd 'node dist/worker.js'

# The parts that need real attention when you move:
#  - internal service-to-service URLs (they change)
#  - the health check path
#  - where migrations run relative to traffic

The short version

Bill too high and services run hot: fixed-price instances. Bill too high and you don't know why: itemise first, because it's usually a leak, a poll loop, or egress. Blocked by the container boundary: microVMs. Outgrown the abstraction: a more configurable PaaS, and only reach for Kubernetes if you'd staff a platform team regardless.

Frequently asked questions

Why is my Railway bill higher than expected?

Usage-based billing charges for what your services consume, so the answer is nearly always a specific resource rather than the platform's rates. The four usual culprits: a memory leak, which on a fixed-price instance would cause a restart and an alert but here just accrues; a background worker polling on a tight interval, burning CPU around the clock to do almost nothing; egress from unoptimised assets or crawler traffic that never reaches your application code; and several small databases each idling at a small cost. Itemise the bill by service and resource before migrating — the fix is often one polling interval or one asset behind a CDN.

Is Render or Railway cheaper?

Neither, in general — it depends on duty cycle. Railway's usage-based model wins for intermittent and spiky workloads, side projects, and anything that idles most of the week. Render's closer-to-fixed pricing wins when a service runs near capacity around the clock, because usage billing on a hot service is just a variable version of a fixed cost with less predictability. Model both against a real week of your own traffic, including the database and egress, rather than comparing the headline numbers. If predictability itself has value to you — because finance dislikes variance — that is a legitimate reason to prefer fixed pricing even at a slightly higher average.

When do containers stop being enough?

When you need something from the kernel rather than from the process. The concrete triggers are nested containers or Docker-in-Docker, loading kernel modules, requiring a specific kernel version, device access, and — increasingly the common one — needing to answer a security review about what separates tenants when your product runs code you did not write. Containers share the host kernel, so namespaces and seccomp are the strongest answer available, and for an agent backend running generated code or a CI runner executing pull-request code, that answer is often judged insufficient. A microVM gives each workload its own kernel, which is a different and much easier conversation.

Should I move from a PaaS to Kubernetes?

Only if you would justify a platform team regardless of this decision. Kubernetes gives maximum control and no vendor lock-in, and it costs an ongoing share of engineering attention that a small team cannot spare — the ingress controller, the certificate manager, the upgrade cadence, and the CI plumbing all become yours permanently. The migration that stalls at eighty percent, with half the services on the new cluster and nobody willing to own the rest, is one of the most expensive outcomes in this category. If you want more configuration than an opinionated PaaS offers, a more configurable PaaS is usually the better next step.

How portable is an app between PaaS platforms?

Very, in terms of code — most container-PaaS apps move with no source changes, since the platform only needs an install command, a build command, and a start command. What actually takes the time is everything around the app: internal service-to-service URLs, which are platform-specific and will all change; the health check path and its semantics; where database migrations run relative to traffic shifting; cron definitions; and the full list of environment variables including the ones nobody documented. Inventory those first and the migration is a day. Skip that step and it becomes a week of small outages.

Keep reading

Run code in a microVM in one API call.

49ms p50 cold start. Fork, snapshot, and scale to zero.

Start free
Written by Ajay Kumar, Founder, PandaStack.