❤️ AZDIGI chính thức cập nhật hệ thống blog mới hoàn chỉnh. Tuy nhiên có thể một số bài viết bị sai lệch hình ảnh, hãy ấn nút Báo cáo bài viết ở cuối bài để AZDIGI cập nhật trong thời gian nhanh nhất. Chân thành cám ơn.
Khi CPU VPS của bạn tăng vọt lên 100%, triệu chứng đầu tiên thường là SSH kết nối chậm chạp, website phản hồi timeout, và thậm chí những lệnh đơn giản như ls cũng có thể lag vài giây. Tình huống này rất phổ biến với VPS, đặc biệt khi chạy WordPress hoặc ứng dụng web có traffic cao.
Vấn đề là nhiều admin thấy CPU 100% liền nghĩ ngay đến nâng cấp VPS, nhưng thực tế thì có rất nhiều nguyên nhân khác nhau – từ MySQL query nặng, PHP-FPM cấu hình sai, đến cả malware ẩn. Hiểu đúng nguyên nhân sẽ giúp bạn xử lý chính xác thay vì ném tiền qua cửa sổ.
Kiểm tra tình trạng CPU hiện tại

Bước đầu tiên là xem VPS đang ”nghẹt” ở đâu. Ba lệnh này cho bạn cái nhìn tổng quan nhanh:
Kiểm tra load average với uptime
uptime
Output mẫu:
12:34:56 up 5 days, 2:15, 2 users, load average: 3.45, 2.89, 1.67
Load average là trung bình số process đang chờ CPU trong 1 phút, 5 phút và 15 phút gần nhất. Nếu VPS có 2 CPU cores mà load > 2.0 thì là dấu hiệu overload rồi. Ở ví dụ trên, load 3.45 với VPS 2 cores có nghĩa là CPU đã quá tải.
💡 Mẹo: Load average > số CPU cores = VPS quá tải, cần xử lý ngay
Xem thống kê thời gian thực với lệnh top
top
Output mẫu:
top - 12:35:21 up 5 days, 2:15, 2 users, load average: 3.21, 2.95, 1.89Tasks: 127 total, 4 running, 123 sleeping, 0 stopped, 0 zombie%Cpu(s): 85.3 us, 12.1 sy, 0.0 ni, 2.1 id, 0.5 wa, 0.0 hi, 0.0 si, 0.0 stMiB Mem : 2048.0 total, 156.4 free, 1654.2 used, 237.4 buff/cacheMiB Swap: 1024.0 total, 890.2 free, 133.8 used. 231.6 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3429 mysql 20 0 1.2g 456m 12m S 67.3 22.9 8:45.67 mysqld 1847 www-data 20 0 456m 89m 8m R 18.7 4.5 2:34.12 php-fpm 1923 www-data 20 0 421m 76m 7m S 12.1 3.8 1:56.34 php-fpm
Dòng %Cpu(s) cho thấy CPU breakdown:
- us (user): 85.3% – Process người dùng (MySQL, PHP, Apache…)
- sy (system): 12.1% – Kernel/system processes
- id (idle): 2.1% – CPU rảnh (càng thấp càng báo động)
- wa (wait): 0.5% – Chờ disk I/O
- st (steal): 0.0% – Steal time (VPS bị \”cướp\” CPU bởi host)
Giao diện trực quan với htop
htop
htop có màu sắc dễ nhìn hơn:
- Xanh lá: User processes (bình thường)
- Đỏ: System/kernel processes
- Xám: Chờ I/O (disk, network)
- Cyan: Steal time (dấu hiệu VPS oversold)
- Xanh dương: Low priority processes
⚠️ Lưu ý: Nếu thấy nhiều màu đỏ hoặc cyan, đó là dấu hiệu cần tìm hiểu sâu hơn.
Phân biệt các loại CPU load

Không phải CPU 100% nào cũng giống nhau. Căn cứ vào dòng %Cpu(s) trong top, bạn có thể biết được nguyên nhân chính:
%us cao (>70%) – Ứng dụng user
Đây là trường hợp phổ biến nhất. CPU bị tiêu thụ bởi các ứng dụng như MySQL, PHP-FPM, Apache, Nginx, Node.js…
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 6 0 0 512000 85532 890140 0 0 2 8 85 156 78 15 7 0 0 5 1 0 511800 85532 890144 0 0 0 4 92 189 82 12 6 0 0
Dấu hiệu:
- r cao (6, 5): Nhiều tiến trình chờ CPU
- us + sy cao (78+15=93%, 82+12=94%): CPU đang làm việc cực khổ
- id thấp (7%, 6%): CPU gần như không có thời gian nghỉ
- wa thấp (0%): Không có vấn đề I/O
Giải pháp: Tối ưu ứng dụng, database queries, hoặc điều chỉnh cấu hình.
%sy cao (>30%) – System/kernel
CPU bị kernel tiêu thụ, thường do network I/O nặng, context switching quá nhiều, hoặc driver có vấn đề.
Dấu hiệu:
- Không thấy process user nào đặc biệt cao
- Network traffic lớn (iotop, iftop)
- Số lượng context switches cao (vmstat)
Giải pháp: Kiểm tra network, điều chỉnh kernel parameters, hoặc liên hệ nhà cung cấp VPS.
%wa cao (>20%) – I/O wait
CPU chờ disk hoặc network I/O. Đây không phải là vấn đề CPU thật sự mà là bottleneck ở storage.
iotop -ao # Xem process nào đang ghi/đọc disk nhiều nhất
Output mẫu:
Total DISK READ: 125.67 M/s | Total DISK WRITE: 234.12 M/s PID USER DISK READ DISK WRITE SWAPIN IO COMMAND 3429 mysql 89.23 M/s 156.78 M/s 0.00 % 67.23 % mysqld 2341 root 23.45 M/s 78.90 M/s 0.00 % 23.12 % rsync
ℹ️ Nếu thấy %wa cao, tham khảo bài Disk I/O cao để xử lý cụ thể.
%st cao (>5%) – Steal time
VPS bị host ”cướp” CPU để phục vụ VPS khác. Dấu hiệu của nhà cung cấp oversold hoặc noisy neighbor.
🚫 Cảnh báo: Nếu steal time > 10%, liên hệ support ngay – đây là vấn đề của infrastructure.
Tìm process ngốn CPU

Sau khi hiểu được loại load, bước tiếp theo là xác định chính xác process nào đang \”ăn\” CPU.
Lệnh ps để sắp xếp theo CPU
ps aux --sort=-%cpu | head -15
Output mẫu:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDmysql 3429 67.3 22.9 1234567 456789 ? Sl 10:23 8:45 /usr/sbin/mysqldwww-data 1847 18.7 4.5 456789 89012 ? S 09:15 2:34 php-fpm: pool wwwwww-data 1923 12.1 3.8 421345 76543 ? S 09:18 1:56 php-fpm: pool wwwwww-data 2156 8.9 3.2 398765 65432 ? S 09:45 1:23 php-fpm: pool wwwroot 2341 6.7 1.2 234567 23456 ? D 11:30 0:45 rsync -av /backup/
Ở đây thấy rõ MySQL đang chiếm 67.3% CPU, tiếp theo là các worker php-fpm.
Theo dõi real-time với pidstat
pidstat -u 1 5 # Cập nhật mỗi 1 giây, lặp 5 lần
Output mẫu:
12:35:45 UID PID %usr %system %guest %CPU CPU Command12:35:46 0 3429 65.00 2.00 0.00 67.00 1 mysqld12:35:46 33 1847 18.00 1.00 0.00 19.00 0 php-fpm12:35:46 33 1923 11.00 1.00 0.00 12.00 1 php-fpm
Cột %usr cao nghĩa là process đó đang thực thi code user space, %system cao nghĩa là nó đang gọi system calls nhiều.
Kiểm tra per-CPU breakdown
Nếu VPS có nhiều cores, xem load phân bố như thế nào:
mpstat -P ALL 1 3 # Hiển thị all CPUs, cập nhật 1s, lặp 3 lần
Output mẫu:
12:35:46 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle12:35:47 all 78.50 0.00 15.25 4.25 0.00 0.50 1.50 0.00 0.00 0.0012:35:47 0 95.00 0.00 3.00 2.00 0.00 0.00 0.00 0.00 0.00 0.0012:35:47 1 62.00 0.00 27.50 6.50 0.00 1.00 3.00 0.00 0.00 0.00
Nếu CPU 0 đạt 95% còn CPU 1 chỉ 62%, có thể ứng dụng chưa được tối ưu multi-threading.
Xử lý từng nguyên nhân cụ thể

MySQL queries nặng
MySQL thường là thủ phạm hàng đầu gây CPU cao. Cách kiểm tra:
# Xem queries đang chạymysql -u root -p -e "SHOW FULL PROCESSLIST;"
Output mẫu:
+----+------+-----------+--------+---------+------+-------+----------------------------+| Id | User | Host | db | Command | Time | State | Info |+----+------+-----------+--------+---------+------+-------+----------------------------+| 23 | web | localhost | shop | Query | 45 | exec | SELECT * FROM products ... || 24 | web | localhost | shop | Query | 38 | exec | SELECT COUNT(*) FROM ... |+----+------+-----------+--------+---------+------+-------+----------------------------+
Nếu thấy query nào chạy quá 30 giây, đó là dấu hiệu cần tối ưu.
Enable slow query log:
# Thêm vào /etc/mysql/mysql.conf.d/mysqld.cnf[mysqld]slow_query_log = 1slow_query_log_file = /var/log/mysql/mysql-slow.loglong_query_time = 2
Restart MySQL và xem log:
systemctl restart mysqltail -f /var/log/mysql/mysql-slow.log
Phân tích query:
EXPLAIN SELECT * FROM products WHERE category_id = 5 ORDER BY created_at DESC LIMIT 20;
Nếu thấy type: ALL (full table scan), cần tạo index:
CREATE INDEX idx_category_created ON products(category_id, created_at);
ℹ️ Chi tiết hơn xem bài MySQL chậm.
PHP-FPM workers quá nhiều
Khi nhiều process php-fpm xuất hiện trong top, thường do cấu hình không phù hợp:
# Kiểm tra status php-fpmcurl -s http://localhost/fpm-status
Output mẫu:
pool: wwwprocess manager: dynamicstart time: 24/Mar/2026:09:15:34 +0700start since: 12450accepted conn: 15678listen queue: 5max listen queue: 12listen queue len: 128idle processes: 2active processes: 28total processes: 30max active processes: 35max children reached: 15slow requests: 156
Nếu max children reached > 0, nghĩa là đã đạt giới hạn workers và có request phải chờ.
Điều chỉnh /etc/php/8.1/fpm/pool.d/www.conf:
; Với VPS 2GB RAM, 2 CPU corespm = dynamicpm.max_children = 20 ; Tối đa 20 workerspm.start_servers = 4 ; Khởi động với 4 workers pm.min_spare_servers = 2 ; Tối thiểu 2 workers rảnhpm.max_spare_servers = 6 ; Tối đa 6 workers rảnhpm.max_requests = 500 ; Restart worker sau 500 requests; Timeout cho request chậmrequest_terminate_timeout = 60s
ℹ️ Chi tiết tối ưu xem Tối ưu Nginx PHP-FPM.
Backup và cron jobs
Các job backup thường chạy vào giờ cao điểm gây CPU spike:
# Xem cron jobs của user hiện tạicrontab -l# Xem system cron jobscat /etc/crontabls -la /etc/cron.d/
Nếu thấy backup chạy lúc 2:00 AM mà đó là giờ peak traffic, hãy dịch chuyển:
# Sửa từ 2:00 AM thành 4:00 AM# Cũ: 0 2 * * * /backup/script.sh# Mới: 0 4 * * * /backup/script.shcrontab -e
Giảm priority cho backup:
# Thay vì: /backup/script.sh# Dùng: nice -n 19 ionice -c 3 /backup/script.shnice -n 19 ionice -c 3 rsync -av /var/www/ /backup/www/
nice -n 19: Priority CPU thấp nhấtionice -c 3: Idle I/O class (chỉ chạy khi disk rảnh)
Mã độc đào tiền ảo
Process lạ có tên ngẫu nhiên hoặc tiêu thụ CPU cao mà không rõ nguồn gốc:
# Tìm process nghi ngờps aux | grep -E "(xmrig|cpuminer|cryptonight)"# Process có tên ngẫu nhiênps aux | awk '{print $11}' | sort | uniq | grep -E "^[a-zA-Z0-9]{8,}$"# Network connection đáng ngờnetstat -tulpn | grep -v "127.0.0.1\|::1"
🚫 Cảnh báo: Nếu phát hiện malware, kill process ngay và scan toàn bộ hệ thống với ClamAV.
Nếu phát hiện malware:
- Kill process ngay:
kill -9 <PID> - Xóa file thực thi:
rm -f /path/to/suspicious/file - Kiểm tra startup scripts
- Scan toàn bộ hệ thống:
clamscan -r --infected --remove /
Giới hạn CPU của processes
Khi biết process nào gây vấn đề mà chưa thể tối ưu ngay, có thể giới hạn CPU tạm thời:
Dùng renice để thay đổi priority
# Giảm priority MySQL (PID 3429) từ 0 xuống 10renice 10 3429# Kiểm tra priority hiện tạips -o pid,ni,comm -p 3429
Priority từ -20 (cao nhất) đến 19 (thấp nhất). User thường chỉ có thể tăng priority (giảm hiệu suất), không thể giảm priority.
Giới hạn CPU với cpulimit
# Cài cpulimitapt install cpulimit# Giới hạn process PID 3429 chỉ dùng 50% CPUcpulimit -p 3429 -l 50 &# Giới hạn theo tên commandcpulimit -e mysql -l 60 &# Kiểm tra cpulimit đang chạyps aux | grep cpulimit
Dùng systemd cgroups
Đối với services chạy qua systemd, có thể giới hạn CPU trực tiếp:
# Tạo override file cho MySQLsystemctl edit mysql# Thêm vào file:[Service]CPUQuota=80%
Restart service:
systemctl daemon-reloadsystemctl restart mysql# Kiểm trasystemctl show mysql | grep CPU
Khi nào cần nâng cấp VPS
Sau khi thử tất cả các cách tối ưu mà vẫn thường xuyên gặp CPU cao, có thể VPS thật sự cần nâng cấp:
Dấu hiệu cần nâng cấp
- Load average liên tục > số CPU cores
- CPU idle time < 10% trong giờ cao điểm
- Response time website > 5 giây
- Không thể tối ưu thêm được code/database
Tính toán nhu cầu CPU
# Xem CPU usage trung bình trong 24hsar -u 1 86400 | tail -1
Output mẫu:
Average: CPU %user %nice %system %iowait %steal %idleAverage: all 78.45 0.12 15.23 3.45 0.67 2.08
Nếu %idle < 20% thường xuyên, nên cân nhắc nâng cấp.
Lựa chọn cấu hình
Với website WordPress 1000+ visitors/day:
- CPU: 4 cores
- RAM: 4GB+
- SSD: NVMe để giảm I/O wait
Với ứng dụng web có database lớn:
- CPU: 6-8 cores
- RAM: 8GB+
- SSD: NVMe với IOPS cao
Có thể bạn cần xem thêm
- Tổng hợp lỗi hiệu năng VPS phổ biến và cách khắc phục từ A-Z
- Tối ưu Nginx và PHP-FPM cho VPS hiệu năng cao
- Load Average cao trên Linux Server: Chẩn đoán và xử lý
- MySQL chậm trên VPS: Cách tìm và tối ưu slow query
- WordPress trên VPS chạy chậm: Hướng dẫn tối ưu toàn diện
- VPS bị chậm do mạng: Cách kiểm tra và khắc phục
Về tác giả
Trần Thắng
Chuyên gia tại AZDIGI với nhiều năm kinh nghiệm trong lĩnh vực web hosting và quản trị hệ thống.