Reducing Bills by 5X, Latency by 8X
The Awakening
That moment when you check your AWS bill and realize you're paying $30/month to host a website with one blog post and a profile picture? Yeah. That was me.
Here's the breakdown
- RDS (PostgreSQL): $14.11/month to store approximately 3 rows of data
- App Runner: $10.49/month to serve maybe 10 visitors a day
- The rest (S3, CloudFront, Route53): ~$5/month
I was essentially paying $1/row/week.
The Plan
The plan was simple: replace the expensive AWS services with a cheap VPS and call it a day. The execution was not.
Attempt 1: Hetzner Cloud
Everyone on the internet swears by Hetzner, and for good reason — €3/month for a VPS, best price-performance ratio out there. But what I didn't know was
Every single CX and CAX instance was sold out. Everywhere.
Nuremberg, Helsinki, Falkenstein; all gone.
Attempt 2: Fly.io
Fly.io has a generous free tier! — my AI assistant told me calmly.
The free tier turned out to be a 2-hour trial. Two hours. That's not a free tier, that's a demo. And the actual pricing? $20/month for a modest setup. That's worse than what I was already paying.
Attempt 3: Railway
Railway looked promising with its $5/month hobby plan. But the fine print reveals it's usage-based pricing with a $5 credit. After doing the math: $0.00023/vCPU/sec doesn't sound like much until you multiply it by "always on" as it worked out to about $10-15/month.
Also I don't know what it is with companies always trying to play it down with stuff like /vCPU/sec. Just give me an hourly price or a monthly price. Easy.
Attempt 4: Oracle Cloud
Oracle Cloud has an always-free tier with 4 ARM cores and 24GB RAM.
Wait, what? Free? Forever? 24GB of RAM?
Turns out Oracle is basically giving away servers like a desperate ex trying to win you back. The catch is that their signup process rejects half of all attempts.
I decided not to gamble on Oracle's signup roulette.
The Winner: Vultr
$5/month.
1 vCPU, 1GB RAM, 25GB SSD. Available. Done. No drama.
Also, the server lives in my own city.
The Migration
PostgreSQL → SQLite
The most satisfying part was deleting database infrastructure. My entire dataset — one post, a few tags, and a profile image reference did not need a managed PostgreSQL instance with multi-AZ failover and automated backups.
SQLite is just a file. No connection strings with SSL certificates, no VPC configurations, no security groups. Just file:/path/to/app.db.
The Prisma migration was straightforward, except SQLite doesn't support array types. A minor indignity.
AWS App Runner → Node.js on a VPS
Replaced a managed container service with just
node build
The server setup is now beautifully simple:
- Nginx as a reverse proxy
- systemd to keep the app running
- UFW for the firewall
- Total memory usage: ~23MB
The Purge
The most satisfying terraform plan output I've ever seen:
Plan: 0 to add, 1 to change, 23 to destroy.
23 resources destroyed. VPC, subnets, security groups, RDS, App Runner, ECR, IAM roles, SSM parameters — all of it. The only change was pointing CloudFront to the VPS instead of App Runner.
Result
| Before | After | |
|---|---|---|
| Monthly cost | ~$30 | ~$6 |
| Compute | App Runner (1 vCPU, 2GB) | Vultr VPS (1 vCPU, 1GB) |
| Database | RDS PostgreSQL | SQLite file |
| Infrastructure | 23 AWS resources | 1 VPS + S3/CloudFront |
| Memory usage | 2GB allocated | 1GB allocated |
The site also loads way faster (remember the server being located in my own city? Yup, that did the trick). But now my wallet is happier and I have one fewer reason to dread the first of the month.
Lessons Learned
- Managed services are for managing scale, not managing a blog. If your database has fewer rows than your Terraform files, you've over-engineered it.
- Free tier is the most overloaded term in cloud computing. Always check whether free means free forever, free for 12 months, or free for 2 hours.
- SQLite is underrated. It's not just for prototyping — it's genuinely the right database for low-traffic sites.
- A $6 VPS can do what $30 of managed services does, if you're willing to run
apt install nginxyourself. - Always check server availability before getting excited about pricing. RIP Hetzner dreams.
Disclaimer
- Parts of this were written by a 🤖, but all of it has been read, edited, and validated by a 🧬
- All prices are post-tax