Cloudflare Cache Rules: tăng cache hit rate từ 30% lên 90%, giảm tải server 10 lần

Mặc định Cloudflare chỉ cache static file (image, CSS, JS). HTML và API response không được cache - đây là lý do nhiều site có cache hit rate chỉ 30%. Cache Rules cho phép bạn kiểm soát chính xác cái gì được cache, bao lâu, và bypass khi nào. Cấu hình đúng, TTFB có thể giảm từ 500ms xuống còn 100ms và server load giảm 90%. ---

Vấn đề

Bạn đã bật Cloudflare proxy, nghĩ rằng CDN đang hoạt động, nhưng vào Analytics → Cache thấy Cache Hit Ratio chỉ 25–35%. Nguyên nhân phổ biến:

  1. HTML không được cache - Cloudflare mặc định không cache text/html vì sợ serve stale content cho dynamic pages
  2. Cache-Control header từ server quá ngắn hoặc no-cache, no-store
  3. Query string làm cache miss - ?v=1, ?utm_source=facebook tạo ra cache key khác nhau
  4. Cookie làm bypass cache - nếu request có cookie, Cloudflare mặc định không cache

Cache Rules (thay thế Page Rules cũ) giải quyết tất cả các vấn đề này.


Hiểu cache flow của Cloudflare

Request → Cloudflare Edge
         → Cache hit? → Serve từ cache (TTFB ~10ms)
         → Cache miss → Forward đến origin
                      → Cache response theo rules
                      → Serve user

Hai loại TTL quan trọng:

  • Edge Cache TTL - bao lâu Cloudflare giữ bản cache ở edge (data center gần user)
  • Browser Cache TTL - bao lâu browser của user giữ bản cache local

Cloudflare tôn trọng Cache-Control header từ origin, nhưng Cache Rules cho phép bạn override lên từ Cloudflare edge mà không cần sửa code server.


Rule 1: Cache aggressively cho static assets

Static file (image, CSS, JS, font) là thứ nên cache lâu nhất - chúng hiếm khi thay đổi.

Vào Caching → Cache Rules → Create Rule.

Rule name: Cache static assets aggressively

When: 
  URI path extension is in: jpg, jpeg, png, gif, webp, svg, ico,
                             css, js, woff, woff2, ttf, eot,
                             pdf, zip

Then:
  Cache eligibility: Eligible for cache
  Edge Cache TTL: 1 month
  Browser Cache TTL: 1 day

Tại sao Browser TTL ngắn hơn Edge TTL? Edge cache được purge khi bạn deploy. Browser cache thì không - nếu TTL quá dài, user sẽ thấy file cũ dù đã purge ở edge.

Thêm query string normalization để tránh style.css?v=1style.css?v=2 tạo ra 2 cache entry:

Vào Caching → Cache Rules → [rule] → Cache Key → Query String → Ignore all nếu file static không cần query string.


Rule 2: Cache HTML với TTL ngắn cho trang ít thay đổi

Trang landing, about, blog post (đã publish) - thay đổi ít, có thể cache HTML ở edge.

Rule name: Cache HTML - static pages

When:
  URI path matches regex: ^/(|about|contact|pricing|blog/[^?]+)$
  AND NOT (http.request.uri.query contains "preview")

Then:
  Cache eligibility: Eligible for cache
  Edge Cache TTL: 4 hours
  Browser Cache TTL: 30 minutes
  Respect origin Cache-Control: Override

Khi publish bài mới hoặc cập nhật page: Purge cache manually hoặc dùng Cloudflare API để purge theo URL.


Rule 3: Bypass cache cho authenticated requests

Trang admin, dashboard, checkout - không được cache vì mỗi user thấy data khác nhau.

Rule name: Bypass cache for authenticated users

When:
  Cookie name: session_token (exists)
  OR Cookie name: auth_token (exists)
  OR URI path starts with: /admin
  OR URI path starts with: /dashboard
  OR URI path starts with: /checkout
  OR URI path starts with: /api/user

Then:
  Cache eligibility: Bypass cache

Đây là rule quan trọng nhất để tránh serve nhầm dữ liệu của user A cho user B.


Rule 4: Cache API response công khai

API endpoint trả về dữ liệu không thay đổi theo user (public catalog, danh sách bài viết, config) hoàn toàn có thể cache.

Rule name: Cache public API responses

When:
  URI path starts with: /api/products
  OR URI path starts with: /api/articles
  OR URI path starts with: /api/config
  AND http.request.method eq "GET"
  AND NOT (Cookie: session_token exists)

Then:
  Cache eligibility: Eligible for cache
  Edge Cache TTL: 30 minutes
  Browser Cache TTL: 5 minutes
  Respect Vary header: Off

Kết hợp với Cloudflare Workers để set Cache-Control header đúng ở origin - Cloudflare sẽ tôn trọng header đó.


Cache Purge: quan trọng như cache rule

Cache lâu mà không có chiến lược purge là con dao hai lưỡi. Cloudflare hỗ trợ:

1. Purge theo URL (chính xác nhất):

curl -X POST "https://api.cloudflare.com/client/v4/zones/<ZONE_ID>/purge_cache" \
  -H "Authorization: Bearer <API_TOKEN>" \
  -H "Content-Type: application/json" \
  --data '{"files":["https://example.com/blog/post-123","https://example.com/api/articles"]}'

2. Purge toàn bộ cache (khi deploy lớn):

Vào Caching → Configuration → Purge Everything - hoặc via API với {"purge_everything": true}.

3. Cache Tag (Enterprise): Tag response với Cache-Tag: blog-posts header, purge theo tag khi có update.

Tích hợp purge vào deploy pipeline:

# Trong script deploy (GitHub Actions, etc.)
echo "Purging Cloudflare cache..."
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"purge_everything":true}' | jq '.success'

Đọc cache status trên response

Kiểm tra xem response được serve từ cache hay origin:

curl -I https://example.com/style.css | grep -i "cf-cache-status"
CF-Cache-Status Ý nghĩa
HIT Served từ Cloudflare cache - origin không bị hit
MISS Cache miss, lấy từ origin và đã cache lại
EXPIRED Cache đã hết TTL, fetch lại từ origin
BYPASS Rule bypass hoặc cookie khiến không cache
DYNAMIC Cloudflare không cache (default với HTML)
REVALIDATED Cache còn hạn, origin confirm vẫn valid

Mục tiêu: tỉ lệ HIT càng cao càng tốt. Xem trong Analytics → Cache → Cache Hit Ratio.


Kết quả thực tế sau khi optimize

Theo case study từ Cloudflare community:

Metric Trước Sau
Cache Hit Ratio 30% 90%+
TTFB (trung bình) ~500ms ~100ms
Origin server requests 100% 10%
Server CPU load High Low
Bandwidth từ origin Full -70%

Best practices tóm tắt

  1. Static assets: cache 1 tháng ở edge, dùng content hash trong filename (app.a1b2c3.js) để bust cache khi deploy
  2. HTML tĩnh: cache 2–4 giờ, purge khi publish content mới
  3. API public: cache 5–30 phút tùy freshness requirement
  4. Authenticated: không bao giờ cache - bypass ngay
  5. Purge sau deploy: tích hợp vào CI/CD pipeline

Tham khảo


BKGlobal Tech Team

Blog Công nghệ

Xem tất cả