← route

LSN 10/10 WAF·CACHE 14 MIN TIER FREE

Caching, WAF, and Bot Fight

Cache Rules, the WAF rulesets, Bot Fight Mode, and the gotchas that turn safety features into outages.

Before this: 05 Pages: hosting your first site

The proxy in front of your site is the place where caching and security live. Both features can save you money and reduce attack surface, and both can break your app in ways that are awkward to debug. This lesson covers the controls and the failure modes.

How Cloudflare caches

By default, Cloudflare caches responses with cacheable content types (static assets like .css, .js, images, fonts) and obeys whatever Cache-Control headers your origin returns. Dynamic content (HTML by default) is not cached unless you ask.

The way you ask is through Cache Rules. The way you debug is the cf-cache-status response header, which tells you what Cloudflare did for that request:

  • HIT — served from edge cache.
  • MISS — not in cache; Cloudflare fetched from origin and is caching the response for next time.
  • EXPIRED — was in cache but past TTL; fetched fresh.
  • BYPASS — a rule explicitly told Cloudflare not to cache.
  • DYNAMIC — content type not cacheable by default (e.g., HTML).
  • REVALIDATED — origin returned 304 to a conditional fetch.
curl -sI https://yoursite.com/style.css | grep -i cf-cache-status
# cf-cache-status: HIT

Make this your first reflex when investigating “why is my change not showing up”.

Cache Rules

The current way to control caching is the rules engine. In the dashboard: CachingCache RulesCreate rule.

A rule has:

  • A match condition, written as an expression (see below).
  • An action: Eligible for cache, Bypass cache, Custom cache TTL, Edge TTL, Browser TTL, Cache key customization, and a few more.

Examples:

# Cache HTML responses for 5 minutes at the edge
when:  http.request.uri.path matches "\.html?$"
then:  Edge TTL = 5 minutes

# Never cache anything under /api
when:  starts_with(http.request.uri.path, "/api")
then:  Bypass cache

# Treat query strings as part of the cache key on /search
when:  starts_with(http.request.uri.path, "/search")
then:  Custom cache key = host + path + sorted(query)

The legacy product was Page Rules, with a different UI and fewer capabilities. New work should use Cache Rules and the broader rules engine (Redirect Rules, Transform Rules, Configuration Rules, Origin Rules, all under the same expression language).

Purging

When you push a deploy, you usually want stale cache to clear:

  • Pages and Workers auto-purge cache for their own deploys.
  • For everything else, the CachingConfiguration page has three options: Purge Everything (sledgehammer), Custom Purge (by URL, hostname, tag, or prefix), and an API endpoint for both.
  • Cache Tags (Business plan and above) let you attach tags to responses and purge by tag, which is how a CMS-shaped workflow gets granular invalidation.

A purge is global within seconds.

The Web Application Firewall

The WAF sits between the cache and the origin. Two flavors:

Managed Rulesets are pre-built by Cloudflare (or sourced from OWASP) and toggled on or off per ruleset. CachingSecurityWAFManaged Rules. The defaults catch a lot of generic attacks (SQL injection patterns, XSS payloads, known bad strings) and have low false-positive rates for typical web traffic.

Custom Rules are yours, written in the same expression language as Cache Rules:

# Block requests to /admin from outside our office
when:  starts_with(http.request.uri.path, "/admin")
       and not ip.src in {203.0.113.0/24}
then:  Block

# Challenge requests with no User-Agent
when:  http.user_agent eq ""
then:  Managed Challenge

Actions include Block, Skip, Log, Managed Challenge (interactive CAPTCHA), JS Challenge (silent), and a few rate-limit-shaped variants.

The Security Events dashboard shows every WAF-triggered event with the rule that fired, the request details, and the action taken. This is the first place to look when a user says “I got blocked”.

Bot Fight Mode

A separate feature aimed at automated traffic. Cloudflare classifies incoming requests by likely-bot score (based on heuristics, behavior, JS challenge results) and acts on suspicious ones.

  • Bot Fight Mode is free and binary: on or off. When on, it challenges anything Cloudflare flags as a likely automated visitor.
  • Super Bot Fight Mode (Pro plan and above) adds finer controls and analytics.

Gotchas, in roughly the order people hit them:

  • Legitimate API clients get blocked. Anything calling your API with a non-browser user-agent looks like a bot. Either exclude /api from Bot Fight Mode (custom rule with Skip), or ensure your clients set a clear User-Agent and the WAF allowlists it.
  • Your own monitoring trips it. UptimeRobot, Better Stack, Pingdom pings can look bot-like. Whitelist their IP ranges or User-Agents.
  • RSS feed readers get challenged. They are technically bots. Often fine, occasionally a complaint.

Turn on Bot Fight Mode for a public marketing site. Be careful with it on an API.

Rate limiting

For request rate control specifically: SecurityWAFRate limiting rules. Define a condition, a threshold (N requests per M seconds from the same IP or fingerprint), and an action (Block for X minutes, Challenge, Log).

Common patterns:

  • 60 requests per minute per IP on /api/auth/* to slow down credential stuffing.
  • 1000 requests per minute per IP across the whole site, as a soft cap on misbehavior.

Free plan gets one rate-limiting rule. Paid plans get more.

Always-on DDoS protection

You do not configure this. Every Cloudflare zone gets always-on L3, L4, and L7 DDoS protection. Free. The bigger plans add more aggressive mitigation profiles and SLAs, but the baseline catches most volumetric attacks transparently.

Putting it together

A realistic baseline for a small production site:

  • Cache Rule: bypass cache for /api/*.
  • Cache Rule: 10-minute edge TTL on HTML for the public pages.
  • WAF: enable the Cloudflare Managed Ruleset on default action. Enable OWASP Core Ruleset on a moderate sensitivity.
  • WAF custom rule: block /admin from outside trusted IPs.
  • Rate limit: 60 req/min on /api/auth/*.
  • Bot Fight Mode: on for marketing pages; rule to skip it on /api/*.

Tune from there based on what shows up in Security Events and Cache Analytics. The default Cloudflare configuration is sane; these overrides exist to fit your specific application.

That is the end-to-end walkthrough. The site is registered, on Cloudflare, with DNS configured, a Pages site live, a Worker handling dynamic bits, storage chosen, auth in front of the private parts, API tokens for automation, and the cache and security layers tuned. From here, every other Cloudflare product is variations on the themes you have already seen.