WP-Cron (wp-cron.php): tắt và thiết lập cron hệ thống | tối ưu hiệu suất WordPress

Trong WordPress, tác vụ Cron là tính năng tự động thực hiện các tác vụ đã lên lịch vào một thời điểm hoặc ngày cụ thể. Các tác vụ này chạy qua file wp-cron.php, và WordPress gọi file này mỗi khi trang được tải để xử lý các tác vụ đã lên lịch. Cách này đơn giản, nhưng trên website nhiều lưu lượng truy cập có thể làm giảm hiệu suất.
Ⅰ. Quá trình chạy của WP-Cron và vấn đề hiệu suất
Thay vì dùng hệ thống Cron truyền thống của server Linux, WordPress cung cấp tính năng Cron riêng là WP-Cron. WP-Cron hoạt động qua file wp-cron.php: ⓐ mỗi khi người dùng truy cập website, nó kiểm tra xem có tác vụ đã lên lịch không rồi chạy chúng, và ⓑ các plugin như Rank Math và WP Rocket tự chạy những tác vụ định kỳ mà chúng đã lên lịch.
Ngược lại, trên website nhiều lưu lượng truy cập, wp-cron.php có thể bị gọi quá thường xuyên và gây quá tải cho server. Đặc biệt, khi nhiều người dùng truy cập cùng lúc, các tác vụ cron trùng lặp sẽ chạy, và điều này có thể dẫn đến tăng mức sử dụng CPU, phản hồi chậm, tốc độ tải trang giảm và các vấn đề tương tự.
Những giới hạn mang tính cấu trúc này của WP-Cron có thể làm giảm hiệu suất WordPress, đặc biệt ở các website cần hiệu suất cao, cửa hàng trực tuyến hay cổng tin tức thì có thể gây ra tình trạng nghẽn cổ chai nghiêm trọng.
🔄 Cách WP-Cron chạy và cấu trúc của nó
Ⅱ. Tối ưu hiệu suất WordPress
Có nhiều cách tối ưu hiệu suất WordPress. Sau khi tối ưu cache, frontend, cơ sở dữ liệu và các phần khác, bạn có thể cải thiện thêm bằng cách thiết lập WP-Cron.
Mỗi khi trang WordPress được tải, các sự kiện đã lên lịch đều được kiểm tra, và vì các tác vụ định kỳ của plugin, cần sử dụng WP-Cron vốn kém hiệu quả này một cách hiệu quả hơn.
1️⃣ Kiểm tra WP-Cron
Khi kiểm tra các tác vụ cron bằng WP-CLI, có thể thấy các Cron đang hoạt động được chạy. Các plugin như Rank Math và WP Rocket chạy tác vụ đã lên lịch theo ngày hoặc theo phút.

2️⃣ Cách thiết lập WP-Cron
WP-Cron là bộ lập lịch ảo xử lý các tác vụ đã lên lịch của WordPress, wp-cron.php chạy khi người dùng truy cập. Nhưng cách chạy dựa trên lưu lượng truy cập không ổn định và việc gọi quá nhiều có thể gây tải cho server, nên thường được bổ sung bằng cron hệ thống.
Khi cần, cách được khuyến nghị là đặt DISABLE_WP_CRON trong wp-config.php để tắt WP-Cron, rồi chạy định kỳ bằng cron của Linux.
|
Hạng mục |
Tắt WP-Cron + chỉ chạy cron hệ thống |
|---|---|
|
Cài đặt |
Tắt WP-Cron và chạy wp-cron.php từ cron hệ thống |
|
Ưu điểm |
Không chạy trùng lặp, chạy đúng theo thời gian và ít tải cho server |
|
Nhược điểm |
Một số tính năng plugin có thể ngừng hoạt động, và cài đặt sai có nguy cơ bỏ sót tác vụ |
|
Khuyến nghị · Tình huống |
Phù hợp với website nhiều lưu lượng truy cập và nhiều tác vụ đã lên lịch |
Tuy nhiên, cách ① có nhược điểm là tính năng PreLoad của các plugin cache như WP Rocket, vốn tạo sẵn cache mỗi 1 phút trước khi khách truy cập vào trang, sẽ bị vô hiệu hóa.
⚙️ Sửa file wp-config.php
Bạn có thể thiết lập bằng cách tắt WP_CRON.
# Tắt WP_CRON
define( 'DISABLE_WP_CRON', true );Khi WP-Cron đang chạy, WP_CRON_LOCK_TIMEOUT đóng vai trò là [khóa theo thời gian] ngăn các lần chạy khác.
# 5 phút là 300, chạy mỗi 60 phút là 3600
define('WP_CRON_LOCK_TIMEOUT', 300);Vì những lý do này, thay vì chỉ tắt WP-Cron trong file wp-config.php, nên tắt nó rồi thêm tác vụ System Cron như cách đang áp dụng trên server được quản lý hiện tại.
⚙️ Bật cron hệ thống trên server Linux [cơ bản]
Có thể bật riêng cho từng domain.
# Chạy mỗi 5 phút
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# Chạy mỗi 30 phút
*/30 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# Chạy mỗi 1 giờ
0 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# Chạy mỗi ngày 1 lần
0 3 * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1Bốn dòng trên là ví dụ theo từng chu kỳ để đăng ký vào crontab; đến mỗi thời điểm đã định, curl gọi địa chỉ [wp-cron.php] nên tác vụ đã lên lịch vẫn chạy dù không có khách truy cập.
# Nếu server là server cục bộ
*/5 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# Chạy mỗi 30 phút
*/30 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# Chạy mỗi 1 giờ
0 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1
# Chạy mỗi ngày 1 lần
0 3 * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1Nếu đã cài WP-CLI, bạn chỉ cần thiết lập một dòng theo chu kỳ mong muốn. ▼
# Chạy mỗi 5 phút
*/5 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# Chạy mỗi 30 phút
*/30 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# Chạy mỗi 1 giờ
0 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet
# Chạy mỗi ngày 1 lần
0 3 * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quietĐây là thiết lập để WP-CLI bên trong server chỉ chạy các tác vụ đã lên lịch đến hạn bằng tùy chọn [--due-now], còn [flock -n] bỏ qua lần chạy mới nếu lần chạy trước chưa xong.
⚙️ WP-CLI và cron hệ thống 1 phút, chống chạy trùng tác vụ cron
WP_CRON mặc định có cấu trúc là khi khối lượng công việc nhiều thì tác vụ bị bỏ qua rồi chạy lại sau. Hãy tắt WP-Cron mặc định và đặt khóa 5 phút cho tác vụ đã lên lịch để cron hệ thống và WP-Cron không chạy chồng lên nhau.
define('DISABLE_WP_CRON', true); // Tắt tự động chạy WP-Cron
define('WP_CRON_LOCK_TIMEOUT', 300); // Không chờ → bỏ qua; giữ khóa 5 phút khi chạy tác vụ đã lên lịch
/* That's all, stop editing! Happy publishing. */Thêm tùy chọn flock -n cho cron hệ thống để phía cron hệ thống thoát ngay lập tức.
# Thiết lập wp cron: flock -n → không chờ → thoát ngay
*/1 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quietKết quả của tổ hợp thiết lập trên là:
- Tự động chạy bên trong WP bị tắt → tác vụ đã lên lịch chạy bất kể số lượng khách truy cập
- Cron hệ thống thử chạy mỗi 1 phút → nếu có tác vụ đã lên lịch thì sẽ chạy
- Khi đã khóa thì không chạy lại trong 5 phút → chống chạy trùng (thực tế với thiết lập flock -n thì WP_CRON_LOCK_TIMEOUT không thật sự cần thiết.)
Với cơ chế chống chạy trùng, luồng hoạt động thực tế là:
- 08:00 → cron hệ thống gọi wp-cron.php
- Tác vụ đã lên lịch A chạy → đặt khóa 5 phút
- 08:01 → cron hệ thống gọi lại
- Tác vụ A đang bị khóa → không chạy
- 08:02–08:04 → tương tự
- 08:05 → mở khóa → nếu có tác vụ đã lên lịch tiếp theo thì sẽ chạy
Thay vì WordPress tự động chạy, hệ thống sẽ chịu trách nhiệm chạy các tác vụ. Còn WP_CRON_LOCK_TIMEOUT hoạt động như một lớp an toàn phụ để chống chạy trùng.
|
Hạng mục |
WP_CRON_LOCK_TIMEOUT |
flock -n |
|---|---|---|
|
Kiểu khóa |
Bên trong WordPress |
Cấp hệ thống |
|
Vị trí khóa |
Dựa trên DB: doing_cron trong wp_options |
Dựa trên file hệ thống: ~/.wp_cron.lock |
|
Có chờ không |
❌ Không chờ → bỏ qua |
❌ Không chờ → thoát ngay |
|
Chống chạy trùng |
✅ Chống chạy trùng |
✅ Chống chạy trùng |
Sau khi hoàn tất, bạn có thể kiểm tra bằng lệnh WP-CLI. Hãy xác nhận cron vẫn hoạt động tốt như trước.
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 |
+-------------------------------------------+---------------------+-----------------------+---------------+Kết quả hiển thị tên hook đã đăng ký, thời điểm chạy tiếp theo và chu kỳ lặp; tác vụ có cột [next_run_relative] là [now] sẽ được xử lý ngay ở lần chạy cron tiếp theo.
Ⅲ. Khi tác vụ đã lên lịch của WP-Cron không chạy
Dễ nghĩ rằng đến giờ đã lên lịch thì tác vụ sẽ tự chạy, nhưng WP-Cron không dựa vào thời gian mà kiểm tra việc cần làm khi có yêu cầu trang đi vào. Tác vụ lên lịch lúc 2 giờ chiều, nếu đến 5 giờ chiều vẫn không có yêu cầu nào, sẽ chạy ở yêu cầu đầu tiên lúc 5 giờ.
Khi việc chạy bị trễ, bài viết lên lịch đăng sẽ hiện là [Lịch trình bị bỏ lỡ] (Missed schedule) trong danh sách bài viết. Trong [cải tiến được đề xuất] ở tab Trạng thái của [Công cụ › Tình trạng website] sẽ xuất hiện [Sự kiện được lên lịch gặp vấn đề]. Các tác vụ do plugin đăng ký như tải trước cache cũng phải chờ chạy vì lý do tương tự.
Tác vụ đã lên lịch chạy trong [wp-cron.php] sau khi đi qua yêu cầu trang, bước kiểm tra việc cần làm và yêu cầu loopback; chỉ cần một khâu bị đứt là tác vụ không chạy dù đã quá giờ.
1️⃣ Khi không có lượt truy cập hoặc cache trang phản hồi
WP-Cron chỉ kiểm tra việc cần làm trong những yêu cầu làm WordPress chạy, nên trong khoảng thời gian không có lượt truy cập, các tác vụ đã quá giờ cứ thế dồn lại. Dù có lượt truy cập, nếu phản hồi bằng file cache trang thì WordPress không chạy và kết quả vẫn vậy.
Trên WordPress bật cache trang của WP Rocket, khi mở trang chủ đã được cache thì không có lệnh gọi [wp-cron.php] nào được ghi lại. Khi mở một địa chỉ không được cache, lệnh gọi được ghi lại ngay trong cùng giây, và năm tác vụ bị dồn đã chạy.
Có thể xem các tác vụ bị dồn bằng cách lọc danh sách WP-CLI, chỉ giữ những dòng có [next_run_relative] là [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] là tác vụ đã quá thời điểm dự kiến. Lệnh liệt kê này cũng tải WordPress, nên nếu có tác vụ bị dồn, nó sẽ gọi [wp-cron.php] ngay khi kết thúc. Chạy lại cùng lệnh ngay lập tức thì tác vụ vừa thấy đã biến mất khỏi danh sách.
Để xử lý các tác vụ bị dồn trước khi sửa nguyên nhân, hãy dùng WP-CLI chạy ngay chỉ những tác vụ đã đến hạn.
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.Lệnh này chạy tác vụ bên trong server mà không cần yêu cầu HTTP; để xử lý theo chu kỳ cố định bất kể lượt truy cập, hãy đăng ký cùng lệnh này vào cron hệ thống.
2️⃣ Khi chỉ bật DISABLE_WP_CRON mà không có cron hệ thống
Nếu đặt [DISABLE_WP_CRON] là true, WP-Cron sẽ không kiểm tra việc cần làm dù có yêu cầu trang. Tài liệu chính thức cũng hướng dẫn theo thứ tự đăng ký với trình lập lịch tác vụ của hệ thống trước rồi mới thêm hằng số này; nếu chỉ thêm hằng số mà không đăng ký thì sẽ không còn nơi nào chạy tác vụ đã lên lịch.
Khi đã thêm hằng số, bài viết lên lịch sau hơn 1 phút vẫn ở trạng thái [Lên kế hoạch] dù đã quá giờ, và cột ngày trong danh sách bài viết hiện [Lịch trình bị bỏ lỡ]. Trong suốt thời gian đó, không có lệnh gọi [wp-cron.php] nào được ghi lại.
Có thể kiểm tra hằng số này có đang bật hay không bằng [wp cron test].
wp cron testError: The DISABLE_WP_CRON constant is set to true. WP-Cron spawning is disabled.Nếu gặp lỗi này, hãy kiểm tra cron hệ thống có dòng nào gọi [wp-cron.php] hoặc chạy [wp cron event run] không. Nếu crontab của tài khoản website trống, kết quả sẽ hiển thị như dưới đây.
crontab -lno crontab for exampleNếu không có dòng đó, hãy đăng ký cron hệ thống; nếu môi trường không cho phép đăng ký, hãy xóa dòng [DISABLE_WP_CRON] để dùng lại WP-Cron.
3️⃣ Khi yêu cầu loopback của server bị chặn
Khi có việc cần làm, WP-Cron để server gửi yêu cầu đến [wp-cron.php] tại địa chỉ website của chính nó để chạy tác vụ; yêu cầu này chính là yêu cầu loopback. Nếu có quy tắc bảo mật chặn [wp-cron.php], yêu cầu loopback sẽ trả về 403 và tác vụ không chạy.
Trên server cấu hình Nginx và Apache, khi giới hạn [wp-cron.php] chỉ mở được từ 127.0.0.1, yêu cầu loopback bị chặn với 403. Lý do là yêu cầu server gửi đến chính domain của nó đi vào qua IP công khai, và [wp cron test] cũng trả về cùng mã trạng thái.
wp cron testError: WP-Cron spawn returned HTTP status code: 403 ForbiddenKhi tác vụ đã bị dồn hơn 5 phút, mở màn hình [Tình trạng website] thì trong [cải tiến được đề xuất] hiện cùng lúc cảnh báo loopback và sự kiện đã lên lịch bị lỗi.

Sau khi xóa quy tắc, [wp cron test] lại thành công. Nếu cần giữ quy tắc, hãy chạy bằng WP-CLI từ cron hệ thống. Chạy bằng WP-CLI không đi qua yêu cầu HTTP, nên các tác vụ bị dồn vẫn được xử lý dù quy tắc đó vẫn còn.
🔢 FAQ & nội dung đề xuất






ℹ️ Thông báo tiếp thị liên kết
Nội dung trên trang này có chứa liên kết affiliate (tiếp thị liên kết). Khi khách truy cập mua sản phẩm hoặc dịch vụ qua các liên kết này, trang sẽ nhận hoa hồng từ bên bán. Trong quá trình đó, số tiền người mua phải trả (sẽ giảm khi có chương trình khuyến mãi ↓) không hề tăng lên. Giá, khuyến mãi và tình trạng hàng được đăng theo thời điểm viết bài và có thể khác với thực tế, vì vậy hãy kiểm tra lại lần cuối với bên bán trước khi mua. Việc chọn và đánh giá sản phẩm dựa trên tiêu chí riêng của trang; việc có nhận hoa hồng hay không không ảnh hưởng đến thứ tự giới thiệu hay nội dung đánh giá.