Cloudflare Security Events Retention: Why Your WAF History Disappears So Fast
Your WAF blocked something suspicious on Friday night. On Monday morning you open Security → Events to take a look.
If you’re on a Free or Pro plan, it’s already gone.
Security Events retention by plan
Cloudflare documents these limits for Security Events (the log of WAF, rate limiting, bot, and other security actions):
| Plan | How far back you can see |
|---|---|
| Free | Last 24 hours |
| Pro | Last 24 hours |
| Business | Last 3 days |
| Enterprise | Last 30 days |
The maximum query window matches the retention period. You can’t page further back than this through the dashboard or the API.
Why it matters: Weekends, holidays, and “I’ll look at it tomorrow” are all longer than 24 hours. On Free and Pro, any event you don’t review the same day is lost.
What you lose when events expire
Security Events answer the questions you need during an investigation:
- Which IPs and ASNs triggered rules, and how often
- Which paths were probed —
/wp-login.php,/.env,/api/admin - Which rule fired and what action it took (block, challenge, log)
- Which user agents and countries the traffic came from
Once events roll off, the overview charts may still show that “something happened”, but not the details you need to act on it.
Events are sampled, too
Security Events come from the firewallEventsAdaptive datasets. The Adaptive suffix means Cloudflare uses adaptive sampling. When volume is low, you see every event. As volume grows — during an attack, for example — progressively lower sample rates are applied so queries stay fast.
Cloudflare’s docs are explicit that unsampled raw data is an Enterprise feature through Cloudflare Logs. On other plans, the sampled events are the best record you’ll get. That’s all the more reason not to lose them.
How to keep Security Events longer
You can’t change Cloudflare’s retention, but you can copy summaries out before they expire. The GraphQL API lets you group events and store the counts.
This query returns the top IPs, actions, and sources from the last 24 hours:
query ($zoneTag: string, $start: Time, $end: Time) {
viewer {
zones(filter: { zoneTag: $zoneTag }) {
firewallEventsAdaptiveGroups(
limit: 100
filter: { datetime_geq: $start, datetime_lt: $end }
orderBy: [count_DESC]
) {
count
dimensions {
clientIP
clientCountryName
action
source
}
}
}
}
}
Run it once a day, store the result as JSON, and you have a permanent record of who hit your WAF and what happened to them. This guide to archiving Cloudflare analytics to R2 shows how to schedule it with a Worker.
Two practical tips:
- Run it more than once a day on Free and Pro. With a 24-hour window, a failed run means a lost day. Running every 6 hours gives you some slack.
- Check your real limits first. The
settingsnode tells you exactly how far back and how wide each query can be on your plan.
When to upgrade instead
If you need every event, unsampled, with full request details, that’s what Enterprise and Logpush are for. For most smaller teams, daily summaries of IPs, paths, rules, and actions are enough to answer “has this attacker been here before?”
Let MetricKeeper keep the history
MetricKeeper connects with a read-only token and archives your Cloudflare security and traffic analytics on a schedule. Your WAF history stays searchable long after the 24-hour window closes.
Sources
- Cloudflare: Security Events
- Cloudflare: Sampling in the GraphQL Analytics API
- Cloudflare: Querying firewall events with GraphQL