A 90-minute debugging session, with curl outputs. TL;DR We run a 6,800-page games portal behind Cloudflare on the Free plan. Last week's audit flagged that cf-cache-status was returning DYNAMIC for every HTML request, despite an origin Cache-Control: s-maxage=31536000 . We spent 90 minutes building Cache Rules with every "correct" config — Eligible for cache, Edge TTL, browser TTL, expression filters covering 8 path patterns — and Cloudflare still refused to cache HTML. The fix wasn't another tweak to Cache Rules; it was switching to the older Page Rules with Cache Everything + Edge Cache TTL . Within 10 seconds of saving, our second-request TTFB dropped from 660ms to 210ms (a 68% reduction on keep-alive connections, much larger globally) and age: headers started incrementing. This post is the actual headers we saw, the configs we tried, and why the docs don't tell you this directly. The setup DooDoo.Love is a multilingual HTML5 games portal. ~6,800 game pages, plus categories, tags, blog, news.…