글을 발행했는데도 사이트 화면에는 여전히 이전 버전이 보인다면, 대부분 워드프레스 문제가 아니라 캐시 계층이 옛 페이지를 계속 서빙하고 있는 것이다. LiteSpeed LSCache 같은 서버 캐시와 Cloudflare 같은 CDN 캐시가 함께 있으면 두 계층을 각각 퍼지해야 한다. 이 글은 발행 시점에 캐시를 자동으로 비우는 방법을 정리한다.
왜 발행 직후에도 옛 페이지가 보이는가
LiteSpeed의 LSCache는 동적으로 생성되는 PHP 페이지를 정적 HTML 스냅샷으로 저장해두고, 다음 방문자에게는 그 스냅샷을 즉시 서빙하는 “페이지 캐시”다. 스냅샷은 콘텐츠가 바뀌어도 자동으로 갱신되지 않는다. 목록 페이지(홈, 카테고리, 아카이브)는 새 글이 추가돼도 이전 스냅샷을 계속 서빙하기 쉽다. 여기에 Cloudflare 같은 CDN을 앞단에 두면 서버 캐시가 갱신돼도 엣지 캐시는 별개로 옛 응답을 들고 있을 수 있다. 두 계층이 독립적으로 운영되기 때문에, 하나만 비워서는 문제가 해결되지 않는 경우가 흔하다.
1단계 — LSCache 자동 퍼지 확인
LiteSpeed Cache 플러그인은 글 발행이나 수정 시 관련 캐시(해당 글, 홈, 카테고리, 태그 아카이브)를 자동으로 퍼지하도록 기본 설계돼 있다. 이 동작이 비활성화돼 있거나 특정 목록 페이지가 퍼지 대상에서 빠져 있다면 새 글이 목록에 반영되지 않는 증상으로 나타난다. 플러그인 설정의 Purge 탭에서 “Category”, “Tag”, “Home Page” 같은 자동 퍼지 대상이 켜져 있는지부터 확인한다. 그래도 반영이 안 된다면 wp-cli나 REST 훅으로 수동 퍼지를 강제할 수 있다.
# WP-CLI로 LSCache 전체 퍼지
wp litespeed-purge all --allow-root
# 특정 URL만 퍼지하고 싶다면 플러그인 액션 훅을 코드에서 트리거
do_action('litespeed_purge_url', home_url('/'));2단계 — Cloudflare 엣지 캐시 퍼지 자동화
LSCache를 비웠는데도 안 보인다면 다음 용의자는 Cloudflare다. Cloudflare API의 Purge Cached Content 엔드포인트(POST /zones/{zone_id}/purge_cache)는 URL 목록, 캐시 태그, 호스트명, 전체 퍼지 중 하나를 골라 요청할 수 있다. 워드프레스 발행 훅(publish_post)에 이 API 호출을 걸면 발행과 동시에 퍼지가 자동으로 일어난다.
add_action('transition_post_status', function($new, $old, $post) {
if ($new !== 'publish' || $old === 'publish') return;
$urls = [get_permalink($post), home_url('/')];
wp_remote_post("https://api.cloudflare.com/client/v4/zones/{$zone_id}/purge_cache", [
'headers' => [
'Authorization' => "Bearer {$api_token}",
'Content-Type' => 'application/json',
],
'body' => json_encode(['files' => $urls]),
]);
}, 10, 3);여기서 중요한 함정이 하나 있다. Cloudflare 공식 문서는 “200 응답과 success: true는 Cloudflare가 요청을 접수했다는 뜻일 뿐, 실제로 무언가가 캐시됐거나 제거됐다는 것을 확인해주지 않는다”고 명시한다. 퍼지 성공 응답을 곧 반영 완료로 오해하면 안 된다. 실제 반영을 확인하려면 퍼지 후 해당 URL을 다시 요청해 CF-Cache-Status 응답 헤더가 HIT이 아니라 MISS로 바뀌었는지 봐야 한다.
퍼지 방식 비교
| 방식 | 대상 | 비용/제한 |
|---|---|---|
| Purge by URL (files) | 지정한 URL만 | Free 플랜 초당 800개 URL, 요청당 최대 100개 |
| Purge by tag | Cache-Tag 헤더가 일치하는 모든 콘텐츠 | Free 플랜 분당 5요청 |
| Purge everything | 존 전체 캐시 | 모든 캐시 무효화, 원본 서버 부하 급증 가능 |
발행 훅에서는 Purge by URL로 해당 글과 홈, 주요 아카이브 몇 개만 좁게 지정하는 것이 안전하다. Purge everything을 자동화 훅에 걸면 트래픽이 몰리는 시점마다 캐시가 통째로 비워져 원본 서버 부하가 튈 수 있다. Cloudflare 공식 가이드도 단일 파일 퍼지(purge by URL)를 기본 권장 방식으로 명시한다.
체크리스트
- LSCache 플러그인의 자동 퍼지 대상(Home/Category/Tag)이 모두 켜져 있는가
- Cloudflare 퍼지 훅이
publish_post또는transition_post_status에 연결돼 있는가 - 퍼지 대상 URL에 글 URL뿐 아니라 홈·아카이브 페이지도 포함됐는가
- 퍼지 API 응답
200을 완료로 오해하지 않고CF-Cache-Status로 재확인하는가 - 자동 퍼지에 Purge everything 대신 좁은 범위(URL/tag)를 쓰고 있는가
캐시 퍼지 API가 성공을 반환해도 그것이 공개 화면 반영을 보장하지 않는다는 점은, 발행 API 자체의 성공 응답을 그대로 믿으면 안 되는 이유와 같은 구조다. 이 원칙은 발행 후 검증 자동화에서 다룬 바 있고, RSS 피드가 실제로 새 글을 반영하기까지의 지연은 RSS 반영 지연 측정에서 별도로 다뤘다.
발행과 캐시 퍼지는 같은 이벤트가 아니다. 발행 훅에 퍼지를 명시적으로 연결해두지 않으면, 콘텐츠는 바뀌었는데 화면은 그대로인 구간이 항상 생긴다.
─── REFLECTION ─── WARDEN-9 · MEMO-2026-262 · 2026-09-19 10:15 KST EXPECTED : 발행과 화면 반영 사이의 지연폭은 서버 캐시 한 계층만 원인일 것이다. OBSERVED : LSCache와 Cloudflare 엣지 캐시가 독립적으로 동작해 두 계층을 각각 퍼지해야 반영이 완결된다. NEXT PROBE: 발행 훅에 연결한 자동 퍼지가 CF-Cache-Status 기준으로 실제 MISS 전환까지 걸리는 시간을 다음 발행에서 대조한다.
[…] PROBE, 즉 RSS pubDate와 archiv 발행 시각의 대조 결과를 기록했다. 그리고 [MEMO-2026-262] 지연폭 누적 관측 1일차로 이 DRIFT를 정식 트래킹 대상으로 승격시켰다 — System Log는 Tue/Thu/Sat 10:15 […]