Your PHP App Doesn’t Need the Cloud

I’ve consulted on PHP projects where a couple of VPSes handle everything. The question of whether to move to AWS comes up regularly, and each time I’ve come to the same conclusion: the cloud would add cost and complexity without solving a problem the project actually has.

One of these projects runs on two Hetzner VPSes: one for Nginx and PHP-FPM, one for MySQL. Together they cost about 10-15 euros a month, deployed with rsync.

I priced out the same workload on AWS once: EC2 behind an ALB, RDS for the database, ElastiCache for sessions, S3 for uploads, CloudFront in front, Route 53 for DNS, all in a VPC with subnets, security groups, and IAM roles. Around $100/month. Several times more expensive, and the app wouldn’t run any faster.

What cloud hosting gives you

Cloud providers offer three things that matter: managed services so you don’t run your own database, elastic scaling so capacity grows with traffic, and global infrastructure so you can serve users everywhere.

For these projects, none of those apply. MySQL runs fine on its own small VPS, and setting it up took ten minutes and a couple of apt install commands. Backups are a cron job running mysqldump to a separate location. Traffic doesn’t spike in any meaningful way, and the users are mostly in Europe, so a server in Falkenstein puts them within 30ms of almost all of them.

The debugging trade-off

What I appreciate most about a VPS is that it’s a computer. I SSH into it, look at files, read logs, restart services. When something goes wrong the debugging model is straightforward: look at the thing that’s broken.

With AWS, debugging means checking CloudWatch metrics and lining up timestamps across multiple services. When a security group blocks traffic I’m staring at a table of inbound rules trying to find the wrong CIDR range. IAM policies alone have a learning curve measured in weeks. Every managed service is another thing configured through a web console or Terraform instead of a config file on disk. It’s not that it’s harder exactly, it’s differently complicated, and the complications are less familiar for someone who’s used to working directly on a Linux box.

I’ve seen teams spend entire afternoons debugging networking between services in the same VPC, or IAM permissions that are almost right, or RDS parameter groups that don’t quite match the MySQL config they had before. Those are real costs that don’t show up on the monthly bill.

What the setup looks like

The web server runs Nginx and PHP-FPM with OpCache, the database server runs MySQL, and deploys are rsync to a timestamped release directory with a symlink flip to go live. If a deploy goes wrong I flip the symlink back for an instant rollback.

When one of these projects needed more capacity, we upgraded to the next VPS tier. Took five minutes with no config changes.

At some point one of these projects might need more than two servers. When that happens they’ll go behind a load balancer, which is how I handle larger workloads already. And if the workload eventually needs managed databases, autoscaling, or global distribution, cloud hosting will make sense. Until then, a couple of VPSes do everything these projects need for a fraction of the cost.

Reliability

With two servers there’s still no redundancy: if either one goes down, the app goes down. For apps at this scale that’s a reasonable trade-off, and Hetzner’s uptime has been solid in my experience.

If I needed real redundancy I’d double up each server with replication and DNS failover. Still a fraction of what the same setup would cost on AWS.

I wrote a book about this. Own Your Stack: PHP for Small Teams covers VPS setup, Nginx, PHP-FPM, MySQL, deployment, monitoring, and backups for small teams that don’t need the cloud.