VPS and cloud providers
Shared hosting, VPS, managed platforms or cloud: what to pick, how to size it and what to do first.
In 30 seconds
There are four main ways to host a web app: shared hosting, a virtual private server (VPS), a managed platform that runs your code for you, and a full cloud provider with dozens of services. Each trades control for convenience and cost. For most small and medium projects a well-run VPS is fast, cheap and simple, as long as you secure it, back it up and watch it.
Why I use it
- My production servers run on DigitalOcean droplets with Ubuntu, so choosing, sizing and securing VPS instances is everyday work for me.
- I am consolidating four servers into two, one for a SaaS product and one for all other sites, because fewer, properly secured servers are cheaper and easier to look after.
- Snapshots with tested restores and provider-level firewalls are part of the baseline I apply to every server.
How it works
01Four ways to host an app
Think of hosting like housing. Shared hosting is a room in a shared flat: cheap and managed for you, but you share resources with hundreds of sites, cannot install your own software and one noisy neighbor slows you down. It works for simple PHP sites. A VPS is your own apartment: a virtual machine with guaranteed CPU, RAM and disk and full root access, where you are responsible for everything inside. A managed platform (PaaS) such as Vercel, Render, Fly.io, Railway or Laravel Cloud is a serviced apartment: you push code and it handles servers, scaling and TLS, at a higher price per resource and with platform limits. A hyperscale cloud (AWS, Google Cloud, Azure) is a whole city: virtual machines plus managed databases, queues, storage and networking, very flexible and very complex.
- Shared hosting: cheapest, least control. Good for brochure sites and small WordPress installs.
- VPS: full control at low cost; you own security, updates and backups.
- Managed platform: fastest to ship, pay for convenience, limited control.
- Hyperscale cloud: everything is available, but cost and configuration need real expertise.
02Choosing a provider
For VPS hosting, the popular options are DigitalOcean (droplets, clear UI, good docs, managed databases and object storage), Hetzner (very strong price-to-performance, data centers in Europe and the US), Vultr, Linode (now Akamai) and OVHcloud. AWS Lightsail offers simple VPS plans inside AWS. The big clouds make sense when you need specific managed services, compliance certifications, many regions, or your company already runs there. When comparing, look past the monthly price: check the data center locations, included bandwidth and the price beyond it, the quality of snapshots and backups, whether there is a cloud firewall and private networking, managed database and object storage options, API and Terraform support, and how support responds. Prices change, so compare current pricing pages rather than old blog posts.
- Location: close to your users; consider data-residency rules such as GDPR.
- Network: included traffic, egress price, IPv6, DDoS protection.
- Extras: cloud firewall, private network, snapshots, backups, object storage, managed DB.
- Operations: API, CLI, Terraform provider, status history and support quality.
03Sizing and region
Start small and measure; it is easy to resize a VPS later, and most providers let you scale up in minutes. A small site with nginx and PHP or Node runs comfortably on 1 to 2 vCPUs and 2 GB of RAM. Add a database, Redis and queue workers on the same machine and 4 GB or more is a safer start. Memory is usually the first limit, not CPU. Shared vCPU plans are cheap and fine for most web apps; dedicated vCPU plans give steady performance for CPU-heavy work. Choose the region closest to most of your users, keep servers that talk to each other in the same region, and remember that a CDN like Cloudflare can serve static files close to users anywhere. Watch load, memory and disk for a few weeks and resize based on data.
- Memory runs out before CPU on most web servers; plan for the database and workers.
- SSD or NVMe disk; keep user uploads and backups in object storage instead of a huge disk.
- Resizing up is usually easy; resizing the disk down often is not.
04Snapshots, backups and private networking
A snapshot is a full image of the server's disk at one moment. It is perfect before risky changes, because you can roll the whole machine back. Provider backups are scheduled snapshots, typically daily or weekly for a small surcharge. But both live at the same provider, and a disk snapshot of a running database may not be consistent. So also make application-level backups, such as a database dump, and copy them off the server, ideally to object storage at another provider or region. A backup only counts once you have restored it successfully. Private networking connects your servers over an internal network that is not reachable from the internet, so the app server can reach the database without exposing it publicly.
- Snapshot before upgrades, migrations and big config changes.
- Database dumps plus off-site copies; follow the 3-2-1 idea (3 copies, 2 media, 1 off-site).
- Test restores on a fresh server on a schedule.
- Use the private network for database and cache traffic between servers.
05Keeping costs under control
Cloud bills grow quietly. The usual leaks are forgotten servers and test environments, old snapshots and unattached volumes, oversized instances nobody resized, load balancers and static IPs you no longer use, and above all outbound traffic (egress), which on the big clouds is billed per gigabyte and can dwarf the server price. A VPS provider with generous included traffic is often far cheaper for bandwidth-heavy sites. Simple habits help: set a billing alert, tag or name every resource by project, review the bill monthly, delete what you do not use, and put a CDN in front of static assets. Consolidating many small, half-empty servers into fewer well-sized ones often cuts cost and maintenance at the same time.
- Billing alerts and budgets on every account.
- Monthly cleanup: old snapshots, volumes, IPs, test servers.
- Mind egress pricing; cache static files at a CDN.
- Commit to reserved or savings plans only for steady, long-term workloads.
06The first 10 minutes on a new server
A fresh public server is scanned within minutes, so secure it before you deploy anything. Create the server with your SSH key added, log in, update packages, create your own sudo user, confirm key login works for that user in a second terminal, then disable password and root login. Turn on the firewall with only SSH, HTTP and HTTPS, and mirror that in the provider's cloud firewall. Enable automatic security updates, install fail2ban, set the time zone and hostname, add a swap file on small instances, and take a first snapshot of the clean base. Finally set up monitoring and a disk alert. The commands for each step are covered in the other Linux lessons.
ssh [email protected] # first login with your key
apt update && apt full-upgrade -y
adduser your_user && usermod -aG sudo your_user
rsync -a --chown=your_user:your_user ~/.ssh /home/your_user/
# New terminal: ssh [email protected] must work before continuing
printf "PasswordAuthentication no\nPermitRootLogin no\n" > /etc/ssh/sshd_config.d/10-hardening.conf
sshd -t && systemctl reload ssh
ufw allow OpenSSH && ufw allow 80/tcp && ufw allow 443/tcp && ufw enable
apt install -y unattended-upgrades fail2ban
dpkg-reconfigure -plow unattended-upgrades
timedatectl set-timezone UTC && hostnamectl set-hostname web1
Use it when
- A VPS: small and medium apps, predictable traffic, a team comfortable with Linux, tight budgets.
- A managed platform: front-end and serverless-friendly apps where shipping speed matters more than control.
- A hyperscale cloud: managed services at scale, compliance needs, many regions or an existing company account.
- Shared hosting: simple sites with no custom software and no one to maintain a server.
Skip it when
- Avoid a self-managed VPS if nobody will apply updates, watch backups and respond to alerts.
- Avoid a hyperscale cloud for a small app just because big companies use it; the complexity and egress costs are real.
- Avoid shared hosting for apps that need background workers, WebSockets, custom extensions or Node.
Alternatives
- Managed platforms (Vercel, Render, Fly.io, Laravel Cloud)
Push code, get TLS, scaling and previews; higher price per resource and less control.
- AWS / Google Cloud / Azure
Every managed service you could want, with IAM, VPCs and real configuration work.
- Managed databases
Many VPS providers sell managed PostgreSQL or MySQL with backups and failover, offloading the riskiest part.
- Bare-metal dedicated servers
Whole physical machines for heavy workloads at a good price, with longer provisioning and no instant resize.
Best practices
- Secure a new server before deploying: keys only, firewall, updates, a non-root sudo user.
- Use both a host firewall and the provider's cloud firewall.
- Keep databases on localhost or a private network, never on a public IP.
- Snapshot before risky changes, keep off-site database backups and test restores regularly.
- Store uploads and backups in object storage so servers stay small and replaceable.
- Set billing alerts and review resources monthly.
- Document every server: what runs there, how it is deployed and how to restore it.
Common mistakes
- Treating provider snapshots as the only backup, at the same provider and never restored.
- Deploying first and hardening later, after the server has already been scanned for days.
- Picking the biggest instance up front instead of measuring and resizing.
- Forgetting test servers, snapshots and volumes that keep billing for months.
- Choosing a region far from users or splitting the app and database across regions.
Deep dive
07What a vCPU really is: hypervisors, steal time and storage
A VPS is a virtual machine on a physical host shared with other customers, run by a hypervisor such as KVM. A vCPU is usually one hardware thread of a host core, scheduled among many guests. On shared-CPU plans the provider assumes not everyone is busy at once; when neighbors are, your VM waits, and that waiting shows up as steal time, the st value in top and vmstat. Consistent steal above a few percent means you are paying for CPU you do not get, and a dedicated-CPU plan or another host fixes it. Storage differs too: local NVMe is fast and low-latency but tied to the host, while network block volumes survive host failures and can be moved, but have higher latency and IOPS limits per volume size. Knowing which one you have explains benchmark results that otherwise make no sense.
top -bn1 | head -5 # look at 'st' in the %Cpu(s) line
vmstat 1 10 # last column 'st' = steal
lscpu | grep -E 'Model name|Thread|Hypervisor'
systemd-detect-virt # kvm, xen, microsoft...
# Quick disk benchmark (apt install fio), on a test file, not a live DB
fio --name=randread --rw=randread --bs=4k --size=1G --runtime=30 \
--ioengine=libaio --direct=1 --filename=/var/tmp/fio.test
08Servers as code: cloud-init and rebuildable machines
The most robust server is one you can recreate in minutes. Almost every provider supports cloud-init: you pass a user-data document when creating the VM, and on first boot it creates users, installs SSH keys, installs packages and runs commands. That turns the first ten minutes of hardening into a file you review and version, so every new server starts identical. Tools like Terraform or OpenTofu go one level higher and describe the servers, firewalls, volumes and DNS records themselves through the provider's API, and configuration tools like Ansible handle ongoing changes inside the machine. Even if you never automate fully, keeping user-data and a written runbook means a lost server is an inconvenience rather than a crisis, because nothing important exists only in someone's memory.
#cloud-config
users:
- name: your_user
groups: [sudo]
shell: /bin/bash
lock_passwd: true
ssh_authorized_keys:
- ssh-ed25519 AAAAC3...placeholder your_user@laptop
ssh_pwauth: false
disable_root: true
package_update: true
package_upgrade: true
packages: [ufw, fail2ban, unattended-upgrades]
runcmd:
- [ufw, allow, OpenSSH]
- [ufw, allow, 80/tcp]
- [ufw, allow, 443/tcp]
- [ufw, --force, enable]
09Availability on a small budget: RPO, RTO and single points of failure
Two numbers make availability discussions concrete. RPO (recovery point objective) is how much data you can afford to lose, which sets the backup frequency: nightly dumps mean up to a day of lost orders. RTO (recovery time objective) is how long you can be down, which sets how much must be automated. A single VPS is a single point of failure, and that is often acceptable if RPO and RTO are agreed and tested. Cheap improvements come first: more frequent dumps or continuous binlog or WAL archiving to object storage, a reserved or floating IP that can be moved to a replacement server, DNS TTLs kept moderate, and a rehearsed restore. Running two app servers behind a load balancer only helps once the database, sessions and uploads are no longer on a single machine.
- Agree RPO and RTO with the business before choosing the architecture.
- A floating or reserved IP lets you swap servers without waiting for DNS.
- Restore drills turn a written RTO into a measured one.
10The scaling path from one VPS
Scale in steps and only when measurements demand it. Step one is vertical: a bigger plan, which takes minutes and changes nothing in the app. Step two is separation: move the database to its own server or a managed database on the private network, so app and data stop competing for memory, and move uploads to object storage. Step three is horizontal: several identical app servers behind a load balancer. That requires stateless app servers: sessions and cache in Redis or the database, files in object storage, scheduled jobs running on exactly one node, and deploys that update every node consistently. Step four is read replicas, queues for slow work and a CDN for static content. Each step adds cost and operational work, so a well-tuned single server often goes further than people expect.
- Vertical first, then split the database, then go horizontal.
- Horizontal scaling needs stateless app servers.
- Make sure cron and schedulers run on one node only.
Real-world scenarios
Migrating a live site to a new server with minimal downtime
Problem
A site with a database and user uploads must move from an old VPS to a new one at another provider. The business accepts at most a few minutes of downtime.
How to solve it
Lower the DNS TTL to 300 seconds a day or more before. Build the new server from your hardening baseline, deploy the app, and rsync uploads in advance. Test it via curl --resolve or a hosts file entry. At the cutover, put the old site into maintenance mode, take a final database dump and restore it on the new server, run a last rsync of uploads, then switch DNS. Keep the old server running read-only and watch both access logs until traffic has fully moved. Verify orders, logins and emails, then raise the TTL again. Keep the old server and its snapshot for a week before deleting them.
The server is slow and CPU graphs make no sense
Problem
Response times on a shared-CPU VPS double at random hours. The app's CPU usage barely changes and there were no deploys or traffic spikes.
How to solve it
Look at steal time: vmstat 1 or top during a slow period. If st regularly climbs above about 5 to 10 percent, other tenants on the same host are taking CPU time your VM is waiting for. Collect evidence with a monitoring agent that records steal over several days. Options, from cheapest: ask support to migrate the VM to another host, resize to a different plan (which often moves it), or switch to a dedicated-CPU plan for steady performance. Also rule out disk: compare iostat latency with the volume's IOPS limit, because a throttled network volume produces similar symptoms with low CPU.
Losing access to the provider account
Problem
A team member's email was compromised and an attacker tried to log in to the cloud account. You realize that all servers, snapshots and backups live in that one account.
How to solve it
Contain first: reset the password, require hardware keys or app-based two-factor authentication for every user, revoke API tokens and review recent activity and created resources. Then remove the single point of failure: copy database dumps and uploads daily to object storage at a different provider, with credentials that can write but not delete, and enable object versioning or retention locks so backups cannot be wiped. Give each person their own account with least-privilege roles instead of shared logins. Document how to rebuild servers from cloud-init and backups elsewhere, and set billing alerts, which also catch crypto-mining abuse quickly.
Cheat sheet
- Check CPU steal time
vmstat 1 5 (column st)- Which hypervisor am I on
systemd-detect-virt- Did cloud-init finish and succeed
cloud-init status --long- Logs of the first-boot setup
sudo less /var/log/cloud-init-output.log- Test a site on a new server before DNS
curl --resolve example.com:443:203.0.113.20 https://example.com/- Check the current TTL of a record
dig +noall +answer example.com A- Final sync of uploads at cutover
rsync -aH --delete --dry-run old:/srv/app/uploads/ /srv/app/uploads/- Basic disk benchmark
fio --name=t --rw=randread --bs=4k --size=1G --direct=1 --runtime=30- Open ports seen from outside
nmap -Pn -p 1-1000 203.0.113.10
In my real projects
- I run four production Ubuntu servers on DigitalOcean droplets hosting Laravel and Next.js sites for my own products and for clients.
- My baseline for each of them: SSH keys only, ufw plus the provider firewall with only 22, 80 and 443 open, unattended-upgrades, fail2ban, and snapshots with tested restores.
- My plan is to consolidate four servers into two, with off-server backups and uploads moving to S3-compatible object storage, migrating by inventory, copy, verify, DNS switch and keeping the old server until everything is verified.
Questions & answers
Q1When would you choose a VPS over a managed platform like Vercel or Render?
A VPS makes sense when I need full control over the stack, such as background workers, cron, WebSockets, custom PHP extensions or several apps sharing one database, and when the cost per resource matters. A small VPS often costs a fraction of the equivalent managed resources and includes generous traffic. The price is responsibility: updates, security, backups and monitoring are mine. A managed platform wins when the team wants to ship quickly without operations work, needs preview deployments and automatic scaling, or the app is front-end heavy and fits the platform's model. Many projects combine both: the front end on a platform, APIs and workers on a VPS.
Q2How do you decide how big a server should be?
I start from what will run on it: web server, app runtime, database, cache and workers, and estimate memory first, because RAM is usually the first limit for web workloads. A small app runs fine on 2 GB; with a database and workers on the same box I start at 4 GB. Then I measure real usage for a few weeks: load average against cores, available memory, swap activity, disk growth and response times. Resizing up on most providers takes minutes, so starting modest and scaling on data is cheaper than guessing big. If one resource dominates, I pick a plan type tuned for it, like dedicated CPU.
Q3What is the difference between a snapshot and a backup?
A snapshot is a point-in-time image of a whole disk, taken by the provider. It is great for rolling back a server after a failed upgrade, but it usually lives at the same provider and region, and a snapshot of a running database can be inconsistent. A backup, in the stricter sense, is a copy of your data that can survive the loss of the server, the account or the provider: for example a nightly database dump and uploaded files copied to object storage elsewhere. I use both, and I only trust either after a test restore onto a fresh server has actually worked.
Q4What do you do in the first minutes on a new server?
Before deploying anything: log in with the SSH key I added at creation, update all packages, create a personal user with sudo, and confirm key login works for that user in a second session. Then disable password authentication and root login over SSH and validate the config with sshd -t. Enable ufw with only SSH, HTTP and HTTPS, and set the same rules in the provider's firewall. Turn on unattended-upgrades, install fail2ban, set the time zone and hostname, add swap on small instances, then take a clean snapshot. Monitoring and a disk alert come next, then the application.
Q5How do you keep cloud costs under control?
Visibility first: billing alerts on every account and every resource named or tagged by project, so nothing is anonymous. Then a monthly review to delete forgotten test servers, old snapshots, unattached volumes and unused IPs or load balancers. Right-size instances based on monitoring rather than guesses. Watch egress: on the big clouds outbound traffic is billed per gigabyte, so a CDN in front of static assets and object storage with reasonable egress pricing matter. For steady workloads, reserved capacity or savings plans reduce cost, but only after usage is known. Often the biggest saving is consolidation: several half-idle servers become one well-sized one.
Q6Why use private networking between servers?
Private networking gives servers in the same region an internal network with private IPs that the internet cannot reach. The database, Redis or internal APIs can then listen only on the private interface, so they are never exposed publicly even if a host firewall rule is wrong. Traffic over the private network usually does not count against your bandwidth allowance and has lower latency. It also simplifies firewall rules: allow the database port only from the private subnet. For extra protection I still encrypt sensitive connections with TLS, since private does not mean isolated from every other customer on every provider.
Senior-level questions
S1A client wants 'high availability' on a small budget. How do you approach it?
I start by turning the phrase into numbers: how many minutes of downtime per month are acceptable, and how much data loss. Most small businesses need a fast, rehearsed recovery more than true redundancy. So the first investments are frequent off-site backups with point-in-time recovery for the database, monitoring with alerts, infrastructure described in cloud-init or Terraform, a floating IP and a tested restore that meets the agreed RTO. Real HA, meaning no single point of failure, needs at least two app servers, a load balancer, a replicated or managed database and shared storage, which multiplies cost and complexity. I present both options with prices and failure modes, and usually recommend the recovery-focused design until revenue justifies redundancy.
S2When would you move from a VPS to a hyperscale cloud like AWS?
Not because of growth alone, since a well-sized VPS setup scales surprisingly far. The move makes sense when a specific need appears: managed services the team would otherwise operate badly, such as a multi-zone managed database, queues or serverless functions; compliance requirements that need certified infrastructure and detailed audit trails; multi-region deployment; fine-grained identity and access control for a large team; or a parent company that standardizes on one cloud. The costs are real: more complex networking and IAM, egress fees, charges for every public IPv4 address, and the risk of lock-in to proprietary services. A middle path is common: keep the core on VPS or containers that are portable, and use selected managed services where they clearly save work.
S3How do you make servers replaceable rather than unique?
By making sure no important state or knowledge lives only on the machine. Configuration is code: cloud-init user-data for first boot, Ansible or similar for ongoing configuration, and Terraform or OpenTofu for the servers, firewalls and DNS themselves. Application deploys come from a pipeline, not manual edits. Data lives outside or is continuously copied out: databases backed up off-site, uploads in object storage, logs shipped centrally. Secrets come from a secret store or protected env files that are rebuilt by automation. Then I prove it by rebuilding a server from scratch on a schedule. The trade-off is upfront effort and discipline, because one manual hotfix on a server breaks the guarantee until it is put back into code.
Glossary
- Hypervisor
- Software, such as KVM, that runs many virtual machines on one physical host and shares its CPU, memory and disks.
- vCPU
- A virtual processor given to a VM, usually one hardware thread of a physical core, possibly shared with other guests.
- Steal time
- Time a VM wanted to run but the hypervisor gave the CPU to another guest. High steal means noisy neighbors.
- IOPS
- Input/output operations per second: how many small reads and writes a disk handles, often capped per cloud volume.
- cloud-init
- The standard first-boot tool on cloud images that applies user-data: users, keys, packages and commands.
- Floating IP
- A public IP that can be moved between servers in a region, allowing failover without changing DNS.
- RPO
- Recovery point objective: the maximum amount of data, measured in time, you accept losing in an incident.
- RTO
- Recovery time objective: the maximum time a service may be down before it must be restored.
- Egress
- Outbound data transfer from a provider's network, often billed per gigabyte on hyperscale clouds.
Keep learning
Have a product in mind?Let's build it.
Tell me about your idea, your product or your team. I usually reply within one working day.