all posts

The 8 Best Platform.sh Alternatives in 2026

Ajay Kumar··8 min read

The exit conversation usually starts with an invoice. Eleven long-lived preview environments, each carrying a running app and a full copy of production data, and nobody deletes them because recreating one means understanding the YAML — and the people who understand the YAML are busy. I'm Ajay, I build PandaStack, one of the eight below, so I have described what each option is optimised for rather than scoring them. Pricing moves on all of these; verify current rates yourself.

What Platform.sh actually does, described fairly

Platform.sh — and Upsun, the newer product from the same company — is built on one idea: your topology is a file in your repo. An app config declares the runtime and its version, the build and deploy hooks, the start command, the writable mounts and the relationships to services. A services file declares the backing services — PostgreSQL, MySQL, Redis, Elasticsearch — each pinned to a version and disk size.

Two consequences follow, and they are why people liked it. The runtime filesystem is read-only apart from declared mounts, so a deploy is genuinely immutable. And a git branch becomes an environment: creating one gives you a child with the parent's services provisioned and its data cloned in. A pull request environment with real data, no seed script. Name that workflow precisely, because most alternatives below lack it.

Why teams leave

Three things, roughly in this order. Cost, as environment count grows, because a cloned environment is a real one with real disk. The learning curve of a config model that is precise, unforgiving, and which most of your team will never learn. And wanting a less opinionated runtime — something needed to write outside the mounts or run a second process beside the web server. Those complaints are the price of the guarantees.

The config file, and the version with no config file

Here is a small, realistic app config. Notice how much of it restates things already true elsewhere in the repo.

# .platform.app.yaml
name: app
type: "nodejs:22"

dependencies:
  nodejs:
    pnpm: "9"

relationships:
  database: "db:postgresql"

mounts:
  "/.next/cache":
    source: local
    source_path: next-cache
  "/uploads":
    source: local
    source_path: uploads

hooks:
  build: |
    pnpm install --frozen-lockfile
    pnpm run build

web:
  commands:
    start: "pnpm run start --port=$PORT"
  locations:
    "/":
      passthru: true

crons:
  nightly:
    spec: "0 3 * * *"
    commands:
      start: "pnpm run jobs:nightly"

# .platform/services.yaml
db:
  type: postgresql:16
  disk: 2048

The nodejs:22 restates your .nvmrc, the pnpm pin restates your packageManager field, the build hook restates your build script. The mounts exist because the filesystem is read-only — a platform property, not something your app asked for. A version pinned twice drifts: .nvmrc says 22.14, the config says 22, and one day that matters.

The inference-first version is the absence of a file. You connect the repo, we detect the framework — Next, Vite, CRA, webpack, static, Node, Python, Go, plus Railpack for the long tail — and read runtime versions from the files that already pin them.

# .nvmrc
22.14.0

# .tool-versions  -- read by mise; the file asdf users already have
nodejs 22.14.0
python 3.12.7

# That is the whole configuration. Detection fills in the rest:
#   install:  pnpm install --frozen-lockfile   (the lockfile picks the manager)
#   build:    pnpm run build
#   start:    pnpm run start                   (binds $PORT)
#
# Overrides live in app settings when detection guesses wrong, and the
# filesystem is writable, so /uploads and .next/cache need no declaration.

$ pandastack apps deploy my-app
  detected framework: next
  mise install       node 22.14.0  (cached)
  build              42s
  health check       :3000 ok
  flip live          blue -> green

That is a trade, not a free win. Inference is convenient until it guesses wrong on an unusual repo, and a declared topology is auditable in a way detection is not.

The eight alternatives

1. Render

The closest spiritual successor for teams who liked declaring a topology but wanted it lighter. A render.yaml blueprint covers services, databases and environment groups, with managed Postgres and Redis, workers, cron jobs and pull-request previews. Pick it if you can seed preview databases yourself.

2. Railway

The opposite philosophy: a canvas of services you wire together, with a large template catalogue covering Postgres, Redis, MySQL and ClickHouse. Environments are first-class, including ephemeral ones. The service graph is the source of truth instead of a file, which some find freeing and others find hard to review.

3. Fly.io

For teams whose real requirement is geography. Fly runs apps as Firecracker microVMs across many regions, with Postgres options, volumes and machine-level control including scale-to-zero through its Machines API. It sits closer to infrastructure than to a PaaS, so pick it when multi-region latency is a product requirement.

4. Northflank

The most direct match on breadth: apps, jobs, managed Postgres, MySQL, Redis and MongoDB, build pipelines, preview environments, and a bring-your-own-cloud mode that runs inside your own AWS, GCP or Azure account — which matters if data residency is part of why you are leaving. It is Kubernetes underneath and does not fully hide that.

5. Heroku

Still the right answer more often than the internet suggests. Buildpacks, an add-on marketplace covering essentially everything in your services file, Review Apps per pull request, and Postgres forks and followers, which get closer to cloning the parent than most of this list. Check pricing against your environment count first.

6. Koyeb

Lighter and serverless-flavoured: deploy from git or a container image, with global edge routing, autoscaling including scale-to-zero on eligible plans, and managed Postgres. Good for a handful of bursty HTTP services with no config vocabulary to learn; a poor fit if you leaned on several declared services and stateful workers.

7. Self-managed: Kubernetes, Dokku or Coolify

Really two things. Dokku and Coolify are single-host, git-push PaaS layers on your own VPS, running your app and a Postgres container for the price of the box; Coolify adds a UI and per-branch previews. Kubernetes with Argo CD is the enterprise version, declarative if you build the cloning workflow yourself. Pick this when a platform engineer costs less than the markup.

8. PandaStack

Ours, so the limits first. There is no declared-services catalogue: no managed MySQL, Redis or Elasticsearch. We run managed Postgres 16 and that is the list, so if your services file has four entries, three become processes inside your app's VM or a third-party account.

What we do have maps onto the parts people miss. Apps are git-driven deploys into a full Linux microVM with framework auto-detection, so no config file is required, and because it is a real VM the filesystem is writable, you get root, and you can run a web server and a worker together. Managed Postgres 16 does clone-to-a-new-database and point-in-time restore, the closest we come to cloning the parent: branch the app, clone the database, point the branch at the clone. Idle apps hibernate and wake in about 1.2 seconds with no per-request charge, so an unused environment costs roughly its stored disk.

Every pricing model and included-service list above changes on the vendors' schedule, not mine. Treat this as a map of the shapes and verify against current docs — especially if you are moving because of cost, since the axis that made Platform.sh expensive for you may exist under a different name elsewhere.

How to choose in ten minutes

  1. Count the non-Postgres entries in your services file. Each is a migration task or a reason to pick a platform with that managed service.
  2. Decide whether parent-data cloning is load-bearing or a habit. If engineers really debug against production-shaped data, you need database branching, not just preview apps.
  3. Multiply your long-lived environment count by what a small always-on instance costs on each candidate. If that is why you are leaving, weight scale-to-zero heavily.
  4. Check what your app writes to disk. If the read-only filesystem annoyed you, that argues for a real VM; if you relied on it, stay on an immutable-image platform.
  5. Ask who owns backups and upgrades a year from now. If nobody, delete the self-managed row before you get attached to its price.

The short version

Northflank for the same breadth under one vendor. Render if you liked declaring a topology and wanted it lighter. Heroku if Review Apps with Postgres forks cover the workflow. Railway if the YAML was the problem. Fly.io if the requirement is regions. Koyeb for bursty HTTP. Dokku, Coolify or Kubernetes if you have both the bill and the person. PandaStack for cheap environments and Postgres you can clone.

Rehearse a restore before you migrate anything. Environment cloning trains teams to assume a fresh copy of production is one command away. On most of this list it is not, and the cutover is the worst time to find out.

Frequently asked questions

What is the difference between Platform.sh and Upsun?

Upsun is the newer-generation product from the same company, sharing the core ideas — a YAML-declared topology committed to the repo, git-branch-per-environment with the parent's data cloned into children, declared managed services, and a read-only runtime filesystem with explicit mounts — with a different configuration layout and different commercial packaging. If you are shopping for alternatives because of the config model or the cost of many long-lived environments, both products sit on the same side of that comparison. Check their current documentation for which product new projects are steered toward and how migration between the two works.

Which Platform.sh alternative is closest on managed services?

Northflank and Heroku cover the widest footprint. Northflank offers managed Postgres, MySQL, Redis and MongoDB alongside apps, jobs and preview environments, plus a bring-your-own-cloud mode that runs everything inside your own AWS, GCP or Azure account. Heroku's add-on marketplace covers essentially anything you would have declared in services.yaml, and its Postgres fork and follower features get closest to the clone-the-parent workflow. Render sits in the middle with managed Postgres and Redis. Anything narrower, PandaStack included, means running some services yourself or pointing at a third party.

Can I get git-branch-per-environment with cloned data elsewhere?

Not usually as one integrated feature, which is why people miss it. Most platforms give you preview app environments from pull requests but leave the data to you, so you seed a fresh database or restore a sanitised dump. The closer approximations are Heroku Postgres forks, and platforms with database branching where you clone a database into a new one and point the branch environment at the clone. On PandaStack that is two steps: deploy the branch as an app, clone the managed Postgres with an optional point-in-time target, then set the connection string.

Do I have to rewrite my .platform.app.yaml when I migrate?

It depends on the direction. Render and Northflank want an equivalent declaration, so it becomes a translation exercise: runtime version, build command, start command, disks, services. Railway wants you to build the service graph instead. On a detection-first platform like PandaStack there is often nothing to write, because runtime versions come from .nvmrc, .python-version, .tool-versions or mise.toml and the framework and build commands are detected from the repo, with overrides when detection guesses wrong. The parts that never translate automatically are mounts and cron definitions.

Does PandaStack offer managed Redis, MySQL or Elasticsearch?

No. We run managed Postgres 16 — one dedicated Firecracker microVM per database with a durable volume, TLS, clone-to-a-new-database, point-in-time restore, failover, credential rotation and idle auto-suspend with wake-on-connect — and that is the entire managed data catalogue. If your services file lists Redis, MySQL or Elasticsearch, you would run them as processes inside your app's microVM, which works because you get root and a real writable filesystem, or point at a third-party managed provider. If you want those managed under one vendor, Northflank or Heroku are the more honest recommendations.

Why do preview environments cost so much on a traditional PaaS?

Because a preview environment is a real environment. Each one holds a running app instance and, if it clones the parent, a full copy of the database on real disk, and both bill whether or not anyone opens the URL. Eleven branches nobody has looked at in a month still cost like eleven deployments. The two levers are deleting environments aggressively, which teams reliably fail to do, and picking a platform where idle costs approximately nothing. Apps that hibernate and wake on the next request make the second lever the default instead of a chore.

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.