DEV Community

Lia
Lia

Posted on

Self-Hosted WAF on a $5 VPS: My Budget Security Setup

The $5 Challenge

Can you run a production-grade WAF on the cheapest VPS available? I tested it on a $5/month VPS (1 vCPU, 1 GB RAM, 25 GB SSD) from a major provider. The goal: protect a Node.js blog and a static site without exceeding the budget.

The Stack

┌─────────────────────────────────────┐
│ $5 VPS (1 vCPU, 1 GB RAM)           │
│                                     │
│  ┌─────────┐  ┌──────────┐          │
│  │ SafeLine │  │ Node.js  │          │
│  │ WAF      │  │ Blog App │          │
│  │ ~500 MB  │  │ ~300 MB  │          │
│  └────┬─────┘  └────┬─────┘          │
│       │              │               │
│  ┌────┴──────────────┴──┐           │
│  │   Nginx (reverse)     │           │
│  │   ~50 MB              │           │
│  └───────────────────────┘           │
│                                     │
│  Total RAM used: ~850 MB            │
│  Free: ~150 MB                      │
└─────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

What Worked

1. SafeLine on 1GB is tight but functional
The WAF's Docker containers used ~500 MB at idle (slightly less than the usual 700 MB — the 1GB constraint forced more aggressive memory management). Under moderate load (100 req/s), it stayed at ~550 MB.

2. Node.js blog ran fine with 300 MB
A simple Express app with SQLite database. Generated pages in ~15ms. The WAF added 1ms. Nobody noticed.

3. The sweet surprise: swap file saved us
I added a 1 GB swap file on disk:

fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
Enter fullscreen mode Exit fullscreen mode

When under load, the kernel swapped PostgreSQL's idle memory pages. SafeLine stayed responsive. The swap file is essential on a 1 GB box.

What Didn't Work

1. WordPress on the same box
WordPress + MySQL + PHP-FPM on the same 1 GB VPS with SafeLine hit the OOM killer within 2 hours. Separated WordPress to its own $5 VPS and it worked fine.

2. Concurrent deployments
SafeLine + docker compose up -d + npm run build happening simultaneously triggered OOM. Staggered deployments: build first, then start WAF containers.

3. Heavy PostgreSQL logging
Default SafeLine PostgreSQL settings wrote attack logs aggressively. Tuned postgresql.conf:

shared_buffers = 64MB
effective_cache_size = 256MB
maintenance_work_mem = 32MB
wal_buffers = 8MB
Enter fullscreen mode Exit fullscreen mode

These PostgreSQL tweaks saved 100 MB of RAM.

Benchmark Results (1GB VPS, 100 concurrent users)

Metric Without WAF With SafeLine Acceptable?
Avg response time 15ms 16ms
Requests/sec 1,200 850 ✅ (-29%)
RAM baseline 350 MB 850 MB ⚠️ tight
Peak RAM under load 450 MB 1,020 MB ⚠️ uses swap

The bottleneck was RAM, not CPU or WAF throughput. On a 2 GB VPS, throughput is 7,600 req/s. On 1 GB, it drops because the system spends cycles managing memory.

Is $5 Enough?

Use Case $5 VPS Enough?
Static site + WAF ✅ Yes, plenty of room
Small Node/Python app + WAF ✅ Yes, with swap
WordPress + WAF ❌ No, need 2 GB minimum
Multiple apps + WAF ❌ No, get 2-4 GB
API with heavy DB queries ❌ No, CPU + RAM starved

FAQ

Why not just use Cloudflare's free plan?

Cloudflare free terminates TLS at their edge — they can see your traffic in plaintext. If you handle sensitive data, a self-hosted WAF means the traffic is decrypted and inspected on your own server. No third party sees it.

Can I run SafeLine on a Raspberry Pi instead of a VPS?

Yes. A Pi 4 with 4 GB RAM is actually more comfortable than a $5 VPS. The ARM Docker images work. Electricity costs about $5/year. Perfect for homelab use.

What if my site gets popular and outgrows 1 GB?

Upgrade to a $10/month 2 GB VPS. The WAF itself doesn't need more — your app growing is what drives the upgrade. SafeLine scales linearly: add more CPU and it handles more QPS.


What's running on your $5 VPS right now?

#webdev #devops #security #tutorial

Top comments (0)