For years, I did what most developers do.
I put everything behind a cloud WAF.
It made sense:
- change DNS
- enable proxy
- turn on a few managed rules
- done
In under 10 minutes you get:
- global CDN
- DDoS protection
- bot filtering
- a Web Application Firewall
Platforms like Cloudflare make this incredibly easy. Their WAF runs on a massive global network and automatically blocks common attacks using managed rules and threat intelligence.
For most projects, this setup is more than enough.
But over time I realized something:
Not all traffic fits well inside a cloud WAF model.
This post isn’t about abandoning cloud WAFs. I still use them heavily.
It’s about why I eventually moved part of my traffic off the edge network and back into infrastructure I control.
The Default Architecture Most of Us Use
If you're running a typical web service today, the architecture probably looks like this:
Internet
│
▼
Cloud WAF / CDN
│
▼
Origin server
│
▼
Application
The benefits are obvious:
- your origin IP is hidden
- large-scale DDoS protection
- global caching
- automatic WAF rules
Cloud WAFs are also easy to deploy because traffic simply passes through a proxy network. Often it’s literally just a DNS change.
For public websites and APIs, it’s hard to beat that convenience.
But after running several services behind this architecture, I started encountering edge cases where the model wasn’t ideal.
Problem 1: Not All Services Should Sit Behind a CDN
The first issue appeared when we started running non-traditional web traffic.
Examples:
- internal dashboards exposed via VPN
- developer tools
- webhook endpoints
- large file uploads
- internal APIs
These workloads behave differently from a public website.
They often involve:
- authenticated clients
- large request bodies
- long-lived connections
- unusual headers or protocols
A CDN-optimized WAF sometimes becomes an awkward fit.
For example, some WAF engines inspect request bodies only up to a certain size depending on plan configuration.
That’s usually fine for normal web traffic.
But if your application frequently handles large payloads, you may find the security layer doing partial inspection or bypassing certain checks.
Problem 2: The “Black Box” Problem
Cloud security platforms are powerful — but they are also abstracted.
You usually get:
- dashboards
- rule toggles
- aggregated logs
But you rarely see the raw request behavior in detail.
For example, when debugging attack traffic, I often wanted answers to questions like:
- what exact payload triggered the rule?
- what did the request body look like?
- which scanner generated it?
- what happened before the request was blocked?
Cloud dashboards often show the result of the decision, not the full context.
That abstraction is intentional — it keeps things simple.
But sometimes you want more control.
Problem 3: The Cost of Routing Everything Through One Network
Another subtle issue is architectural coupling.
When everything goes through a cloud WAF:
- DNS
- traffic routing
- security
- caching
- sometimes load balancing
all become tied to the same provider.
Most of the time that’s fine.
But occasionally you want flexibility like:
- exposing a service temporarily
- routing certain traffic directly
- running private endpoints
- testing infrastructure without the proxy layer
When everything sits behind a single edge network, those experiments become harder.
The Hybrid Approach I Eventually Settled On
Instead of removing the cloud WAF entirely, I ended up with a split architecture.
Public traffic still uses the edge network.
But some services bypass it and go through a local security layer.
Internet ──────► │ Cloud WAF/CDN│ ─────► Public Web Apps
│
▼
Internal Gateway
│
▼
Self-Hosted WAF Layer
│
▼
Services
This approach keeps the benefits of the cloud edge:
- global performance
- massive DDoS protection
- easy caching
But also allows more control for specialized services.
Where Self-Hosted WAFs Still Shine
Once I started experimenting with local filtering layers again, I remembered why they were popular before cloud WAFs took over.
A self-hosted WAF sits directly in your infrastructure:
Internet
│
▼
Reverse Proxy + WAF
│
▼
Application
That gives you things cloud platforms can't always provide:
Full request visibility
You can inspect:
- raw payloads
- headers
- request bodies
- full traffic logs
This makes debugging attacks significantly easier.
Fine-grained control
Because it runs in your environment, you can implement rules like:
- endpoint-specific policies
- per-service rate limits
- behavior rules based on internal logic
Cloud WAFs support custom rules, but they usually operate within platform constraints.
Running your own layer removes those limits.
Local traffic filtering
Many attacks never need to hit your application.
Common probes include:
GET /.env
GET /.git/config
GET /wp-login.php
GET /phpmyadmin
A local WAF can block these instantly without involving upstream services.
What I Look For in a Self-Hosted WAF
After trying a few options, I realized the most useful features for small teams are actually pretty simple:
- bot challenges
- request filtering
- rate limiting
- good traffic visibility
You don't necessarily need an enterprise security appliance.
You just need something that can sit in front of your services and reduce noise.
Recently I’ve been experimenting with SafeLine WAF, which takes the approach of packaging these features into a relatively easy-to-run self-hosted system.
The interesting part isn’t that it replaces cloud WAFs.
It’s that it fits nicely into the hybrid model described above — acting as a security layer for traffic that doesn't benefit from going through a CDN.
If you're curious, their website is here:
When You Should Absolutely Stay on a Cloud WAF
To be clear, cloud WAFs are still the best choice for many situations.
If your application is:
- a public website
- a global SaaS product
- heavily cacheable
- latency-sensitive worldwide
then the edge network advantages are enormous.
The global scale of providers like Cloudflare is impossible to replicate locally.
Final Thoughts
The biggest lesson from running production services is that security architecture rarely stays static.
What works for a small web app might not work for:
- internal tools
- APIs
- large uploads
- specialized infrastructure
Cloud WAFs solved many problems for developers.
But they also introduced a new pattern:
everything goes through the edge network.
Sometimes that's perfect.
Sometimes it isn't.
The solution, at least for me, wasn’t choosing one model over the other.
It was simply using both where they make sense.
Top comments (0)