Tối Ưu WordPress Heartbeat API: Giảm 70% Tải CPU Server Trong 10 Phút

Câu trả lời nhanh
WordPress Heartbeat API gửi AJAX request mỗi 15-60 giây khi mở wp-admin, gây quá tải CPU trên VPS cấu hình thấp. Bạn có thể giảm tần suất xuống 120 giây bằng code trong functions.php, tắt trên frontend, hoặc rate-limit admin-ajax.php ở tầng Nginx/OpenLiteSpeed. Kết hợp các phương pháp này có thể giảm 70-87% tải CPU.

Mình đã quản lý hàng chục site WordPress trong nhiều năm, và một trong những nguyên nhân gây quá tải CPU phổ biến nhất mà nhiều người bỏ qua chính là WordPress Heartbeat API. Tính năng này liên tục gửi AJAX request mỗi 15-60 giây khi bạn mở wp-admin, và trên các site có VPS cấu hình thấp, nó có thể ăn tới 30-40% CPU.

Trong bài này, mình sẽ hướng dẫn bạn từ A đến Z: hiểu Heartbeat API hoạt động thế nào, cách kiểm tra nó đang gây tải quá mức, và các phương pháp tối ưu từ nhẹ đến mạnh để giảm tải server ngay lập tức.

WordPress Heartbeat API La Gi Va Sao No An Tai CPU?

Tối ưu WordPress Heartbeat API - Giảm 70% tải CPU server

Heartbeat API được giới thiệu từ WordPress 3.6, hoạt động như một “nhịp tim” gửi AJAX request đến /wp-admin/admin-ajax.php mỗi 15-60 giây. Mục đích chính là đồng bộ dữ liệu realtime: auto-save bài viết, hiển thị thông báo plugin mới, lock bài khi nhiều người chỉnh sửa, và cập nhật dashboard.

Vấn đề nằm ở chỗ: mỗi heartbeat request đều khởi tạo một PHP process đầy đủ, load WordPress core, kết nối database, chạy các hook của plugin và theme. Nếu bạn có 5 admin đang mở wp-admin cùng lúc, server phải xử lý 5 request mỗi 15 giây. Trên VPS 1-2GB RAM, điều này đủ để khiến CPU chạy 100%.

Cách Kiểm Tra Heartbeat API Co Dang Gay Qua Tai Khong?

Trước khi tối ưu, bạn cần xác minh Heartbeat có thực sự là thủ phạm. Mình thường dùng hai cách sau:

Cách 1: Kiểm tra access log

# Đếm số lượng admin-ajax.php request trong 1 giờ gần nhất
grep "admin-ajax.php" /var/log/nginx/thienlv.com.access.log | \
  awk '{print $4}' | cut -c2-15 | sort | uniq -c | sort -rn | head -20

# Nếu thấy 100+ request mỗi phút từ cùng IP, Heartbeat đang chạy quá nhanh

Cách 2: Dùng New Relic hoặc GTmetrix Waterfall

Mở wp-admin, nhấn F12 mở DevTools, vào tab Network, lọc theo admin-ajax. Bạn sẽ thấy các request POST liên tục đến admin-ajax.php với action heartbeat. Nếu khoảng cách giữa các request dưới 15 giây, Heartbeat đang chạy quá nhanh.

Cách 3: Kiểm tra CPU load trực tiếp

# Theo dõi CPU real-time khi mở wp-admin
top -c -p $(pgrep -d',' php8.)

# Mở wp-admin trên browser, quan sát CPU tăng đột biến
# Nếu CPU nhảy lên 80-100% khi mở wp-admin, Heartbeat rất có thể là nguyên nhân

Cach Tat Hoac Giam Tan Suat Heartbeat API Bang Plugin

Cách đơn giản nhất cho người mới là dùng plugin Heartbeat Control (miễn phí trên WordPress.org). Plugin này cho phép bạn điều chỉnh tần suất Heartbeat hoặc tắt hoàn toàn theo từng khu vực.

Bước 1: Cài đặt Heartbeat Control

# Cài qua WP-CLI
sudo -u www-data wp plugin install heartbeat-control --activate \
  --path=/var/www/thienlv.com/public_html

Bước 2: Vào Settings > Heartbeat Control, cấu hình như sau:

  • Dashboard: Giảm tần suất (modify frequency) xuống 120 giây
  • Editor (Post Edit): Giữ 60 giây để auto-save vẫn hoạt động
  • Frontend: Tắt hoàn toàn (disable) vì không cần thiết

Bước 3: Lưu lại và kiểm tra bằng DevTools. Tần suất heartbeat phải giảm rõ rệt.

Nếu bạn không muốn cài thêm plugin, mình khuyên dùng cách thủ công qua code ở phần tiếp theo.

Huong Dan Cau Hinh Heartbeat API Bang Code Khong Can Plugin

Mình thích cách này hơn vì không cần cài thêm plugin, nhẹ hơn và kiểm soát chi tiết hơn. Bạn chỉ cần thêm vài dòng code vào functions.php của theme child.

Tắt Heartbeat trên frontend:

// Thêm vào functions.php của child theme
add_action( 'init', function() {
    if ( ! is_admin() ) {
        wp_deregister_script( 'heartbeat' );
    }
}, 1 );

// Hoặc dùng wp_heartbeat_settings
add_filter( 'heartbeat_settings', function( $settings ) {
    if ( ! is_admin() ) {
        $settings['interval'] = 0; // Tắt trên frontend
    }
    return $settings;
});

Giảm tần suất Heartbeat trong wp-admin xuống 120 giây:

add_filter( 'heartbeat_settings', function( $settings ) {
    // 120 giây thay vì mặc định 15-60 giây
    $settings['interval'] = 120;
    return $settings;
});

Tắt Heartbeat hoàn toàn (chỉ khi bạn không dùng tính năng auto-save và co-editing):

add_action( 'init', function() {
    wp_deregister_script( 'heartbeat' );
}, 1 );

Chỉ tắt Heartbeat trên các trang cụ thể trong admin:

add_action( 'admin_enqueue_scripts', function() {
    $screen = get_current_screen();
    
    // Tắt trên Dashboard và Plugins (ít cần realtime)
    if ( $screen->base === 'dashboard' || $screen->base === 'plugins' ) {
        wp_deregister_script( 'heartbeat' );
    }
});

Toi Uu Heartbeat API Tren Server Nginx Va OpenLiteSpeed

Nếu bạn quản lý server, có một kỹ thuật nâng cao hơn: rate-limiting admin-ajax.php ở tầng server. Cách này hiệu quả hơn vì chặn request trước khi nó đến PHP, tiết kiệm CPU đáng kể.

Trên Nginx:

# Thêm vào server block của site
location = /wp-admin/admin-ajax.php {
    # Giới hạn 2 request mỗi 15 giây cho mỗi IP
    limit_req zone=admin_ajax burst=3 nodelay;
    
    # Các config PHP fastcgi bình thường
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}

# Định nghĩa zone trong http block (nginx.conf)
# limit_req_zone $binary_remote_addr zone=admin_ajax:10m rate=8r/m;

Sau khi chỉnh sửa, reload Nginx:

sudo nginx -t && sudo systemctl reload nginx

Trên OpenLiteSpeed:

Vào WebAdmin > Virtual Hosts > Context > thêm context cho /wp-admin/admin-ajax.php:

# Tạo context mới
Type: App Server
URI: /wp-admin/admin-ajax.php
Location: /wp-admin/admin-ajax.php

# Vào tab "Security" của context
# Bật Rate Limiting
# Request Rate: 8 requests per minute
# Burst: 3

Rate-limiting ở tầng server có ưu điểm lớn: request bị chặn sẽ không bao giờ đến PHP, tiết kiệm 100% CPU cho các request đó.

Heartbeat API Anh Huong Nhu The Nao Den Core Web Vitals?

Nhiều người nghĩ Heartbeat chỉ ảnh hưởng đến wp-admin, nhưng không đúng. Nếu theme hoặc plugin gọi Heartbeat trên frontend (rất phổ biến với WooCommerce, BuddyPress, LearnDash), mỗi request sẽ cạnh tranh tài nguyên server với request của người dùng thật, làm chậm TTFB và gián tiếp ảnh hưởng LCP.

Mình đã từng làm cho một site WooCommerce bị CLS (Cumulative Layout Shift) kém, nguyên nhân là plugin chat gọi Heartbeat mỗi 5 giây trên frontend để kiểm tra tin nhắn mới. Sau khi tắt Heartbeat trên frontend và chuyển chat sang WebSocket, CLS giảm từ 0.25 xuống 0.05, LCP giảm từ 2.8 giây xuống 1.4 giây.

Kiểm tra Heartbeat trên frontend:

# Mở trang chủ, F12 > Network > filter "admin-ajax"
# Nếu thấy request POST admin-ajax.php lặp lại, Heartbeat đang chạy trên frontend

# Hoặc check source HTML
curl -s https://yourdomain.com/ | grep -i "heartbeat"
# Nếu có script heartbeat, theme/plugin đang load nó trên frontend

Cac Plugin Thuong Gay Tai Heartbeat Lon Nhat

Qua kinh nghiệm quản lý hàng chục site, mình nhận thấy các plugin sau thường dùng Heartbeat API nhiều nhất, gây tải server đáng kể:

  • WooCommerce – Kiểm tra đơn hàng mới, cập nhật stock realtime trong dashboard
  • Elementor – Auto-save khi chỉnh sửa, kiểm tra lock bài
  • Yoast SEO – Lưu indexable data định kỳ
  • WPML – Đồng bộ translation giữa các editor
  • LearnDash / LifterLMS – Theo dõi tiến trình học realtime
  • Plugin chat (Crisp, Tawk.to wrapper) – Poll tin nhắn mới

Nếu bạn đang dùng các plugin này, mình khuyên kiểm tra Heartbeat ngay. Đặc biệt với WooCommerce, bạn có thể tắt Heartbeat trên frontend và chỉ giữ ở trang wp-admin > WooCommerce > Orders.

Kiem Tra Ket Qua Sau Khi Toi Uu Heartbeat API

Sau khi áp dụng các tối ưu trên, bạn cần đo lường để xác nhận kết quả. Mình dùng các phương pháp sau:

Đo CPU load trước và sau:

# Trước khi tối ưu - ghi lại baseline
top -bn1 | grep "Cpu(s)" | awk '{print $2}'
# Ví dụ: 45.3% user CPU khi mở wp-admin

# Sau khi tối ưu - mở cùng số tab wp-admin, đo lại
top -bn1 | grep "Cpu(s)" | awk '{print $2}'
# Ví dụ: 12.1% user CPU - giảm 73%

Đếm request admin-ajax.php trước và sau:

# Trước: Đếm request trong 5 phút
grep "admin-ajax.php" /var/log/nginx/access.log | \
  awk -v d="$(date -d '5 minutes ago' '+%d/%b/%Y:%H:%M')" \
  '$0 ~ d' | wc -l
# Ví dụ: 340 requests trong 5 phút

# Sau khi tối ưu: lặp lại câu lệnh
# Ví dụ: 42 requests trong 5 phút - giảm 87%

Test bằng Query Monitor plugin:

# Cài Query Monitor
sudo -u www-data wp plugin install query-monitor --activate \
  --path=/var/www/thienlv.com/public_html

Mở wp-admin, nhìn thanh Query Monitor trên cùng. Nếu trước tối ưu bạn thấy “MySQL Queries: 120” và thời gian load 1.5 giây, sau tối ưu sẽ giảm xuống khoảng “MySQL Queries: 40” và 0.3 giây.

Ket Luan: Heartbeat API Toi Uu Khi Nao Va The Nao?

Không phải site nào cũng cần tối ưu Heartbeat. Nếu site của bạn có ít người dùng admin đồng thời, chạy trên VPS 4GB+ RAM, và không dùng plugin nặng, Heartbeat mặc định hoàn toàn ổn. Nhưng nếu bạn gặp các dấu hiệu sau, hãy tối ưu ngay:

  • CPU thường xuyên trên 70% khi mở wp-admin
  • Site chậm đột ngột khi nhiều editor làm việc cùng lúc
  • admin-ajax.php chiếm top request trong access log
  • VPS 1-2GB RAM và hay bị OOM (Out of Memory)
  • WooCommerce dashboard load quá 3 giây

Lưu ý quan trọng: không tắt Heartbeat hoàn toàn nếu bạn dùng tính năng co-editing (nhiều người viết cùng bài). Heartbeat cần thiết để lock bài và auto-save. Trong trường hợp này, chỉ giảm tần suất xuống 120 giây thay vì tắt.

Nếu bạn đang chuẩn bị nâng cấp lên WordPress 7.1 ngày 19/8 tới, đây cũng là lúc lý tưởng để dọn dẹp Heartbeat trước khi update, vì WordPress 7.1 thêm nhiều tính năng realtime mới có thể tăng tải Heartbeat thêm. Kết hợp với việc thay WP-Cron bằng server cron mà mình đã hướng dẫn trước đó, server của bạn sẽ nhẹ hơn rất nhiều.

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 *