WP-Cron(wp-cron.php): 비활성화 및 시스템 크론 설정 | 워드프레스 성능 최적화

워드프레스에서 Cron 작업은 특정 시간이나 날짜에 예약된 작업을 자동으로 수행하는 기능입니다. 이 작업은 wp-cron.php 파일을 통해 실행되며, 워드프레스는 페이지가 로드될 때마다 이 파일을 호출하여 예약된 작업을 처리합니다. 이러한 방식은 간편하지만, 트래픽이 많은 사이트에서는 성능 저하를 유발할 수 있습니다.
Ⅰ. WP-Cron의 실행 과정과 성능 문제
워드프레스는 리눅스 서버의 전통적인 Cron 시스템을 사용하지 않고 자체적인 Cron 기능인 WP-Cron을 제공합니다. WP-Cron은 wp-cron.php 파일을 통해 작동하며, ⓐ 사용자가 사이트를 방문할 때마다 예약된 작업이 있는지 확인하고 이를 실행하며, ⓑ Rank Math와 WP Rocket과 같은 플러그인 등은 자체적으로 예약된 주기적인 작업을 실행합니다.
반대로, 트래픽이 많은 사이트에서는 wp-cron.php가 지나치게 자주 호출되어 서버에 과부하를 줄 수 있습니다. 특히, 동시에 여러 사용자가 접속할 경우 중복된 크론 작업이 실행되며, 이는 CPU 사용률 증가, 응답 지연, 페이지 로딩 속도 저하 등의 문제로 이어질 수 있습니다.
이러한 WP-Cron의 구조적 한계는 워드프레스의 성능을 저하시킬 수 있으며, 특히 고성능이 요구되는 사이트나 쇼핑몰, 뉴스 포털 등에서는 치명적인 병목 현상을 유발할 수 있습니다.
🔄 WP-Cron의 실행 방식 및 구조
Ⅱ. 워드프레스 성능 최적화
워드프레스 성능 최적화 방식에는 여러 가지가 있습니다. 캐싱 및 프론트엔드와 데이터베이스 등의 최적화 후 WP-Cron의 설정을 통한 개선 방법이 있습니다.
워드프레스 페이지가 로드될 때마다 예약된 이벤트가 확인되며, 플러그인의 주기적인 작업으로 비효율적인 WP-Cron을 효율적으로 활용할 필요가 있습니다.
1️⃣ WP-Cron 테스트
WP-CLI로 크론 작업을 확인했을 때 작동 중인 Cron이 실행되는 것을 확인할 수 있습니다. Rank Math 및 WP Rocket 등의 플러그인이 예약된 작업을 하루 또는 분 단위로 실행되는 것이 확인됩니다.

2️⃣ WP-Cron 설정 방법
WP-Cron은 워드프레스의 예약 작업을 처리하는 가상 스케줄러로, 사용자의 방문 시 wp-cron.php가 실행됩니다. 하지만 트래픽 기반 실행은 불안정하고 과도한 호출로 서버 부하를 유발할 수 있어, 시스템 크론으로 보완하는 것이 일반적입니다.
필요 시 wp-config.php에서 DISABLE_WP_CRON을 설정해 WP-Cron을 끄고, 리눅스 크론으로 정기 실행하는 방식이 추천됩니다.
|
항목 |
WP-Cron 비활성화 + 시스템 크론 단독 실행 |
|---|---|
|
설정 |
WP-Cron을 끄고 시스템 크론에서 wp-cron.php를 실행 |
|
장점 |
중복 실행이 없고 정확한 시간 기반 실행이 가능하며, 서버 부하가 적음 |
|
단점 |
일부 플러그인 기능이 중단될 수 있고 설정 실수 시 작업 누락 위험 |
|
추천 상황 |
트래픽이 많고 예약 작업이 많은 사이트에 적합 |
하지만 ①번 방식은 WP Rocket과 같은 캐시 플러그인이 1분마다 PreLoad 기능으로 방문자가 웹페이지에 방문하기 전에 캐시를 미리 생성하는 기능이 비활성화되는 단점이 있습니다.
⚙️ wp-config.php 파일 수정
WP_CRON을 비활성화하는 방법으로 설정할 수 있습니다.
# WP_CRON 비활성화
define( 'DISABLE_WP_CRON', true );WP_CRON_LOCK_TIMEOUT은 WP-Cron이 실행 중일 때 다른 실행 시도를 막아 주는 [시간 기반 잠금 장치]입니다.
# 5분은 300으로, 60분마다 실행 3600
define('WP_CRON_LOCK_TIMEOUT', 300);이와 같은 이유로 wp-config.php 파일에서 WP-Cron만 비활성화하는 방법보다는, 비활성화한 뒤 System Cron 작업을 추가하는 방법을 권장하며, 현재 관리 중인 서버에도 이 방법으로 설정했습니다.
⚙️ 리눅스 서버에 시스템 크론 활성화[기본]
개별 도메인으로 활성화할 수 있습니다.
# 5분마다 실행
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# 30분마다 실행
*/30 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# 1시간마다 실행
0 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# 하루 1번 실행
0 3 * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1위 네 줄은 crontab에 등록하는 주기별 예시이며, 지정한 시각마다 curl이 [wp-cron.php] 주소를 호출하여 방문자가 없어도 예약 작업이 실행됩니다.
# 서버가 로컬 서버일 경우
*/5 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# 30분마다 실행
*/30 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# 1시간마다 실행
0 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# 하루 1번 실행
0 3 * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1WP-CLI를 설치했을 경우 원하는 시간대로 하나만 설정할 수 있습니다. ▼
# 5분마다 실행
*/5 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# 30분마다 실행
*/30 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# 1시간마다 실행
0 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# 하루 1번 실행
0 3 * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet서버 안에서 WP-CLI가 [--due-now] 옵션으로 기한이 된 예약 작업만 실행하는 설정이며, [flock -n]은 앞선 실행이 끝나지 않았으면 새 실행을 건너뜁니다.
⚙️ WP-CLI 및 시스템 크론 1분 및 크론 작업 중복 방지
기존의 WP_CRON은 작업량이 많으면 그냥 무시(건너뜀)되고 이후에 재실행되는 구조입니다. 기존의 WP-Cron을 끄고 예약 작업을 5분 잠금 유지로 설정하여 시스템 크론과 WP-Cron이 겹쳐 실행되는 것을 막습니다.
define('DISABLE_WP_CRON', true); // WP-Cron 자동 실행 끔
define('WP_CRON_LOCK_TIMEOUT', 300); // 대기 안 함 → 무시(건너뜀) 예약 작업 실행 시 5분 잠금 유지
/* That's all, stop editing! Happy publishing. */시스템 크론 flock -n 옵션을 추가로 설정하여, 시스템 크론에선 즉시 종료로 적용합니다.
# wp cron 설정 : flock -n → 대기 안 함 → 즉시 종료
*/1 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet위와 같이 설정한 조합의 결과는
- WP 내부 자동 실행은 꺼짐 → 방문자 수와 무관하게 예약 작업 실행
- 시스템 크론이 1분마다 실행 시도 → 예약된 작업이 있으면 실행됨
- 잠금이 걸리면 5분 동안 재실행 안 됨 → 중복 실행 방지(사실상 WP_CRON_LOCK_TIMEOUT은 flock -n 설정으로 굳이 필요하지 않습니다.)
중복 실행 방지로 실제 동작 흐름은
- 08:00 → 시스템 크론이 wp-cron.php 호출
- 예약 작업 A 실행됨 → 잠금 5분 설정
- 08:01 → 시스템 크론 다시 호출
- 작업 A는 잠금 중 → 실행 안 됨
- 08:02~08:04 → 동일
- 08:05 → 잠금 풀림 → 다음 예약 작업이 있으면 실행됨
WP가 자동으로 실행하지 않는 대신, 시스템이 책임지고 실행한다는 점. 그리고 WP_CRON_LOCK_TIMEOUT은 중복 실행을 막는 보조 안전장치로 작동한다는 것입니다.
|
항목 |
WP_CRON_LOCK_TIMEOUT |
flock -n |
|---|---|---|
|
잠금 방식 |
워드프레스 내부 |
시스템 레벨 |
|
잠금 위치 |
DB 기반 wp_options의 doing_cron |
시스템 파일 기반 ~/.wp_cron.lock |
|
대기 여부 |
❌ 대기 안 함 → 건너뜀 |
❌ 대기 안 함 → 즉시 종료 |
|
중복 실행 방지 |
✅ 중복 실행 방지 |
✅ 중복 실행 방지 |
작업 완료 후 WP-CLI 명령어로 확인해 볼 수 있습니다. 기존처럼 크론이 잘 작동하는지 확인합니다.
wp cron event list+-------------------------------------------+---------------------+-----------------------+---------------+
| hook | next_run_gmt | next_run_relative | recurrence |
+-------------------------------------------+---------------------+-----------------------+---------------+
| rocket_saas_pending_jobs | 2026-10-17 12:00:57 | now | 1 minute |
| action_scheduler_run_queue | 2026-10-17 12:00:57 | now | 1 minute |
| action_scheduler_run_queue_rucss | 2026-10-17 12:00:58 | now | 1 minute |
| rocket_saas_on_submit_jobs | 2026-10-17 12:00:58 | now | 1 minute |
| rocket_preload_process_pending | 2026-10-17 12:00:59 | now | 1 minute |
| rocket_purge_time_event | 2026-10-17 12:16:59 | 15 minutes 8 seconds | 1 hour |
| wp_privacy_delete_old_export_files | 2026-10-17 12:28:46 | 26 minutes 55 seconds | 1 hour |
| wp_update_user_counts | 2026-10-17 20:15:52 | 8 hours 14 minutes | 12 hours |
| rocket_preload_revert_old_failed_rows | 2026-10-17 20:17:59 | 8 hours 16 minutes | 12 hours |
| wp_version_check | 2026-10-17 20:28:34 | 8 hours 26 minutes | 12 hours |
| wp_update_plugins | 2026-10-17 20:58:34 | 8 hours 56 minutes | 12 hours |
| wp_update_themes | 2026-10-17 21:28:34 | 9 hours 26 minutes | 12 hours |
| recovery_mode_clean_expired_keys | 2026-10-18 07:28:46 | 19 hours 26 minutes | 1 day |
| wp_privacy_personal_data_cleanup_requests | 2026-10-18 07:28:46 | 19 hours 26 minutes | 1 day |
| wp_scheduled_delete | 2026-10-18 08:15:52 | 20 hours 14 minutes | 1 day |
| delete_expired_transients | 2026-10-18 08:15:52 | 20 hours 14 minutes | 1 day |
| wp_scheduled_auto_draft_delete | 2026-10-18 08:15:54 | 20 hours 14 minutes | 1 day |
| wp_delete_temp_updater_backups | 2026-10-18 08:16:17 | 20 hours 14 minutes | 1 week |
| rocket_update_dynamic_lists | 2026-10-18 08:16:57 | 20 hours 15 minutes | 1 week |
| rocket_saas_clean_rows_time_event | 2026-10-18 08:16:57 | 20 hours 15 minutes | 1 week |
| rocket_performance_hints_cleanup | 2026-10-18 08:16:58 | 20 hours 15 minutes | 1 day |
| rocket_preload_clean_rows_time_event | 2026-10-18 08:26:57 | 20 hours 25 minutes | 1 week |
| rocket_database_optimization_time_event | 2026-10-18 09:34:25 | 21 hours 32 minutes | 1 day |
| wp_site_health_scheduled_check | 2026-10-19 07:28:46 | 1 day 19 hours | 1 week |
| rocket_remove_saas_failed_jobs | 2026-10-19 08:16:58 | 1 day 20 hours | 3 days |
+-------------------------------------------+---------------------+-----------------------+---------------+출력에는 등록된 훅 이름과 다음 실행 시각, 반복 주기가 표시되며, [next_run_relative] 열이 [now]인 작업은 다음 크론 실행 때 바로 처리됩니다.
Ⅲ. WP-Cron 예약 작업이 실행되지 않을 때
예약 시각이 되면 작업이 저절로 실행된다고 여기기 쉽지만, WP-Cron은 시각이 아니라 페이지 요청이 들어올 때 할 일을 확인합니다. 오후 2시로 예약한 작업도 오후 5시까지 요청이 없으면 5시의 첫 요청에서 실행됩니다.
실행이 밀리면 예약 발행 글은 글 목록에서 [예약을 놓쳤습니다](Missed schedule)로 표시됩니다. [도구 › 사이트 건강] 상태 탭의 [권장 개선사항]에는 [예정된 이벤트가 실패했습니다]가 나타납니다. 캐시 사전 로드처럼 플러그인이 등록한 작업도 같은 이유로 실행을 기다립니다.
예약 작업은 페이지 요청과 할 일 확인, 루프백 요청을 거쳐 [wp-cron.php]에서 실행되며, 이 가운데 한 곳이 끊기면 시각이 지나도 실행되지 않습니다.
1️⃣ 방문이 없거나 페이지 캐시가 응답할 때
WP-Cron은 워드프레스가 실행되는 요청에서만 할 일을 확인하므로, 방문이 없는 시간에는 시각이 지난 작업이 그대로 쌓입니다. 방문이 있어도 페이지 캐시 파일로 응답하면 워드프레스가 실행되지 않아 결과는 같습니다.
WP Rocket 페이지 캐시가 켜진 워드프레스에서 캐시된 첫 화면을 열었을 때는 [wp-cron.php] 호출이 기록되지 않았습니다. 캐시되지 않는 주소를 열자 같은 초에 호출이 기록되었고, 밀려 있던 작업 다섯 개가 실행되었습니다.
밀린 작업은 WP-CLI 목록에서 [next_run_relative]가 [now]인 줄만 걸러 확인할 수 있습니다.
wp cron event list --next_run_relative=now --fields=hook,next_run_gmt,next_run_relative+----------------------------------+---------------------+-------------------+
| hook | next_run_gmt | next_run_relative |
+----------------------------------+---------------------+-------------------+
| rocket_saas_pending_jobs | 2026-10-17 14:49:57 | now |
| action_scheduler_run_queue | 2026-10-17 14:49:57 | now |
| action_scheduler_run_queue_rucss | 2026-10-17 14:49:58 | now |
| rocket_saas_on_submit_jobs | 2026-10-17 14:49:58 | now |
| rocket_preload_process_pending | 2026-10-17 14:49:59 | now |
+----------------------------------+---------------------+-------------------+[now]는 예정 시각이 이미 지난 작업이며, 이 목록 명령도 워드프레스를 불러오므로 밀린 작업이 있으면 끝나는 순간 [wp-cron.php]를 호출합니다. 같은 명령을 바로 다시 실행하면 방금 보였던 작업은 목록에서 사라져 있습니다.
원인을 고치기 전에 밀린 작업부터 처리하려면 WP-CLI로 기한이 지난 작업만 바로 실행합니다.
wp cron event run --due-nowExecuted the cron event 'rocket_saas_pending_jobs' in 0.005s.
Executed the cron event 'action_scheduler_run_queue' in 0.006s.
Executed the cron event 'action_scheduler_run_queue_rucss' in 0.006s.
Executed the cron event 'rocket_saas_on_submit_jobs' in 0.005s.
Executed the cron event 'rocket_preload_process_pending' in 0.007s.
Success: Executed a total of 5 cron events.이 명령은 HTTP 요청 없이 서버 안에서 작업을 실행하며, 방문과 상관없이 정해진 간격으로 처리하려면 같은 명령을 시스템 크론에 등록합니다.
2️⃣ DISABLE_WP_CRON만 켜고 시스템 크론이 없을 때
[DISABLE_WP_CRON]을 true로 두면 페이지 요청이 와도 WP-Cron이 할 일을 확인하지 않습니다. 공식 문서도 시스템 작업 스케줄러에 먼저 등록한 뒤 이 상수를 넣는 순서로 안내하며, 등록 없이 상수만 넣으면 예약 작업을 실행하는 곳이 사라집니다.
상수를 넣은 상태에서 1분 남짓 뒤로 예약한 글은 시각이 지나도 [예약됨]으로 남았고, 글 목록 날짜 칸에는 [예약을 놓쳤습니다]가 표시되었습니다. 그동안 [wp-cron.php] 호출은 한 번도 기록되지 않았습니다.
상수가 켜져 있는지는 [wp cron test]로 확인할 수 있습니다.
wp cron testError: The DISABLE_WP_CRON constant is set to true. WP-Cron spawning is disabled.이 오류가 나오면 시스템 크론에 [wp-cron.php]를 부르거나 [wp cron event run]을 실행하는 줄이 있는지 확인합니다. 사이트 계정의 crontab이 비어 있으면 아래처럼 표시됩니다.
crontab -lno crontab for example줄이 없으면 시스템 크론을 등록하고, 등록할 수 없는 환경이면 [DISABLE_WP_CRON] 줄을 지워 WP-Cron을 다시 사용합니다.
3️⃣ 서버의 루프백 요청이 막혔을 때
WP-Cron은 할 일이 있으면 서버가 자기 사이트 주소의 [wp-cron.php]로 요청을 보내 작업을 실행하며, 이 요청이 루프백 요청입니다. [wp-cron.php]를 막는 보안 규칙이 있으면 루프백 요청이 403으로 돌아오고 작업은 실행되지 않습니다.
Nginx와 Apache 구성 서버에서 [wp-cron.php]를 127.0.0.1에서만 열리게 막자, 루프백 요청이 403으로 막혔습니다. 서버가 자기 도메인으로 보낸 요청이 공인 IP로 들어오기 때문이며, [wp cron test]도 같은 상태 코드를 반환합니다.
wp cron testError: WP-Cron spawn returned HTTP status code: 403 Forbidden작업이 5분 넘게 밀린 상태에서 [사이트 건강] 화면을 열자, [권장 개선사항]에 루프백 경고와 예정된 이벤트 실패가 함께 표시되었습니다.

규칙을 지우자 [wp cron test]는 다시 성공했습니다. 규칙을 유지해야 한다면 시스템 크론에서 WP-CLI로 실행합니다. WP-CLI 실행은 HTTP 요청을 거치지 않아, 같은 규칙이 있는 상태에서도 밀린 작업이 처리되었습니다.
🔢 FAQ & 추천 콘텐츠



ℹ️ 제휴 안내
본 사이트의 콘텐츠에는 제휴 링크가 포함되어 있습니다. 방문자가 이 링크를 통해 상품 또는 서비스를 구매하면 본 사이트는 판매처로부터 수수료를 지급받습니다. 이 과정에서 구매자가 지불하는 금액(이벤트 할인 시 금액이 내려갑니다↓)은 오르지 않습니다. 게시된 가격·할인·재고 정보는 작성 시점 기준이며 실제와 다를 수 있으므로, 구매 전 판매처에서 최종 확인하시기 바랍니다. 상품 선정과 평가는 자체 기준에 따라 작성되며, 수수료 지급 여부가 소개 순서나 평가 내용에 영향을 주지 않습니다.

