Serverless vs VPS for Side Projects
For a project you maintain in spare hours, the choice between serverless and a virtual private server is about attention rather than performance. This article compares cost shapes, workload fit, the operational ledger and four common project types.

The Scarce Resource Is Attention, Not Compute
Side projects fail for boring reasons. The certificate expired in month four. A dependency update broke the deploy and fixing it needed a free Saturday that never arrived. The bill grew quietly until it was easier to delete the whole thing than to investigate.
So the serverless versus virtual private server question, for a project you maintain in spare hours, is not really about performance. It is about which failure mode you can live with: a platform that does more for you but constrains what you can build, or a machine that does exactly what you tell it and nothing you forget to tell it.
Both answers are correct for different projects. What follows is the set of properties that actually distinguishes them, followed by four common project shapes and a recommendation for each.
Two Very Different Cost Shapes
A virtual private server bills for time. It costs the same whether it serves a million requests or none, and the bill is predictable to the cent before you deploy anything.
Serverless platforms bill for use: invocations, execution duration and the resources attached to them. An idle project costs close to nothing, and most providers include a free allowance that a genuinely small project may never exceed. The Lambda billing documentation and the equivalent pages for Cloud Run and Azure Functions describe the metering precisely.
The crossover is real but it sits further out than people assume. Sustained, steady traffic is cheaper on a machine you rent by the month, because you are paying wholesale for capacity instead of retail for each request. Spiky or occasional traffic is cheaper on a platform that charges nothing while nothing happens.
Watch the parts that are not compute. Serverless architectures accumulate managed pieces: an API gateway, a queue, a store, a log aggregator, each with its own meter. Data leaving the platform is charged either way, which the egress costs article covers, and it surprises people on both sides.
What Fits a Function, and What Does Not
Serverless is a good fit for work that is short, stateless and triggered by an event. A webhook receiver, a scheduled report, an image resizer, a form handler, an API endpoint that reads and writes a store: all natural.
It fits badly in four situations, and knowing them in advance saves a rewrite.
- Long running work. Every platform caps execution time. Video transcoding, large imports and slow scrapes have to be split into steps or moved to a container service.
- Persistent connections. WebSockets, long polling and anything that holds a socket open need a separate managed service rather than a plain function.
- Traditional database connections. Each concurrent function instance may open its own connection, and a PostgreSQL server allocates a process per connection. Without a pooler or a proxy, a traffic spike exhausts the database rather than the function.
- Anything that wants a filesystem. The writable space is temporary and local to one instance. State belongs in object storage or a database.
Cold starts deserve a calmer treatment than they usually get. An idle function must be initialised before it answers, which adds latency to the first request after a quiet period. Lightweight runtimes start quickly, heavier ones less so, and large dependency trees make it worse. For an API a human is waiting on, it is noticeable; for a webhook or a nightly job, it is irrelevant. Platforms offer ways to keep instances warm, but paying to keep capacity resident is exactly the cost shape you chose serverless to avoid.
The Operational Ledger
| Recurring task | Serverless | Your own VPS |
|---|---|---|
| Operating system patching | Platform | You, ideally unattended upgrades |
| Runtime version upgrades | You, on the platform deprecation schedule | You, on your own schedule |
| TLS certificates | Platform | You, automated with an ACME client |
| Scaling under load | Platform, automatically | You, by resizing or adding machines |
| Staying up when a host fails | Platform | You, or you accept the downtime |
| Backups | You, for whatever store you attached | You, for everything |
| Monitoring and alerts | Basic metrics included, alerts are yours | Entirely yours |
| Local reproduction of the environment | Harder; emulators approximate the platform | Easy; it is a Linux box |
Note the last row. On a server you can reproduce production on your laptop with a container and be confident. On a serverless platform, the gateway behaviour, the identity model and the event payloads are the platform, and local emulation is an approximation. That is the hidden tax on debugging.
Note also that the runtime upgrade row is not free on either side. Platforms retire old language runtimes on a published timetable, and a function left alone for two years will eventually stop being deployable.
Four Project Shapes and a Recommendation
A static site with a contact form
Static hosting plus one function for the form. There is nothing to run between visits, and this is the case serverless was designed for. Renting a server for it is wasteful.
A hobby API with a database and a handful of users
One small server. The traffic is trivial, the cost is a fixed small number, the database sits on the same private network, and you can read a log by typing journalctl -u app -f. The deployment workflow makes the setup repeatable, and an account at Vultr or a comparable developer cloud is enough.
A scheduled scraper or data pipeline
Functions, unless a single run exceeds the execution limit. Work that happens for ten minutes a day should not pay for twenty four hours of capacity. If the runs are long, a container service that scales to zero splits the difference.
A project that might become a product
Start on a server, keep the application boring and portable, and move specific pieces to managed services when a real bottleneck appears. This is the argument in the SaaS MVP hosting article: early architecture should optimise for the ability to change your mind.
The Combination Most Projects Land On
Very few mature side projects are purely one thing. The usual end state is a small server running the application and its database, with a few functions handling the work that genuinely spikes: webhook receivers, thumbnail generation, scheduled jobs and outbound notifications.
That split keeps the predictable part predictable and the bursty part cheap. It also keeps the debugging surface small, because the thing you touch every week is still a Linux machine.
An AWS account gives you both halves under one bill, which is convenient if you already know the platform. Developer clouds keep the server side simpler and cheaper, and a platform as a service sits between the two, trading control for having nothing to operate at all; the Heroku and Vultr comparison is a useful illustration of that trade. Either way, the billing model matters more than the badge, which is the subject of the pricing models article.
Common Questions
Can a serverless project produce a surprise bill?
Yes, through a retry loop, a misconfigured trigger or unexpected attention. Set a budget alert on day one, cap concurrency where the platform allows it, and make failing functions stop retrying rather than hammering a downstream service. Usage based billing has no natural ceiling unless you add one.
Is a container platform that scales to zero a third option?
It is, and often the best one. You package the application as a normal container, the platform runs instances only when requests arrive, and you keep the ability to run the same image on a server later. It avoids most function specific constraints while keeping the idle cost near zero.
How locked in am I with functions?
The business logic is portable; the edges are not. Event payload shapes, identity, gateway configuration and the managed services around the function are provider specific. Keep the handler thin and the logic in ordinary modules and a move becomes a rewrite of the edges only.
What about a server that I forget to maintain?
That is the honest risk. Enable unattended security upgrades, automate certificate renewal, set up an uptime check that emails you, and take an image snapshot before any manual change. A server with those four things survives neglect far better than one without.
Questions about a cloud account?
Ask about products, variants, availability or purchasing on either channel.



