all posts

The best Astro hosting platforms in 2026

Ajay Kumar··8 min read

Astro is unusual among frameworks in that the same repo can produce three genuinely different artifacts. A pure static site is a folder of HTML. A server-rendered site is a Node process. A hybrid site is both, with some routes prerendered and some rendered per request. Your hosting decision is downstream of that choice, and most of the confusion in this space comes from people comparing platforms before deciding which artifact they're shipping.

I'm Ajay, I build PandaStack — one of the options here. Below: how the output modes differ, what each one needs from a host, and which platforms suit which.

The three output modes, and what each one needs

Static

The default. `astro build` writes HTML, CSS, and JS to `dist/` and that's the whole deployable. Any static host serves it, a CDN caches it globally for free, and there is no server to keep alive, patch, or pay for. If your content changes at build time rather than per-request, stop here — this is the fastest and cheapest thing Astro can be, and reaching for SSR when you didn't need it is the most common self-inflicted wound in the ecosystem.

Server (SSR)

Set `output: 'server'` and add an adapter, and `astro build` produces a server entrypoint instead. The adapter you pick is a hosting commitment: the Node adapter gives you a plain Node server that runs anywhere, while the platform-specific adapters target one vendor's function runtime. Choose the Node adapter if you want to keep your options open. Choose a platform adapter if you're confident about where you're staying and want the integration.

Hybrid

Most real sites end up here: a marketing site and docs that are prerendered, plus a handful of routes — search, a dashboard, a form handler — rendered on demand. You still need a server, so you host it like the SSR case; the prerendered routes just make it cheaper to run and much easier to cache.

If you are on the Node adapter, use standalone mode unless you have a specific reason not to. It produces a server you can start with `node ./dist/server/entry.mjs`, which is exactly what a generic host expects. Middleware mode expects you to bring your own Express wrapper — fine if you already have one, an unnecessary step if you don't.

The platforms

Static hosts: Cloudflare Pages, Netlify, GitHub Pages

For a static Astro build these are excellent and mostly interchangeable at small scale. GitHub Pages is free and fine for docs and personal sites, with no server-side anything. Cloudflare Pages and Netlify add build pipelines, preview deployments, redirect rules, and a functions layer you can grow into when one route eventually needs to be dynamic. Pick on which dashboard you'd rather live in; the delivered site is the same HTML.

Vercel and Netlify, with their adapters

The smoothest SSR path if you're happy with the vendor. The adapter maps Astro's on-demand routes onto the platform's function runtime, and everything — image optimisation, preview URLs, edge middleware — is wired up for you. The cost is portability: moving later means swapping the adapter and re-testing every dynamic route, because you've been running on a function runtime with its own duration limits and its own idea of what a request is.

Anywhere that runs Node: Render, Railway, Fly, Cloud Run

With the Node adapter, an SSR Astro site is just a Node server, which means every general-purpose host works. This is the boring, durable choice: no adapter lock-in, no function-runtime limits, and your slow routes can take as long as they take. You're responsible for a bit more — the start command, the port binding, a health check — but it's five minutes of setup, not an architecture.

PandaStack (mine)

Astro is detected from the repo, built, and run inside its own Firecracker microVM. Static builds are served straight from the build output with no VM kept running; SSR builds run the Node server as a normal long-lived process. Because it's a VM rather than a function runtime, the Node adapter works unmodified and there is no per-request duration ceiling. The idle behaviour is the specific thing: an SSR site nobody is visiting sleeps and wakes on the next request, so a low-traffic hybrid site doesn't pay for a server that sat there all month.

# Astro is auto-detected from package.json — no framework flag needed.
# For SSR, install the Node adapter first so the build emits a server:
#   npx astro add node

pandastack app create \
  --name marketing-site \
  --git-url https://github.com/acme/site \
  --git-branch main \
  --start-command "node ./dist/server/entry.mjs" \
  --port 4321

When not to use it: a purely static site with global traffic belongs on a CDN-first host, full stop. There is no version of running a VM that beats an edge cache for serving unchanging HTML.

Four things that break Astro deploys

  1. Adapter missing or mismatched. `output: 'server'` without an adapter fails the build with a clear message; the harder version is an adapter for a platform you no longer deploy to, quietly producing an artifact your host can't start.
  2. Port and host binding. Astro's Node server reads `PORT` and `HOST`. Bind to 0.0.0.0, not localhost — a server listening only on the loopback interface is invisible to every health check and proxy, and this is the single most common 'it started but returns nothing' cause.
  3. Env vars at build time vs runtime. Anything referenced through `import.meta.env` with a `PUBLIC_` prefix is inlined into the client bundle during the build. It must exist when the build runs, and changing it later requires a rebuild, not a restart.
  4. Content collections and remote data at build time. If your build fetches from an API, that API must be reachable from the build environment and fast enough not to blow the build timeout. A CMS that's slow from your host but fast from your laptop is a real and annoying failure mode.

Short version

Static-only: Cloudflare Pages or Netlify, and don't overthink it. SSR where you're committed to a vendor: that vendor's adapter, which is genuinely the nicest experience. SSR where you want to stay portable: the Node adapter on any host that runs a Node process — Render, Railway, Fly, Cloud Run, or a microVM platform like PandaStack. Decide the output mode first; the hosting question mostly answers itself afterwards.

Frequently asked questions

Should I use Astro's static or server output mode?

Static unless a specific route genuinely needs per-request rendering. Static output is a folder of HTML that any CDN serves for close to nothing, with no server to run, secure, or pay for, and it is the mode Astro is best at. Move to server or hybrid output when you have real per-request needs — authenticated pages, search over live data, form handling, content that changes between builds — and even then prefer hybrid, so the pages that can be prerendered still are. The common mistake is switching the whole site to server output because one route needed it, which turns a free static site into a server you now operate.

Which Astro adapter should I use if I might change hosts later?

The Node adapter, in standalone mode. It emits a plain Node HTTP server that starts with a single command and runs unmodified on any platform that can run Node — a PaaS, a container host, a VM, or a microVM. Platform-specific adapters give you a nicer integration with one vendor's function runtime and image pipeline, but they bind your build output to that vendor's execution model, so switching means changing the adapter and retesting every dynamic route against different timeout and streaming behaviour. If you already know where you are staying, the platform adapter is the better experience; if you are not sure, take the portable one.

Why does my Astro SSR site build but return nothing when deployed?

In most cases the server is listening on the wrong interface or the wrong port. Astro's Node adapter reads the `HOST` and `PORT` environment variables; if `HOST` defaults to localhost, the process is reachable only from inside the machine, so the platform's proxy and health check both see nothing and the deploy either fails its check or serves an error page. Set `HOST` to 0.0.0.0 and honour the `PORT` the platform assigns rather than hardcoding one. The second most common cause is a start command pointing at the wrong entry file — check the actual path your build produced under `dist/`, since it varies with adapter and config.

Can I host an Astro site without a Dockerfile?

Yes. A static Astro build is just files, so any static host takes it with no container involved. An SSR build with the Node adapter is a standard Node application, and most modern platforms detect that from `package.json`, install, build, and start it without you writing anything. A Dockerfile is worth writing only if you need a system dependency the platform's build image doesn't provide — a specific image-processing library, a headless browser, a font package — or if you need the exact same artifact to run in several unrelated environments.

Is Astro SSR cheaper on serverless or on a long-running server?

It depends entirely on traffic shape, and the honest answer is to price your own. Serverless bills per invocation, so a site with bursty, low-average traffic often costs almost nothing and scales without you thinking about it. A long-running server bills for time, so it wins once traffic is steady enough that you would have been paying for a continuous stream of invocations anyway, and it removes the duration limits and cold-start behaviour that serverless imposes. A third option splits the difference: a long-running process on a platform that sleeps it while idle, so you get an unconstrained server during traffic and near-zero cost without it.

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.