Skip to content
___________________________
V.1.0.0 // SECURE CONNECTION
Return_to_vault
[LOG: 2026-03-01]

VPS Migration Retrospective

DevOpsInfrastructureRetrospective

VPS Migration: Vercel to Hetzner

Why I Left

Vercel is great until you need control. Custom headers? Limited. Server-side logic beyond edge functions? Complicated. Running a second app? Another project, another bill. And $20/month for a portfolio site felt like paying rent on an apartment I didn't fully own.

$6.65/month gets me a real server. Root access. Run whatever I want. No cold starts. No surprise invoices.

The Stack

ComponentChoiceWhy
ServerHetzner CPX11 (2 vCPU, 2GB RAM)Cheapest reliable option. Ashburn VA for US latency.
OSUbuntu 24.04 LTSBoring. Stable. That's the point.
Reverse ProxyCaddyAuto-SSL with zero config. 3 lines for HTTPS.
Process ManagerPM2Keeps Node alive, handles restarts, manages logs.
DNSCloudflare (proxied)Free DDoS protection, edge caching.
DatabasePostgreSQL 16Overkill for now. Ready when I need it.

Key Decisions

Caddy over Nginx. Nginx is the standard. Caddy is the shortcut. Automatic HTTPS provisioning, readable config, less than 5 minutes to set up. For a solo builder running one site, Caddy wins every time.

PM2 over systemd. Better Node.js integration. Built-in log rotation. Cluster mode if I ever need it. pm2 restart tcv is easier to type at midnight than debugging a systemd unit file.

Ed25519 SSH keys. Faster, shorter, more secure than RSA. Root login disabled. UFW firewall. Basic stuff, but basic stuff is what prevents stupid problems.

What Went Well

The entire migration took one evening. DNS propagation was the longest part. Caddy provisioned SSL certificates automatically. The site loads faster now because there are no cold starts. Serverless functions used to spin up in 1-3 seconds. Now it's instant because the server is always running.

What I'd Do Differently

Set up automated backups before the first deploy, not after. I added a cron job later, but that "later" was a week of running without backups. Stupid risk for zero reason.

Write the deploy script first. I deployed manually 3 times before writing deploy.sh. Each time I forgot a step. The script took 5 minutes to write and has saved me from myself every deploy since.

The Numbers

MetricVercelHetzner
Monthly cost$20 (Pro)$6.65
Cold start1-3 secondsNone
ControlLimitedFull root
DeploysGit push (automatic)SSH + script (10 seconds)

I'm never going back to managed hosting for a site this simple. The 10 seconds of manual deploy is worth full ownership of the stack.

Share

"End of transmission."

[CLOSE_LOG]