Skip to content
Vercel vs Self-Hosting Next.js: The Honest Comparison
Milos KnezevicMilos Knezevic20 Oct 2026 · 11 min read

Vercel vs Self-Hosting Next.js: The Honest Comparison

Vercel fans call self-hosting masochism; self-hosters call Vercel a tax. Both are sometimes right — here is the math that tells you which one you are.

Vercel does not sell hosting

Strip away the marketing and Vercel sells one thing: the absence of an ops role. You push to a branch and about ninety seconds later there is a URL. Every pull request gets its own preview deployment that a reviewer can click instead of pulling the branch. Static assets sit on a CDN near your users without you configuring one. Traffic spikes and more function instances appear; traffic dies and you pay nothing for the idle. A bad deploy rolls back from a dropdown. None of that is hosting — a five-euro VPS hosts. That is the work of a part-time infrastructure engineer, packaged as a deploy target.

The mechanics of getting an app live there take about ten minutes, and I walked through every step in the Vercel deployment guide. The interesting part is not the how. It is the bill, and specifically the shape of the bill.

Hobby is free and genuinely generous, but it is licensed for non-commercial projects — the moment your site carries ads or a checkout, you are out of terms. Pro is 20 dollars per team member per month and includes a pool of usage: data transfer on the order of a terabyte, a large allowance of function invocations and compute time, a budget of image transformations. Most projects never exhaust the pool. The ones that do discover the real pricing model: Vercel charges in proportion to traffic, not features. A blog with ten readers and a blog with a hundred thousand run identical code and very different invoices.

The shape matters more than the exact numbers, because the numbers get adjusted and the shape does not. Bandwidth-heavy products — image galleries, file downloads, anything where each visitor pulls megabytes — hit the data-transfer overage first. Function-heavy products — every page rendered on demand, polling APIs, chatty server actions — hit invocation and duration costs instead. If your app is mostly static or well cached, you can ride the included pool to a traffic level most side projects never reach, and your bill stays at twenty dollars for years.

Self-hosting is cheap the way a puppy is free

Self-hosting Next.js is not exotic. next start is an ordinary Node server, and Vercel itself documents running it anywhere. The honest question is not whether it works but what has to surround it, because a process listening on port 3000 is maybe a tenth of a production deployment. The rest of the list is yours forever:

  • A reverse proxy in front of Node, terminating TLS and compressing responses
  • Certificate issuance and renewal, or a proxy that automates it
  • A deploy pipeline — something has to build the app and restart it without downtime when you push
  • Process supervision so a crash at 3 a.m. restarts instead of taking the site down until morning
  • Monitoring and alerting, because nobody emails you when your own server dies
  • OS security patches, log rotation, disk space, backups — every month, forever

Add it up honestly. If you have done this before, initial setup is an afternoon — four or five focused hours to a clean, repeatable deploy. If you have not, it is a weekend, because each piece works on the second attempt, not the first. Ongoing, a quiet server wants an hour or two a month: patch, check disk, glance at logs. The cost that never fits in a spreadsheet is the bad day — the certificate that silently failed to renew, the disk that filled with logs, the Node process the kernel started killing under memory pressure. Those days are rare, and they are entirely yours.

The modern minimal setup is two files and a server. Next.js builds a self-contained bundle when you set output to standalone in next.config.ts:

Dockerfile
# requires output: 'standalone' in next.config.ts
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/.next/standalone ./
COPY --from=build /app/.next/static ./.next/static
COPY --from=build /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]
Caddyfile
yourdomain.com {
    reverse_proxy localhost:3000
    encode zstd gzip
}

Caddy is doing more than proxying in those four lines: it obtains and renews TLS certificates automatically, which deletes the single most common self-hosting failure of the past decade. The deploy pipeline is a GitHub Action that builds the image and restarts the container over SSH — twenty lines you write once and forget. None of this is hard anymore. It is just yours.

Most of Next.js works fine off Vercel — here is what does not

The fear that Next.js is crippled away from Vercel is mostly out of date. Rendering, the App Router, Server Components, server actions, API routes and middleware all run unmodified under next start — middleware simply executes inside your Node process instead of at the edge. Image optimization works out of the box, because the sharp library ships with Next now. For a single-server deployment, the framework is genuinely portable.

The sharp edges live in caching, and specifically in ISR. On Vercel, revalidation is backed by shared infrastructure: every instance of your app sees the same cache, and a revalidateTag call invalidates everywhere at once. Self-hosted on one machine, ISR works without any configuration, because the cache is files on local disk. Run two instances behind a load balancer and the assumption breaks — each instance keeps its own cache and revalidates on its own schedule, so users see different versions of the same page depending on which box answered. The fix is a custom cacheHandler, usually backed by Redis, which Next supports officially but you configure, deploy and operate yourself.

warning

On a single server, ISR just works. The moment you add a second instance, configure a shared cacheHandler before anything else — split-brain caches produce the kind of bug report you can never reproduce, because the page really is different for the person reporting it.

Image optimization works but the CPU becomes yours: resizing a 4 MB upload into six responsive variants on a two-core VPS competes directly with rendering your pages, and the optimized output caches to disk you have to size for. The edge runtime is less a loss than a relocation — your middleware runs fine, but in one region, so the latency benefit of running auth checks physically near a user in another hemisphere is gone. Before mourning that one, ask whether you ever had users far enough away to notice.

The genuine loss is preview deployments. There is no self-hosted equivalent that comes close without real engineering effort, and once you have reviewed work by clicking a URL on every pull request, going back to pull-the-branch-and-run-it feels like losing a sense. If you work alone this costs you little. On a team, it is the feature people miss most.

The middle options everyone skips

The argument is usually staged as Vercel versus a bare VPS, and that framing is stale. Coolify and Dokploy are open-source platforms you install on your own server that give it a PaaS face: connect a Git repository and you get push-to-deploy, automatic TLS, a web dashboard, one-click databases. You still own the machine and pay only its rent — five to ten euros a month buys a VPS that comfortably runs several side projects — but the proxy configs and deploy scripts dissolve into a UI.

tip

Coolify on a cheap VPS is the best-kept secret for solo developers with several projects: one server, one fixed monthly bill, push-to-deploy for everything on it. You inherit the server's maintenance, but the per-project ops work drops to nearly zero.

Beyond that, other clouds run Next.js better than they used to. Railway, Render and Fly take your Docker image as a managed container and bill for resources rather than per request, which suits steady traffic. Cloudflare and AWS support Next through the OpenNext adapter — more setup, different trade-offs, dramatically cheaper bandwidth. And notice that this entire decision repeats one layer down: your database faces the same managed-versus-self-hosted fork, and I ran that math separately in the managed Postgres comparison. The pattern is the same — you are always buying back hours, the only question is the exchange rate.

The crossover math

Here is the only formula in this article. Take your effective hourly rate. Multiply it by the hours per month a server will actually take you — not the optimistic number, the one with the occasional bad day amortized in. Compare the result to the Vercel bill. Whichever number is smaller wins, and everything past that is tribal preference.

For a solo developer billing 50 euros an hour, two hours of server attention a month is 100 euros of foregone work to avoid a 20-dollar subscription. Framed that way, Vercel Pro is the cheapest employee you will ever hire — it works nights, never takes a holiday, and handles the deploy while you build the thing people actually pay for. This is why the Vercel-tax argument lands wrong for most individuals. The tax is real. It is also the smallest line item on the project.

The math flips in two situations. The first is bandwidth: when each visitor pulls megabytes, usage pricing scales with your success, and a flat-rate VPS or a bandwidth-cheap platform wins by an order of magnitude — this is where the tax metaphor stops being rhetoric and starts being arithmetic. The second is when your marginal cost of self-hosting is near zero: you already run a server, already patch it, already watch it, and one more container costs nothing but RAM. Agencies and home-lab people live here, and for them the Vercel bill really is pure overhead.

Lock-in is real, but it is not in your code

Lock-in is the loudest argument against Vercel and the weakest. Next.js is open source and runs anywhere Node runs; the standalone output target is officially supported, not a community workaround. Your application code does not call Vercel APIs. If you leave, you change where the build artifact runs — a weekend of infrastructure work, not a rewrite. Compare that to platforms where leaving means porting code, and the panic looks borrowed from somewhere else.

The real lock-in is softer and stronger: workflow comfort. After a year of preview URLs, instant rollbacks and environment variables managed in a dashboard, your habits — and your team's review process — quietly assume them. Leaving means rebuilding muscle memory, not just servers. That is not a trap; it is ordinary switching cost, and it deserves honest pricing: the longer you stay, the more the convenience compounds into dependence. Treat it like any dependency. Know your exit, even if you never take it.

The decision rule

Stop reading arguments and pattern-match your situation instead:

  • Solo developer or small team, normal traffic, your time bills by the hour: choose Vercel. Hobby for experiments, Pro the day a project earns money. Twenty dollars buys back hours every month.
  • Several side projects, comfortable owning one server, fixed costs matter more than time: choose a VPS with Coolify or Dokploy. One bill, push-to-deploy for everything on it.
  • Bandwidth-heavy product — media, downloads, heavy pages at real scale: self-host or pick a bandwidth-cheap platform from day one, because usage pricing will grow precisely as fast as your success does.
  • You already operate servers for other reasons: self-host. Your marginal cost is one container, and Vercel solves a problem you do not have.
  • A team whose review culture lives in pull-request previews: choose Vercel and stop feeling guilty. The workflow is the product you are paying for.

Notice what is missing from that list: performance. A well-built Next.js app is fast on a five-euro VPS and fast on Vercel — the hosting choice decides who carries the operational load, not how quick your pages are. And wherever the app runs, hosting is only one of the decisions standing between working code and production; the full path, from environment variables to monitoring to the deploy itself, is mapped in the guide to shipping Next.js to production.

My honest suggestion, if you are still unsure: deploy your current project to Vercel today, because it costs ten minutes and gives you a baseline. Build, ship, watch the invoice. If it never makes you wince, you have your answer. If one day it does, you will be deciding from a position of strength — a working app, a measured bill, and this framework — instead of from a comment thread.