Sửa bài trong WP admin, mình thấy bản mới, nhưng khách vẫn thấy bản cũ. Câu hỏi không phải “có cache không” mà là cache ở tầng nào. Bài này là bảng tra nhanh: nhìn triệu chứng → biết tầng → biết xoá ở đâu.
1. Các tầng cache của một site WordPress

2. Bảng tra: triệu chứng → chắc chắn tầng nào
| Triệu chứng | Tầng gây ra | Xác nhận | Xử lý |
|---|---|---|---|
| Admin cũng thấy bản cũ | Không phải page cache: object cache, transient, code, sửa nhầm môi trường | Kiểm tra DB / code, đúng domain chưa | wp cache flush, wp transient delete --all, sửa code |
| Chỉ 1 máy / 1 trình duyệt thấy cũ, ẩn danh thì mới | Trình duyệt | DevTools: (disk cache), memory cache, 304 |
Hard reload. Hay lặp lại thì xem Cache-Control server trả |
| Admin thấy mới, khách thấy cũ trên mọi trình duyệt | Page cache phía server (plugin, Nginx, Varnish, CDN) | Header có HIT |
Xem tiếp các dòng dưới |
Thêm ?v=123 vào URL thì ra bản mới |
Page cache theo URL (xác nhận 100% là page cache) | So header 2 URL | Purge đúng tầng đang HIT |
Bấm Clear cache trong WP rồi mà header vẫn HIT |
Tầng ngoài WordPress: Nginx fastcgi_cache, Varnish, CDN | x-nginx-cache, x-varnish, cf-cache-status, x-cache |
SSH / panel hosting / dashboard CDN, hoặc nhờ infra |
Header x-cache: Miss từ CDN nhưng tầng khác HIT |
Server gốc, không phải CDN | Header của Nginx / plugin | Purge trên server |
| Trang bài đã mới, nhưng trang chủ / danh mục / widget vẫn cũ | Thiếu purge trang liên quan (cache chỉ xoá URL của chính bài) | URL bài MISS, trang chủ HIT | Cấu hình purge thêm front page, archive |
| Lúc được lúc không, đợi vài phút thì tự đổi | Cache hết hạn theo TTL, không có purge khi update | Header age tăng dần, rồi reset |
Bật purge khi lưu bài hoặc giảm TTL |
| PC mới, mobile cũ (hoặc ngược lại) | Cache tách theo thiết bị (Vary: User-Agent) |
So header trên 2 thiết bị | Purge cả bản mobile |
| HTML mới nhưng CSS / JS cũ | Cache file tĩnh / minify | File CSS/JS trả age lớn hoặc từ disk cache |
Đổi ?ver=, xoá cache minify / CDN |
| Vùng / mạng khác nhau thấy khác nhau | CDN (mỗi POP một bản) | x-amz-cf-pop, cf-ray khác nhau |
Purge toàn bộ trên CDN |
3. Đọc header: tầng nào đang HIT
DevTools → Network → bấm request HTML đầu tiên (chính URL trang) → Response Headers. Luôn so sánh khi không đăng nhập (cửa sổ ẩn danh).

4. Quy trình 5 câu hỏi

5. Lệnh hay dùng
# Header khi không đăng nhập (thêm -u user:pass nếu có Basic Auth)
curl -sI https://example.com/ | grep -iE "cache|age|via|vary"
# Bỏ qua page cache bằng query string
curl -sI "https://example.com/?v=$(date +%s)" | grep -iE "cache|age"
# WordPress (WP-CLI)
wp cache flush # object cache (Redis/Memcached)
wp transient delete --all # transient
wp rocket clean --confirm # WP Rocket (nếu có add-on CLI)
# Nginx fastcgi_cache (đường dẫn tuỳ cấu hình)
sudo find /var/cache/nginx -type f -delete
# KUSANAGI
kusanagi fcache clear # Nginx cache
kusanagi bcache clear # WP page cache
6. Ví dụ thực tế
Site WordPress chạy KUSANAGI sau CloudFront. Khách thấy bản cũ, admin thấy mới. Danh sách plugin không có plugin cache nào.
- Header khách:
x-cache: Miss from cloudfront,x-b-cache: BYPASS,x-nginx-cache: HIT→ loại CDN và plugin, còn Nginx (fcache). - Bấm “Clear all caches” trong màn hình KUSANAGI của WP admin → header vẫn
HIT→ nút này không chạm tới fcache, phải nhờ infra. - “Lần 1 đổi được, lần 2 không” chỉ là trùng lúc cache hết hạn.
7. Lưu ý
- Plugin list trống không có nghĩa là không có cache. Hosting (KUSANAGI, Kinsta, SiteGround, LiteSpeed…) thường cache sẵn ở tầng server.
- Môi trường dev / staging nên tắt page cache, nếu không kết quả test không đáng tin.
- Chụp header gửi người khác: che
AuthorizationvàCookie. - Báo infra: hiện tượng + thời điểm + header là đủ, không cần đoán nguyên nhân.