A VPS is probably enough
Most applications are deployed onto infrastructure sized for a scale they will never reach. Here is how we decide what a system actually needs.
A significant share of the applications we are asked to review run on infrastructure built for a scale they will not reach for years, if ever. Kubernetes for a system with four hundred daily users. A multi-region database for an application whose users are all in one time zone. Six managed services for something a single well-configured server would carry comfortably.
Nobody chose this irresponsibly. It is what the reference architectures show, and it looks like the professional option.
But infrastructure has a running cost that is not only money. It is the number of things that can break, the number of concepts a new engineer must hold, and the number of layers between a deployment and a user seeing it.
The question that actually decides it
Not "how much traffic do we have" but: what happens when this goes down for ten minutes?
For a large share of business applications the honest answer is that some people are annoyed and some work is delayed. That answer permits a much simpler architecture than most teams give themselves permission to build.
If the answer is that money is lost by the minute, or a regulated obligation is breached, or someone's safety is affected — then the complexity is justified and this article is not about your system.
Most systems are the first kind, deployed as though they were the second.
What a single server genuinely handles
A modern VPS with a few dedicated cores and 8–16GB of RAM, running a server-rendered application with a sensibly indexed database, handles a workload that surprises people — comfortably into the millions of requests per month for typical business software.
The limiting factor is almost never CPU. It is nearly always one of:
- Queries with no supporting index
- N+1 query patterns in a list view
- Synchronous work that should be queued — email, image processing, third-party calls
- Images served at full size to phones
Every one of those is a code problem. Adding servers hides it temporarily and makes it more expensive to keep hiding.
A worked example: the AI verification service in this case study runs on Compute Engine — Ubuntu, Apache virtual hosts — and has handled six figures of identity checks alongside hundreds of thousands of classification calls. The web tier was never the constraint. The model calls were, which is why they are queued and metered rather than spread across more application servers.
What you give up, honestly
A single server has real limitations and it is dishonest to pretend otherwise:
- No automatic failover. Hardware failure means downtime until you restore.
- Deployment is a moment of risk without a second machine to shift traffic to.
- Vertical scaling has a ceiling, and reaching it means a migration.
- Backups are entirely your responsibility, including — especially — testing restores.
These are acceptable trade-offs for many businesses. They are not acceptable for all. The point is to make the trade deliberately rather than to default either way.
What we do regardless of size
Some practices are not about scale, and skipping them is how a simple deployment becomes a bad one:
Infrastructure in version control. Server configuration as code, so the machine can be rebuilt. A server nobody can reproduce is a single point of failure with a countdown on it.
A deploy that is one command, and a rollback that is one more. If deploying is a documented sequence of manual steps, it will be done wrong under pressure.
Tested restores. An untested backup is a belief, not a backup. Restore it somewhere on a schedule and confirm the data is actually there.
Monitoring that pages a human. Not a dashboard nobody watches — an alert on the handful of conditions that mean the system is genuinely unhealthy.
A CDN in front. Cloudflare or equivalent absorbs static assets and a surprising amount of abuse. This is cheap and worth it at any size.
When managed services earn their cost
Managed infrastructure is worth paying for when it removes work you would otherwise do badly.
Managed databases are usually worth it. Backups, point-in-time recovery and patching are handled by people who do it full time, and getting this wrong yourself is catastrophic rather than inconvenient.
Object storage is worth it immediately. Do not store uploads on the application server; it couples your data's durability to one machine's disk and makes horizontal scaling impossible later.
Managed queues and container orchestration are worth it when you have the traffic and the team to justify them. Before that they are mostly a tax paid in complexity.
Design so the decision stays reversible
The goal is not to be small forever. It is to avoid buying complexity before it is needed, while not painting yourself into a corner.
Two habits keep the door open. Keep the application stateless — no session or upload data on local disk — so adding a second machine is a configuration change rather than a rewrite. And keep infrastructure defined as code, so moving to a different platform is a change of target rather than an archaeology project.
Get those right and you can start on one server and move when the traffic actually arrives, rather than paying for the possibility of it for years.
The recommendation
Size infrastructure against the traffic and the team you have, not the diagram you would like to show. Fix the slow query before adding the second server. Then spend the difference on something the business can see.