Your PHP App Doesn’t Need the Cloud
I’ve consulted on PHP projects where a couple of VPSes handle everything, and the question of moving to AWS comes up regularly. Each time, I’ve reached 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 and one for MySQL. Together they cost around 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 inside a VPC with its own subnets, security groups, and IAM roles. It came to around $100 a month, several times the cost, and the app wouldn’t have run any faster.
What cloud hosting is good at
Cloud providers do a few things genuinely well. They run managed services so you don’t have to operate your own database, they scale capacity up and down with traffic, and they give you global infrastructure for serving users anywhere.
The projects I’m describing don’t need any of that. MySQL runs
fine on its own small VPS; setting it up took ten minutes and a
couple of apt install commands, and 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 keeps them within about 30ms.
The debugging difference
What I appreciate most about a VPS is that it’s just a computer. I SSH in, look at files, read logs, and restart services. When something goes wrong, I look at whatever is broken.
On AWS, debugging tends to mean checking CloudWatch metrics and lining up timestamps across several services. When a security group blocks traffic, I’m reading down a table of inbound rules looking for the wrong CIDR range. IAM policies on their own have a learning curve measured in weeks. Every managed service is one more thing configured through a console or Terraform rather than a file on disk. It isn’t necessarily harder, but it’s complicated in a less familiar way for someone used to working directly on a Linux box.
I’ve watched teams lose entire afternoons to networking between services in the same VPC, or to IAM permissions that were almost right, or to RDS parameter groups that didn’t quite match the MySQL config they’d had before. Those costs are real even though they never appear 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 an rsync to a timestamped release directory followed by a symlink flip to go live. If a deploy goes wrong, flipping the symlink back is an instant rollback.
When one of these projects needed more capacity, upgrading to the next VPS tier took five minutes and no config changes.
At some point one of these projects might outgrow two servers. When that happens, they’ll move behind a load balancer, which is how I handle larger workloads already. And if a project eventually does need managed databases, autoscaling, or global distribution, cloud hosting will be the right call. Until then, a couple of VPSes do everything these projects need at a fraction of the cost.
Reliability
With two servers there’s no real redundancy: if either one goes down, the app goes down. For applications at this scale that’s a reasonable trade-off, and Hetzner’s uptime has been solid in my experience.
If I did need genuine redundancy, I’d double up each server with replication and DNS failover, which would still cost a fraction of the equivalent setup 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.