Phoenix is the flagship Elixir web framework, and Elixir runs on the BEAM — the Erlang VM built for massive concurrency, fault tolerance, and long-lived connections. That foundation means Phoenix hosting has needs most frameworks don't: WebSocket-heavy LiveView traffic, optional BEAM clustering across nodes, hot-ish deploys, and runtime configuration. Picking a host that respects the BEAM matters. Here's a fair 2026 guide.
What makes Phoenix hosting different
- Long-lived connections (LiveView/Channels): Phoenix apps hold many persistent WebSocket connections. Hosts that aggressively idle or scale-to-zero break this; you want a warm, always-on process.
- Clustering: BEAM nodes can form a cluster (via
libcluster) for distributed features like Phoenix PubSub and Presence across instances. This needs network reachability between nodes — not all platforms expose that easily. - Releases: Production Phoenix typically ships as an OTP release (via
mix release), a self-contained artifact. - Runtime config:
config/runtime.exsreads env vars (likeDATABASE_URL,SECRET_KEY_BASE,PHX_HOST) at boot. - Postgres: Ecto + Postgres is the default data layer.
A production release Dockerfile
Phoenix releases containerize cleanly with a multi-stage build:
FROM hexpm/elixir:1.17-erlang-27-debian-bookworm AS build
WORKDIR /app
RUN mix local.hex --force && mix local.rebar --force
ENV MIX_ENV=prod
COPY mix.exs mix.lock ./
RUN mix deps.get --only prod && mix deps.compile
COPY . .
RUN mix assets.deploy && mix release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y libstdc++6 openssl libncurses6 && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=build /app/_build/prod/rel/my_app ./
ENV PHX_SERVER=true
EXPOSE 4000
CMD ["bin/my_app", "start"]With config/runtime.exs reading DATABASE_URL, SECRET_KEY_BASE, and PHX_HOST from the environment, the same release runs anywhere those vars are set.
Hosting options at a glance
| Platform | Always-on (LiveView) | Clustering ease | Managed Postgres | Notes |
|---|---|---|---|---|
| Fly.io | Yes | Strong (private net) | Managed PG | Popular in Elixir community |
| PandaStack | Yes (paid tier) | Single-node simple; multi-node limited | Yes (PG) | DB auto-wired, container deploy |
| Render | Yes | Limited | Yes (PG) | Mature managed PaaS |
| Gigalixir | Yes | Built for BEAM (hot upgrades) | Managed PG | Elixir-specialized |
| Self-hosted/VM | Yes | Full control | You run it | Maximum control |
Fly.io
Fly.io has long been a favorite in the Elixir community, and for good reason: its private networking makes BEAM clustering across regions practical, it keeps Machines running for persistent connections, and it offers managed Postgres. If clustering and multi-region LiveView are central to your app, Fly is purpose-built and well-documented for Phoenix. It's the benchmark to compare others against here.
Gigalixir
Gigalixir is a platform specifically built for Elixir/Phoenix. It supports hot upgrades, clustering, remote observer access, and the BEAM-native workflows Elixir developers love. If you want a host that speaks Elixir fluently and you value BEAM-specific features like hot code upgrades, Gigalixir is a specialized, strong choice.
PandaStack
For a single-node (or horizontally replicated but stateless) Phoenix app with Postgres, PandaStack works well as a straightforward container host. Connect the Git repo, ship the OTP release via your Dockerfile, and it builds with rootless BuildKit and deploys via Helm. Attach a managed PostgreSQL and DATABASE_URL is injected, which config/runtime.exs consumes directly.
Why it can suit Phoenix:
- Managed Postgres auto-wired for Ecto, with backups.
- Container deploys from your release Dockerfile, with SSL and custom domains (set
PHX_HOSTaccordingly). - Cronjobs and edge functions alongside if needed.
- Free tier to evaluate; move to a warm paid compute tier for LiveView.
Honest caveats — and these matter for Phoenix specifically: do not run a LiveView app on the scale-to-zero free tier — idling kills persistent WebSocket connections and adds cold-starts; use an always-on paid compute tier. BEAM clustering (distributed Erlang across pods) is not a first-class, documented feature here the way it is on Fly/Gigalixir; for single-node or PubSub-via-Postgres setups that's fine, but if you need true multi-node distributed Erlang, prefer a platform built for it. PandaStack is newer with a growing ecosystem.
Render
Render hosts Phoenix releases with managed Postgres and keeps services always-on, suitable for LiveView. Clustering support is limited, so it fits single-node or stateless-replica designs. A mature, predictable option.
Self-hosted VM
A classic Phoenix deployment is an OTP release on a VM (or a small cluster) you control — maximum flexibility for clustering, hot upgrades, and tuning, at the cost of operating the box, Postgres, and TLS yourself. Right for teams that want full BEAM control and have the ops capacity.
How to choose
- Multi-region clustering + LiveView at scale → Fly.io.
- BEAM-native features (hot upgrades, observer) → Gigalixir.
- Single-node Phoenix + Postgres, simple deploys, bundled DB → PandaStack (on a warm tier).
- Mature managed PaaS, single-node → Render.
- Full control over the BEAM → self-hosted VM.
The key question is whether you need distributed Erlang clustering. If yes, lean toward Fly.io or Gigalixir. If your app is a single node (or stateless replicas with PubSub over Postgres) plus a database, a general container PaaS with a bundled DB is simpler — just keep it warm for LiveView.
References
- Phoenix deployment docs: https://hexdocs.pm/phoenix/deployment.html
- Elixir releases: https://hexdocs.pm/mix/Mix.Tasks.Release.html
- libcluster (clustering): https://github.com/bitwalker/libcluster
- Fly.io Elixir guides: https://fly.io/docs/elixir/
- Gigalixir: https://www.gigalixir.com/
---
Running a single-node Phoenix app with Postgres? PandaStack builds your OTP release, auto-wires a managed database via DATABASE_URL, and handles SSL — free to start at https://dashboard.pandastack.io. For LiveView, run it on a warm compute tier (not scale-to-zero).