Vercel vs a VPS for an App a Coding Agent Just Generated

Elena Vasquez

Elena Vasquez

September 30, 2026

Vercel vs a VPS for an App a Coding Agent Just Generated

The app took an agent about forty minutes to write. It was a booking tool for a friend who runs a ceramics studio in Gràcia: a calendar, a form, a Stripe checkout, an admin page where she could upload photos of the week’s pieces, and a nightly job that emailed students a reminder. Next.js, because that is what the agent reached for. A Prisma schema. A README that ended with a confident line: Deploy to Vercel with one click.

I clicked. It deployed. The landing page was fast, the preview URL looked professional, and for about a day I thought the hosting question had answered itself.

Then my friend uploaded eleven photos, and the next morning they were gone. The reminder emails never went out. And a PDF invoice route that worked on my laptop timed out every third request. None of those were Vercel bugs. They were the agent writing code for a machine that stays on, and me deploying it to a platform where nothing stays on.

That gap is the whole decision. Vercel versus a VPS is not really a question about price or speed for an agent-built app. It is a question about what the code assumes about the computer it runs on, and whether you have read the code closely enough to know.

What the agent assumed without telling me

When I finally read the repository properly, instead of skimming the diff summary, I found four assumptions that only hold on a long-running server.

The uploads went to disk. The admin route wrote files into public/uploads with fs.writeFile. On my laptop that folder persisted. On Vercel, the function’s filesystem is ephemeral; anything written outside the build output disappears when the instance is recycled. The photos existed for exactly as long as one warm container lived.

The reminder job was a timer. The agent had put a setInterval in a module that loaded with the server, checking every hour whether it was 8 p.m. That is a perfectly reasonable thing to write for a Node process that runs forever. On a serverless platform there is no “forever.” The module loads when a request arrives and the instance goes cold when requests stop. The timer never got its hour.

The database was a file. Prisma was pointed at SQLite in development and, because I had not changed it, in production too. On Vercel that file was baked into the deployment and effectively read-only. Bookings looked like they saved and then evaporated on the next cold start.

The PDF route did real work. It launched a headless browser to render an invoice. That is slow and memory-hungry on any machine, and on a function with a duration cap and a modest memory ceiling it failed whenever the instance was cold.

None of this was hidden. It was all in plain code. The agent did not lie; it wrote a normal Node application. The one-click line in the README was the part nobody had checked.

Developer at a kitchen table at night reviewing a laptop next to a paper invoice

The two ways to fix it

I had two honest options, and I think they are the same two options most people have with a freshly generated app.

Option one: bend the app to fit Vercel. Move uploads to object storage (Vercel Blob, S3, R2, whatever). Move the database to a managed Postgres. Replace the timer with a platform cron hitting an API route. Move the PDF rendering to a lighter library or an external service. Each of those is a reasonable change. Together they are a small rewrite, and a rewrite of code I did not write in the first place.

Option two: give the app the machine it expected. Rent a small VPS, run next start behind a reverse proxy, keep SQLite on a real disk, let the timer tick, let uploads land in a folder that actually persists, and back that folder up.

I asked the agent to do option one first, partly out of curiosity. It did it competently. It also touched nineteen files, added three new environment variables, two new vendor accounts, and a cron configuration file I would need to remember existed. For a studio with maybe forty bookings a week, that felt like buying a delivery van to carry a sandwich.

So I went with option two, and I want to be clear about why, because “VPS good, platform bad” is not the lesson.

When Vercel is the right answer for agent code

If the agent produced something that is mostly a front end, Vercel is excellent, and I would not talk anyone out of it. A marketing site, a docs site, a dashboard that reads from an API someone else runs, a form that posts to a third-party service. Anything where the server-side code is short request handlers that start, do a small thing, and finish.

For those apps you get things a VPS will not give you for free: preview deployments on every branch, a CDN you never configure, TLS that is simply there, rollbacks that are one click, and no operating system to patch. When an agent is pushing frequent commits, per-branch previews are genuinely useful, because you can look at what it built before it touches production.

The test I use now is short. Before deciding where an agent’s app lives, I search the repository for five things:

  • fs.writeFile, fs.createWriteStream, or any path under public/ or uploads/ being written at runtime
  • setInterval, node-cron, agenda, or any in-process scheduler
  • A database URL that starts with file:
  • WebSockets or server-sent events that need a connection held open
  • puppeteer, playwright, sharp on large images, child_process, or anything that shells out

If none of those show up, the app is already shaped for a platform and Vercel will probably just work. If two or more show up, the agent wrote a server, and you should either host a server or budget time to turn it into something else.

What the VPS actually cost me

The rental was the cheap part: a two-vCPU, four-gigabyte box from a European host for a few euros a month. The real cost was the evening I spent making it boring.

That evening looked like this. A non-root user. SSH keys only. A firewall that allows 22, 80, and 443. Unattended security upgrades. Node installed from the distribution’s LTS channel rather than whatever the agent’s README suggested. Caddy in front for TLS, because it gets certificates on its own. A systemd unit for the app so it restarts when it crashes and comes back after a reboot. A nightly job that copies the SQLite file and the uploads folder to object storage somewhere else, and a second job, a week later, where I actually restored from that copy onto my laptop to see if it opened.

I thought about putting a self-hosted panel on the box so it would feel more like Vercel, with a deploy button and a log viewer. I decided against it for an app this size, mostly because I wanted to be able to see a failed deploy as a failed command rather than as a green badge that lied. That is the main thing a PaaS panel gives up against a plain Docker Compose file: the button is friendlier, and the failure is easier to miss.

Deploys are a shell script: pull, install, build, restart the service. The agent wrote that script too. I read every line of it before I ran it, which is more than I had done for the Vercel deploy.

Hands on a keyboard beside a small blinking server on a desk in blue light

The part people underweight: who notices when it breaks

This is where I think the comparison gets honest.

On Vercel, a lot of failure is absorbed for you. The platform restarts things, scales things, and keeps the static parts up even if your functions misbehave. What it does not do is tell you that your code assumes a disk. It will cheerfully serve a site whose uploads vanish, because from the platform’s point of view nothing failed. The request returned 200.

On a VPS, failure is yours. If the disk fills up, the site stops. If you forget to renew something, it breaks. If the kernel update needs a reboot and your service does not come back, nobody pages you unless you set that up. But the failure modes are the ones the code was written for. The agent wrote a program that expects a disk, a clock, and a process that stays alive, and the VPS provides all three.

So the question I ask is not “which is more reliable?” Both are reliable at different things. The question is: which set of failures am I more likely to notice? For an app I did not write line by line, I would rather have the failures be loud and ordinary, like a stopped service, than silent and architectural, like writes that quietly go nowhere.

Money, briefly

At this studio’s scale, both options are cheap enough that price should not decide it. Vercel’s hobby tier is not meant for commercial use, so a paying business belongs on a paid plan, and the paid plan is a per-seat monthly fee plus usage. The VPS is a smaller fixed number. The difference over a year is less than one pottery class.

Where price starts to matter is usage that the agent introduced without thinking about it. Image optimisation on every request, a function that polls an external API every few seconds, a page that fetches uncached data from a serverless route on every view. On a platform, those turn into metered line items. On a VPS, they turn into CPU load, which is capped by the box you rented. Neither is wrong, but only one of them can surprise you at the end of the month, and I would want to know which the agent picked before I found out from an invoice.

What I would do next time

I have deployed three more agent-built apps since the ceramics one. Here is the order I now follow.

  1. Read the repo before choosing a host. Run the five-item search. It takes two minutes and it replaces a day of confused debugging.
  2. Tell the agent where it is going to run, up front. “This will run on a single small Linux VPS with a persistent disk” or “This will run on Vercel with no persistent filesystem and a managed Postgres” produces very different code. Most of my problems came from letting the agent default to “my laptop.”
  3. If it is mostly front end, use Vercel and do not overthink it. Previews alone are worth it when an agent is committing frequently.
  4. If it is a server, give it a server. A small VPS with a proxy, a service manager, a firewall, and a tested backup is an evening of work and then mostly silence.
  5. Do not let the README decide. The one-click line was written by the same agent that wrote the setInterval. It had no idea they contradicted each other.

My friend’s booking tool has been running on the little VPS for four months. The photos stay where she puts them. The reminders go out at eight. The PDF route is still slow, but it finishes, because nobody is killing it after a few seconds. The only incident was a full disk from logs I had not rotated, which took ten minutes to fix and taught me to add logrotate to my evening checklist.

If I had rewritten the app for the platform, it would also be running fine today. That is the honest conclusion: both hosts can carry an agent-built app. What neither host can do is tell you what the agent assumed. That part is still reading, and it is still yours.

More articles for you