Tat WP-Cron Dung Server Cron: Toi Uu Background Tasks WordPress 2026

Câu trả lời nhanh
WP-Cron kích hoạt trên mỗi page load gây spike CPU. Tắt bằng DISABLE_WP_CRON=true trong wp-config.php, rồi thêm server cron */5 * * * * chạy wp-cron.php qua PHP CLI. Kết quả: TTFB giảm 10-30ms, không còn spike CPU giờ cao điểm, scheduled tasks chạy đúng giờ.

Nhiều người gọi mình hỏi: “Site WordPress chạy chậm lúc 2-3h chiều mỗi ngày, kiểm tra traffic thì bình thường, PageSpeed vẫn điểm cao. Tại sao?”. Trong 8/10 trường hợp, thủ phạm là WP-Cron — hệ thống scheduled tasks của WordPress đang âm thầm chạy ngầm, ăn RAM và CPU đúng lúc traffic đông nhất.

Trong bài này, mình sẽ hướng dẫn cách tắt WP-Cron mặc định, cấu hình server cron thay thế, và tối ưu toàn bộ background tasks để site WordPress chạy ổn định 24/7. Toàn bộ quy trình áp dụng được trên VPS Ubuntu/Debian chạy Nginx, Apache, hoặc OpenLiteSpeed.

WP-Cron vs Server Cron cho WordPress - server monitoring dashboard
WP-Cron chạy trên mỗi page load có thể gây spike CPU bất ngờ, server cron cho phép lịch chạy ổn định hơn

WP-Cron La Gi Va Tai Sao No Lam Site Cham?

WP-Cron là hệ thống lập lịch tác vụ tự động của WordPress. Nó chịu trách nhiệm publish bài đang lên lịch, kiểm tra update plugin, gửi email thông báo, xóa transient hết hạn, và hàng tá tác vụ khác từ plugin.

Vấn đề nằm ở cách WP-Cron hoạt động: thay vì chạy theo lịch cố định như cron job Linux, WP-Cron kích hoạt trên mỗi page load. Mỗi khi có người truy cập, WordPress kiểm tra xem có task nào đến hạn chưa. Nếu có, nó thực thi ngay trong request đó.

Điều này tạo ra hai vấn đề lớn. Thứ nhất, trên site đông traffic, nhiều page load cùng lúc đều kiểm tra WP-Cron, gây race condition và spike CPU. Thứ hai, trên site ít traffic, task có thể không chạy đúng giờ vì không ai truy cập để kích hoạt.

Cach Kiem Tra WP-Cron Dang Chay Gi Tren Site

Trước khi tối ưu, mình cần biết hiện tại WP-Cron đang chạy những gì. Cài plugin WP Crontrol (miễn phí, hơn 300.000 active installs) để xem toàn bộ cron events:

# Cài qua WP-CLI
wp plugin install wp-crontrol --activate

# Hoặc tải thủ công từ wordpress.org/plugins/wp-crontrol/

Sau khi kích hoạt, vào Tools > Cron Events. Bạn sẽ thấy danh sách tất cả scheduled tasks, gồm: tên hook, thời gian lên lịch tiếp theo, khoảng lặp lại, và callback function. Mình thường thấy site client có 30-50 cron events, trong đó phần lớn là update check từ plugin không cần thiết.

Nếu dùng WP-CLI, kiểm tra nhanh bằng lệnh:

# Liệt kê tất cả cron events
wp cron event list

# Xem cron schedule
wp cron schedule list

Kết quả mẫu trên một site WooCommerce tiêu chuẩn: khoảng 25 events, chủ yếu là wp_version_check, wp_update_plugins, wp_update_themes, woocommerce_scheduled_sales, woocommerce_cleanup_sessions. Tất cả đều chạy trên cùng default schedule.

BUOC 1: Tat WP-Cron Mac Dinh

Đây là bước đơn giản nhất nhưng quan trọng nhất. Mở file wp-config.php, tìm dòng /* That's all, stop editing! */ và thêm vào phía trên:

// Tat WP-Cron mac dinh, dung server cron thay the
define( 'DISABLE_WP_CRON', true );

Ngay sau khi lưu file, WP-Cron sẽ không còn kích hoạt trên mỗi page load. Tại thời điểm này, các tác vụ lên lịch sẽ tạm thời không chạy cho đến khi mình cấu hình server cron ở bước tiếp theo.

Lưu ý: không xóa file wp-cron.php. File này vẫn cần thiết, chỉ là mình sẽ gọi nó theo lịch cố định thay vì để WordPress tự gọi.

BUOC 2: Cau Hinh Server Cron Cho WordPress

SSH vào server và tạo cron job gọi file wp-cron.php mỗi 5 phút:

# Mở crontab editor
crontab -e

# Thêm dòng sau vào cuối file
*/5 * * * * curl -s -o /dev/null https://yoursite.com/wp-cron.php?doing_wp_cron

# Hoặc dùng PHP CLI (tốt hơn, không qua web server)
*/5 * * * * cd /var/www/yoursite.com/public_html && php wp-cron.php >/dev/null 2>&1

Mình prefer cách thứ hai (PHP CLI) vì ba lý do: không tốn bandwidth web server, không bị timeout bởi reverse proxy, và không ghi log access vào Nginx/Apache.

Nếu server chạy nhiều site WordPress (multisite hoặc nhiều domain), cấu hình riêng cho từng site:

# Site A - mỗi 5 phút
*/5 * * * * cd /var/www/site-a.com/public_html && php wp-cron.php >/dev/null 2>&1

# Site B - mỗi 10 phút (ít task hơn)
*/10 * * * * cd /var/www/site-b.com/public_html && php wp-cron.php >/dev/null 2>&1

# WooCommerce store - mỗi 3 phút (cần process order nhanh)
*/3 * * * * cd /var/www/shop.com/public_html && php wp-cron.php >/dev/null 2>&1

Kiểm tra cron job đã được thêm thành công:

# Liệt kê tất cả cron jobs
crontab -l

# Xem cron log (trên Ubuntu/Debian)
grep CRON /var/log/syslog | tail -20

BUOC 3: Don Dep Cron Events Khong Can Thiet

Sau khi chuyển sang server cron, đây là lúc tối ưu số lượng tasks. Mình luôn audit kỹ từng cron event và loại bỏ những cái không cần thiết. Trở lại WP Crontrol, identifying các nhóm task thừa:

Nhóm 1: Update check từ plugin cũ — Nhiều plugin thêm cron check update mỗi giờ dù không cần. Nếu plugin có ở wordpress.org, WordPress core đã tự check rồi. Xóa các event dạng pluginname_check_update nếu plugin đó đã nằm trong repo.

Nhóm 2: Marketing plugin chạy mỗi 5 phút — Plugin email marketing, social auto-post thường set interval rất ngắn. Nếu không cần post mỗi 5 phút, đổi sang 30 phút hoặc 1 giờ.

Nhóm 3: Task từ plugin đã gỡ nhưng cron còn sót — Rất phổ biến. Gỡ plugin không nghĩa là cron bị xóa theo. Dùng WP Crontrol xóa thủ công.

Dùng WP-CLI để quản lý cron events:

# Xóa một cron event cụ thể
wp cron event delete wp_update_plugins

# Chạy thử một cron event để test
wp cron event run wp_version_check

# Xem thời gian chạy tiếp theo của tất cả events
wp cron event list --fields=hook,next_run_relative,recurrence

BUOC 4: Toi Uu Cron Schedule Cho WooCommerce

WooCommerce phụ thuộc cron rất nhiều: process pending orders, send transactional emails, cleanup sessions, scheduled sales, subscription renewals. Nếu site chạy WooCommerce, mình cần cấu hình cron aggresive hơn.

Tạo cron schedule riêng cho WooCommerce bằng cách thêm vào functions.php hoặc plugin custom:

// Thêm cron interval 3 phút cho WooCommerce
add_filter( 'cron_schedules', function( $schedules ) {
    $schedules['every_3_minutes'] = array(
        'interval' => 180,
        'display'  => __( 'Every 3 Minutes' )
    );
    $schedules['every_15_minutes'] = array(
        'interval' => 900,
        'display'  => __( 'Every 15 Minutes' )
    );
    return $schedules;
});

Sau đó đổi schedule cho các WooCommerce events quan trọng sang interval ngắn hơn, và các task cleanup sang interval dài hơn:

// Đổi WooCommerce cleanup sessions sang every 15 minutes
// Thay vì mỗi lần load page
if ( ! wp_next_scheduled( 'woocommerce_cleanup_sessions' ) ) {
    wp_schedule_event( time(), 'every_15_minutes', 'woocommerce_cleanup_sessions' );
}

Quan trọng: đảm bảo PHP max_execution_time đủ cao để WooCommerce cron chạy hết. Mình thường set 120 giây cho site WooCommerce:

# php.ini hoặc .htaccess hoặc PHP-FPM pool config
max_execution_time = 120
memory_limit = 512M

BUOC 5: Xu Ly Backup Va Import Khong Anh Huong Visitor

Backup và import là hai tác vụ nặng nhất trong WordPress. Nếu chạy đúng lúc traffic đông, site sẽ chậm rõ rệt. Nguyên tắc mình luôn tuân thủ:

Backup: Chạy vào khung giờ thấp điểm (2-4h sáng). Nếu dùng plugin backup như UpdraftPlus, cấu hình schedule:

// wp-config.php hoặc plugin config
// Set backup chạy lúc 3h sáng Chủ nhật
define( 'UPDRAFTPLUS_BACKUP_TIME', '03:00' );

Tốt hơn nữa, dùng backup ở mức server thay vì plugin. Snapshot ở mức disk không tải PHP hay database:

# Crontab: backup database lúc 3h sáng mỗi ngày
0 3 * * * mysqldump -u root wordpress_db | gzip > /backups/db-$(date +\%Y\%m\%d).sql.gz

# Xóa backup cũ hơn 7 ngày
0 4 * * * find /backups/ -name "db-*.sql.gz" -mtime +7 -delete

Import: Chia nhỏ batch và chạy cách quãng. Thay vì import 10.000 sản phẩm cùng lúc, chia thành 500 sản phẩm mỗi 15 phút:

# Crontab: import batch mỗi 15 phút trong giờ thấp điểm
*/15 1-5 * * * cd /var/www/shop.com/public_html && wp wc product_import run --batch=500 >/dev/null 2>&1

Cach Debug Khi Cron Khong Chay

Nếu sau khi cấu hình, cron không chạy, đây là checklist mình dùng để debug:

1. Kiểm tra DISABLE_WP_CRON đã đúng chỗ:

# Phải ở TRƯỚC dòng "That's all, stop editing!" trong wp-config.php
grep DISABLE_WP_CRON wp-config.php

2. Kiểm tra server cron service đang chạy:

sudo systemctl status cron
sudo systemctl status crond  # CentOS/RHEL

3. Test wp-cron.php chạy được qua CLI:

cd /var/www/yoursite.com/public_html
php wp-cron.php
echo $?  # 0 = thành công, khác 0 = có lỗi

4. Kiểm tra PHP path: Crontab có thể dùng PHP version khác so với web server:

# Xem PHP path trong cron environment
which php
php -v

# Nếu sai version, chỉ định đường dẫn tuyệt đối trong crontab
*/5 * * * * cd /var/www/yoursite.com/public_html && /usr/bin/php8.3 wp-cron.php >/dev/null 2>&1

5. Kiểm tra quyền file: User chạy cron phải có quyền đọc wp-cron.php và ghi wp-content:

# Nếu chạy cron sebagai root nhưng WordPress file thuộc www-data
# Cần chạy cron dưới user www-data
sudo -u www-data crontab -e
# Hoặc trong system crontab
*/5 * * * * www-data cd /var/www/yoursite.com/public_html && php wp-cron.php >/dev/null 2>&1

Do Kiem Tra Sau Khi Cau Hinh

Sau 24-48 giờ cấu hình, mình luôn verify kết quả. Các chỉ số cần quan tâm:

Server response time (TTFB): Trước và sau khi tắt WP-Cron, TTFB nên giảm 10-30ms trên dynamic requests. Kiểm tra bằng:

# Test TTFB
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" \
  https://yoursite.com/

# Chạy 10 lần để lấy trung bình
for i in {1..10}; do
  curl -o /dev/null -s -w "%{time_starttransfer}\n" https://yoursite.com/
done

CPU usage: Giảm đáng kể trong giờ cao điểm. Theo dõi bằng htop hoặc vmstat:

# Theo dõi CPU real-time
htop
# Hoặc
vmstat 5 10

PHP-FPM status: Ít process bị block hơn:

# Kiểm tra PHP-FPM status page
curl http://127.0.0.1/status

# Hoặc xem process count
ps aux | grep php-fpm | grep -v grep | wc -l

Nếu site chạy Redis Object Cache kết hợp với Nginx FastCGI Cache (mình đã hướng dẫn tại đây), việc tắt WP-Cron sẽ giảm tải PHP-FPM thêm 15-20%, giúp cache hit ratio tăng lên vì ít phải bypass cache để xử lý cron hơn.

Ket Luan: Mot Thay Doi Nho, Tac Dong Lon

Tắt WP-Cron và chuyển sang server cron là một trong những tối ưu đơn giản nhất nhưng mang lại impact lớn nhất cho WordPress. Mình đã áp dụng cho hơn 100 site, từ blog cá nhân đến WooCommerce store nghìn đơn/ngày, và kết quả luôn rõ ràng: TTFB ổn định hơn, không còn spike CPU bất ngờ, và scheduled tasks chạy đúng giờ.

Toàn bộ quy trình mất khoảng 30 phút thiết lập ban đầu, sau đó thì không cần đụng tới nữa. Nếu bạn đang chạy WordPress trên VPS hoặc hosting cho phép SSH access, hãy làm ngay hôm nay. Còn nếu dùng shared hosting không có crontab, hỏi nhà cung cấp xem có Cron Jobs feature trong cPanel/DirectAdmin không — đa số đều có.

Nếu gặp vấn đề trong quá trình cấu hình, để lại comment bên dưới, mình sẽ hỗ trợ từng bước.

Thanh Tùng

Mình là Thanh Tùng. Bạn bè gọi mình là "bác sĩ máy tính" vì hễ máy nào có vấn đề là mình muốn mò vào xem sao. Mình viết hướng dẫn theo cách mà mình mong người khác đã viết cho mình ngày xưa — từng bước rõ ràng, không bỏ sót, và nói luôn cái gì hay bị lỗi. Ngoài giờ làm mình chơi guitar, nuôi mèo, và có một con VPS riêng dành riêng cho việc cài thử đủ thứ linh tinh.

Xem tất cả bài viết →

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *