- Next.js 16 Self-Hosted Alternatives: Fly.io, Cloud Run, VPS
Next.js 16 Self-Hosted Alternatives: Fly.io, Cloud Run, VPS
Practical comparison of Fly.io, Google Cloud Run, Railway, Render and bare VPS for cost, reliability, and Next.js 16…

⚡ Next.js Implementation Guides
In-depth Next.js guides covering App Router, RSC, ISR, and deployment. Get code examples, optimization checklists, and prompts to accelerate development.
Related Posts:
Next.js 16 Self-Hosted Alternatives: Railway vs Fly.io vs Cloud Run vs Bare VPS
If you're reading this, you've probably already made your peace with Vercel. You know what it does well. You also know what happens to your bill when you upgrade to Next.js 16, watch your Edge Request count double overnight, and get an email from your billing dashboard that makes you question your life choices.
This article is for the moment after that. When you've decided — or you're seriously considering — leaving Vercel behind, and you want a clear-eyed comparison of what you're actually choosing between.
I'm going to go through each realistic option, what it gives you with Next.js 16 specifically, where it breaks down, and what the cost picture looks like at real scale. No "10 Vercel alternatives" fluff. Just the tradeoffs.
Why Next.js 16 Makes This Decision More Urgent
Before getting into platforms, it's worth being specific about what changed in 16 that makes self-hosting worth reconsidering even if you were happy before.
Next.js 16 ships with more aggressive prefetching behavior by design. The official framing is that this reduces total transfer size. The practical reality for self-hosted and Vercel deployments alike is that request counts increase materially after upgrading — one production report put it at requests "effectively doubling" after moving from 15 to 16, with direct impact on server load and cloud bills. Vercel confirmed this is expected behavior when developers reported Edge Request spikes without any traffic increase.
The build output also got larger. There's a documented case of a 6,000-page static site watching its .next/server/app folder grow from 3.5 GB to 6.3 GB after upgrading, with corresponding increases in deploy times and CI costs.
Neither of these is a disqualifying bug. But they both push the cost-benefit calculation on Vercel in a direction that makes self-hosting worth looking at more seriously. If you're already at a scale where bandwidth and function invocations show up meaningfully on your bill, 16's behavior can compound that fast. One documented case study showed a Next.js app on Vercel go from the free tier to over $700 per month, with bandwidth overages alone accounting for most of it.
That's the context. Now, the platforms.
The Deployment Options That Actually Matter in 2026
The field broadly breaks into three categories:
Container PaaS — you push a Docker image or a Git repo and the platform handles the runtime. This covers Fly.io, Google Cloud Run, Railway, and Render.
Bare VPS or VM providers — you get a Linux machine and you own everything from there. Hetzner, DigitalOcean, Akamai/Linode.
VPS + Docker on your own terms — same machines, but you're running Docker with output: "standalone", a reverse proxy, and whatever shared cache you configure. This is what most serious self-hosted Next.js setups actually look like in production.
The official Next.js 16 docs are clear: both a Node.js server and a Docker container support all Next.js features. Static export is explicitly "Limited." So the question isn't about feature parity in isolation — it's about what you have to build and maintain yourself to make each deployment model production-ready.
Fly.io
Fly.io is probably the most developer-friendly entry point into container-based self-hosting for Next.js. Run fly launch, and it detects your Next.js app and generates a Dockerfile. If you have output: "standalone" set in your next.config.ts, the generated configuration adapts to that and the resulting image size drops by around 400 MB.
The deployment model is persistent VMs rather than pure serverless. This matters for Next.js 16 specifically because it means you're not fighting cold starts the way you would with a scale-to-zero model. It also means WebSockets and long-lived connections work without special handling — they're supported at the VM level.
What Fly gives you versus raw VPS: a simpler deployment workflow, per-second billing, and a managed networking layer. What you still own: TLS (via automated Let's Encrypt, but you configure it), rate limiting, observability, and scaling decisions. Fly doesn't include a built-in WAF. If you want DDoS protection and rate limiting at the edge, you're putting Cloudflare in front of it yourself.
Observability is serviceable — fly logs works, and you can forward to external tooling — but it's not opinionated about this the way Vercel is.
Cost at small scale: a shared 256 MB instance runs around $1.94 per month plus $2 per month for a dedicated IPv4 address. At growing product scale with a couple of containers, you're looking at $6–20 per month in compute. The Fly model rewards you at predictable, steady traffic. Spiky workloads require you to scale manually or via the CLI, which adds ops overhead.
Where it fits: Teams comfortable with Docker who want the fly launch experience and don't need Vercel-specific edge features. Good for apps that need persistent connections. Requires real investment in security and observability tooling.
Google Cloud Run
Cloud Run is the most production-ready of the container PaaS options for Next.js 16. The deployment story is gcloud run deploy --source . — it builds a container from your source and deploys it. For Next.js 16.x, this works without special configuration.
Autoscaling is a genuine strength here. Cloud Run scales based on requests and concurrency, handles scale-to-zero for cost savings, and you can set minimum instances to avoid cold start latency on warm paths. The observability stack is also proper — Cloud Logging, Cloud Monitoring, and Cloud Trace with OpenTelemetry integration give you a real production monitoring setup without bolting on three external tools.
What Cloud Run doesn't give you: a built-in WAF or rate limiting. Security at the edge requires Cloud Armor or Cloudflare in front of your deployment. You also lose per-preview deployment URLs and Vercel-specific integrations, which may or may not matter depending on your workflow.
For Next.js 16 specifically, streaming and SSR work correctly as long as your container is stateless and respects Cloud Run's request timeout and concurrency configuration. WebSockets require a dedicated service setup rather than the default HTTP model.
Cost is usage-based per vCPU and memory per second. A couple of containers handling a growing product workload runs roughly $20–40 per month in compute. Add managed Redis for shared ISR cache and a CDN layer and you're looking at $50–100 per month total infrastructure for steady mid-scale traffic — well below what that same workload costs on Vercel once bandwidth overages enter the picture.
Where it fits: Teams that want managed container autoscaling with solid observability without Vercel lock-in. Good when you're already in the Google Cloud ecosystem. Best suited to stateless SSR workloads rather than apps needing persistent connections.
Railway
Railway positions itself as an all-in-one platform — servers, databases, and AI agents in a single deployment surface. There's a Next.js 16.1 template that claims to run full client and server-side functionality in a single deployment.
The honest assessment from the data: Railway's Next.js 16.1 template had a 44% success rate on recent deploys at the time this research was compiled. That's a real reliability concern for production use and something to validate carefully before committing to it for anything business-critical.
Scaling on Railway is vertical within a service or horizontal via additional services, rather than the serverless autoscaling you get on Cloud Run. Logging and metrics exist per service, and you can integrate external observability, but it's less opinionated than either Vercel or Cloud Run.
Where Railway has a genuine use case is full-stack deployments where you want your Next.js app, database, and other services on one platform with unified billing. If that operational simplicity is worth the current maturity tradeoffs, Railway is worth evaluating carefully.
Where it fits: Developers who want a single platform for their full stack and are willing to do their own deployment reliability testing. Probably not the right choice for production-critical workloads at this point without careful validation.
Render
Render supports Next.js SSR, ISR, and API routes through its Web Service deployment type. The model is similar to Railway in concept — deploy from Git or Docker, get managed TLS via Let's Encrypt, handle scaling manually or via CPU/memory autoscaling rules.
Render doesn't have a built-in WAF, so Cloudflare or similar goes in front for real security posture. Observability requires external tooling beyond the basic per-service logs and metrics available in the platform.
One consistent practical note from community usage: zero-downtime rolling deploys for Next.js on Render require deliberate configuration — it's not automatic, and getting it right requires some work upfront.
Render's positioning is "flexible infrastructure for SSR/ISR/API routes" — teams who want to treat Next.js as a containerized web service rather than a platform-native first-class citizen. The tradeoff is the same as the other container PaaS options: you gain cost predictability and lose Vercel-specific integrations and polish.
Where it fits: Teams who want PaaS simplicity without the raw ops burden of bare VPS, and who are willing to invest in getting zero-downtime deploys configured correctly.
Bare VPS (Hetzner, DigitalOcean, Akamai/Linode)
This is where you get maximum cost efficiency and maximum ops responsibility. The numbers are hard to ignore: Hetzner's CX22 (2 vCPUs, 4 GB RAM) runs around $4 per month. Their CX32 (4 vCPUs, 8 GB RAM) is around $7 per month. DigitalOcean's 4 GB / 2 vCPU Droplet is $24 per month. Akamai/Linode's 4 GB plan is also $24 per month.
The meaningful included bandwidth on these plans — Hetzner includes 20 TB per month, DigitalOcean includes 500–6000 GB depending on the plan — is significant when you're comparing against Vercel's $0.15 per GB overage above their 1 TB Pro tier. For a high-traffic content site at 5 TB of bandwidth, that's a $600 monthly line item on Vercel versus well within the included transfer on a Hetzner plan.
What you get in exchange for those numbers is full ownership of everything. The self-hosting guide for Next.js 16 is explicit about this: you need a reverse proxy (Nginx, Caddy, or Traefik) in front of your Next.js server for rate limiting, DDoS mitigation, slow connection attack handling, and payload size enforcement. TLS certificate lifecycle is your responsibility. Secret management, supply chain security, and dependency patching are yours. Incident response has no platform support to call.
The production-grade self-hosted architecture for Next.js 16
The community has converged on a specific pattern for running Next.js 16 on a VPS with Docker, and it's worth laying out concretely.
The build configuration starts with output: "standalone" in next.config.ts. This produces a minimal server bundle in .next/standalone that reduces image size significantly and is explicitly what Fly.io, the Next.js Docker docs, and the Kubernetes examples all point toward for production.
The Dockerfile follows a multi-stage build pattern: a builder stage installs dependencies (including Sharp for image optimization) and runs next build, and a runner stage copies .next/standalone, .next/static, and public, sets NODE_ENV=production, exposes port 3000, and runs node server.js. This is the pattern documented in the Next.js standalone Docker examples and the OneUptime production guide.
The reverse proxy sits in front of the Next.js container and handles TLS termination, rate limiting, and static asset cache headers. For Nginx, this means setting Cache-Control: public, max-age=31536000, immutable for /_next/static assets. One important detail: rate limiting rules must match where Server Actions actually route to — in the App Router, that's often a POST to /, not to a named path. An Nginx rule scoped to a specific route will miss Server Actions entirely.
Shared cache becomes necessary the moment you run more than one instance. Next.js 16's ISR and Cache Components default to the filesystem on the Next.js server, which is only coherent for a single-instance deployment. For multi-instance, you configure Redis or ValKey via cacheHandlers in next.config.ts and set cacheMaxMemorySize: 0 to disable in-memory caching and force all cache reads and writes through the remote store. There's a documented Kubernetes example doing exactly this with two Next.js pods and one Redis pod — the same pattern applies on a two-container VPS setup.
A CDN layer (typically Cloudflare) in front of your reverse proxy handles static asset delivery globally and provides DDoS protection. For media-heavy or high-bandwidth content, moving large assets to object storage (Cloudflare R2, S3) and serving from CDN rather than your Next.js origin is a documented pattern for controlling bandwidth costs at scale.
The real operational cost
Bare VPS infrastructure looks extremely cheap. The honest accounting includes the engineering time. Initial setup for a production-grade self-hosted Next.js 16 deployment — Docker, reverse proxy, shared cache, observability, CI/CD pipeline — runs 20–60 engineering hours depending on your starting point. Ongoing maintenance for a straightforward app runs 4–12 hours per month. Complex setups with multiple services and strict compliance requirements can run one to three days per month.
At a loaded senior engineer rate of $150–300 per hour, the ops cost at the low end ($600–$1800 per month for ongoing maintenance) can easily exceed what you're paying for compute. The break-even point depends heavily on whether you have existing DevOps capacity or whether this represents net new engineering work.
The Known Failure Modes You Should Plan For
Across all self-hosted configurations, a few failure patterns show up consistently in 2026 production data.
Image optimization memory usage. Next.js optimizes images at runtime, not build time. On glibc-based Linux, this can produce excessive memory usage without additional configuration. Sharp must be correctly installed in standalone mode — the error "sharp is required to be installed in standalone mode for the image optimization to function correctly" shows up in Docker deployments where Sharp isn't bundled into the runner stage. Tune Node's --max-old-space-size based on your container's available memory: a rule of thumb from the maintainers is 512–768 MB heap for a 1 GiB container.
The proxy.ts execution bug in certain reverse-proxy setups. There's an open GitHub issue (#86122) showing that proxy.ts — the renamed middleware in Next.js 16 — does not execute in some self-hosted configurations using output: "standalone" behind Cloudflare or Traefik. middleware.ts continues to work in the same configurations. The current community workaround is staying on middleware.ts until the root cause is resolved. This matters if you were planning to rely on the new Proxy API for authentication or routing logic.
Proxy bypass at the reverse-proxy layer. Independent of the above, there's documented security research showing that Next.js middleware and Proxy behavior can be bypassed by manipulating a specific HTTP header in Traefik setups. Authentication and authorization must not rely solely on Next.js-layer middleware if your reverse proxy can be tricked. Enforce security at the edge, not only in Next.js.
Build size increases from Next.js 16. The larger .next output in 16 increases deploy times and storage requirements, which compounds in CI environments running frequent deploys. If you're deploying many times per day, the build time increase from 15 to 16 is worth measuring before rolling out.
Cost Comparison at Three Traffic Scales
Small SaaS or hobby project (300k pageviews/month, 60 GB bandwidth, modest API usage):
Vercel Pro typically lands at $20–50 per month at this scale, usually within included limits with some headroom. A Hetzner CX22 with optional CDN runs $5–20 per month in infrastructure. The difference narrows considerably when you account for 2–4 hours per month of ops time.
Growing product with spikes (5M Edge Requests, 500 GB bandwidth, active Server Actions):
Vercel Pro with overages lands around $28–40 per month in raw usage, but this is where the variability becomes unpredictable. Self-hosted at this scale — a DigitalOcean 4 GB Droplet plus a small Redis instance plus CDN — runs around $45–55 per month in infrastructure. The cost calculation inverts quickly when ops time is included, but if that work is being done anyway for your infrastructure generally, the marginal cost of adding Next.js to it is lower.
High-traffic content site (20M Edge Requests, 5 TB bandwidth, heavy images):
Vercel's bandwidth overage alone — 4 TB above the included 1 TB at $0.15/GB — is $600 per month, plus Edge Request overages and image optimization charges. Total often exceeds $650–700 per month. Three Hetzner CX42 instances plus CDN runs around $152–200 per month in infrastructure. The ops time is real and must be staffed, but even at 20 hours per month the self-hosted cost is often materially lower.
Making the Call
Choose Vercel when speed to ship is the priority, your team doesn't have DevOps capacity, you rely on per-preview deployment URLs as part of your workflow, or your traffic is unpredictable and you need autoscaling without designing it yourself. At small scale, Vercel's DX advantages are real and the pricing is manageable.
Choose a container PaaS (Fly.io, Cloud Run) when you want Docker-based workflows without the full VPS ops burden, your workload is containerized cleanly, and you're willing to build your own security and observability layer. Cloud Run is the strongest choice for stateless SSR apps that need real autoscaling. Fly.io is stronger for apps with persistent connections or where you're comfortable managing VMs.
Choose bare VPS with Docker when you have existing DevOps capacity, cost control at scale is the primary driver, you have compliance or data residency requirements that constrain your platform choice, or you're running Next.js alongside other services where the ops overhead amortizes across the stack.
Railway and Render are worth evaluating for full-stack simplicity, but warrant careful reliability testing before production commitment, particularly Railway at its current maturity level.
The honest summary: at small scale, Vercel is probably still the right call. At sustained medium-to-high scale with predictable traffic, the infrastructure math shifts. Next.js 16's behavior accelerates that shift.
If you're running this stack with Payload CMS, there are additional considerations around database access patterns, admin routes, and why self-hosting often becomes the natural choice rather than just the cheaper one — I cover those in a separate piece.
Let me know in the comments if you have questions about specific configurations or want to dig into any of these platforms further. Subscribe if you want more of this kind of depth on the Next.js and Payload stack.
Thanks, Matija


