Chạy WordPress Trên VPS 1GB RAM Không Bị Sập — Tuning Thật Từ A-Z
1. Chuyện thường ngày ở VPS 1GB
Bạn mua con VPS NAT 47K/tháng, cài WordPress lên, vài hôm đầu ngon lắm. Rồi cài thêm WooCommerce, thêm vài plugin page builder, tối ưu ảnh… Bỗng một ngày web báo lỗi "Error establishing a database connection". Vào kiểm tra thấy MySQL/MariaDB không chạy, log kernel ghi mariadbd invoked oom-killer. Server hết RAM, kernel đâm thẳng vào database — DB chết, web sập.
Chuyện này xảy ra với rất nhiều người. Không phải VPS yếu, mà là vì **cấu hình mặc định trên server Linux được thiết kế cho máy có nhiều RAM**. MariaDB mặc định xin buffer pool tới 128MB, PHP-FPM không giới hạn worker, mỗi request WordPress cơ bản ngốn 40-60MB — chỉ cần 3-4 request đồng thời là thổi bay 1GB RAM.
Bài này tôi sẽ chỉ bạn cách tính toán chính xác con số cho từng thành phần trên VPS 1GB, dựa trên số liệu thực tế (không phải ước lượng), và kể mấy cái gotcha mà mấy bài generic hay bỏ qua.
2. VPS 1GB RAM có những "con mồi" ngốn RAM nào?
Trên một VPS 1GB chạy Nginx + PHP-FPM + MariaDB + WordPress, RAM phân bố như sau:
| Thành phần | RAM thường dùng (idle) | RAM lúc có khách | Ghi chú |
|---|---|---|---|
| Hệ điều hành (Ubuntu 22.04/24.04 LTS) | ~200-300MB | ~300-400MB | service nền: systemd, sshd, cron, fail2ban... |
| Nginx | ~10-30MB | ~40-80MB | vài worker process |
| MariaDB/MySQL | ~150-300MB | ~300-500MB+ | innodb_buffer_pool_size + per-connection buffers |
| PHP-FPM (1 worker) | ~40-60MB | ~60-150MB | tùy plugin — trang càng nhiều plugin càng nặng |
| Redis / object cache (tùy chọn) | ~20-50MB | ~50-100MB | nên có nếu VPS còn RAM |
Điểm mấu chốt: với 1GB RAM, bạn chỉ có khoảng 400-500MB dành cho PHP worker và database spike sau khi trừ OS + Nginx. Sai một li là OOM đi một dặm.
3. "Con mồi" số 1: MariaDB và cái bẫy innodb_buffer_pool_size
Có một câu chuyện thật từ một dev kia (blog.haicon.moe). Client của anh ấy có vài WordPress chạy Docker trên Google Cloud, thỉnh thoảng server tự dưng không SSH được, web time out. Metric CPU + RAM nhìn bình thường, chỉ thấy disk throughput đột biến. Debug cả tháng trời, cuối cùng mở syslog ra thấy:
kernel: [ 8085.099452] mariadbd invoked oom-killer ...
kernel: [ 8085.099691] oom_kill_process+0x116/0x270
Kernel đã **giết MariaDB** vì OOM. Nhưng sao RAM chỉ 50% mà OOM? Hóa ra innodb_buffer_pool_size chỉ vỏn vẹn 128MB — quá nhỏ. MariaDB phải liên tục đọc từ đĩa, gây burst I/O + cấp phát đột biến per-connection buffers, đủ để trigger OOM killer dù RAM tổng còn. Bạn có thể đọc bài gốc để rõ hơn.
Với VPS 1GB RAM, việc buffer pool quá nhỏ cũng gây ra hiệu ứng tương tự — nhất là khi site có traffic. Công thức an toàn cho MariaDB trên 1GB:
- innodb_buffer_pool_size = 128MB — 256MB (12-25% tổng RAM). 128MB nếu bạn cũng dùng Redis + nhiều PHP worker; 256MB nếu site có nhiều dữ liệu cần cache. Không nên vượt quá 300MB vì không còn RAM cho PHP.
- Bật innodb_buffer_pool_instances = 2 (giảm contention trên buffer pool).
- Giới hạn per-connection buffers:
sort_buffer_size = 256K,join_buffer_size = 256K,tmp_table_size = 32M,max_connections = 30.
[mysqld]
# Với VPS 1GB RAM
innodb_buffer_pool_size = 256M
innodb_buffer_pool_instances = 2
sort_buffer_size = 256K
join_buffer_size = 256K
tmp_table_size = 32M
max_connections = 30
key_buffer_size = 16M
query_cache_type = OFF # deprecated từ MySQL 8 / MariaDB 10.10+
sort_buffer_size nhân với max_connections. Nếu bạn set sort_buffer=2M và max_connections=150, đó là 300MB có thể bị lock ngay khi có burst kết nối, dù bình thường không dùng hết. Đây chính là lý do OOM xuất hiện không báo trước — không phải RAM đầy mà là một lần cấp phát đột biến vượt quá giới hạn. Luôn để per-connection buffers ở mức tối thiểu trên VPS RAM thấp.
4. "Con mồi" số 2: PHP-FPM worker và bài toán pm.max_children
Đây là thứ quan trọng nhất nhưng ít người tính đúng. Công thức tham khảo từ bài PHP-FPM tuning cho WordPress (tweakswp.com):
pm.max_children = RAM khả dụng / RAM trung bình mỗi PHP-FPM worker
Trong đó:
- RAM khả dụng = tổng RAM - OS overhead - MariaDB - Redis - services khác.
- RAM mỗi worker = con số bạn PHẢI đo thực tế.
Cách đo RAM mỗi PHP-FPM worker trên server của bạn:
# Tính RAM trung bình của tất cả các php-fpm worker
ps --no-headers -o rss,comm -C php-fpm | awk '{sum+=$1; cnt++} END {if (cnt>0) printf "%.0f MB/worker (tổng %d workers)\n", sum/cnt/1024, cnt}'
Với VPS 1GB, giả sử:
- OS + Nginx + MariaDB + Redis đã ngốn ~500-600MB
- Còn lại ~400-500MB cho PHP
- Đo được mỗi worker ~50MB (WordPress khiêm tốn, ít plugin)
- → pm.max_children = 400 / 50 = 8 (làm tròn xuống 6-7 để có headroom)
| Loại site | RAM/worker (ước lượng) | max_children (1GB VPS) |
|---|---|---|
| WordPress cơ bản + 5-7 plugin nhẹ | ~40-60MB | 6-8 |
| WordPress + Elementor + WooCommerce | ~80-120MB | 3-5 |
| WordPress + page builder + bảo mật + backup plugin | ~100-150MB | 2-3 |
pm = dynamic
pm.max_children = 6
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 500
request_terminate_timeout = 60
pm.max_requests = 500 giúp dọn dẹp memory leak (PHP và plugin đều bị rò rỉ qua thời gian). Quá trình recycle mất ~50-100ms — chấp nhận được. request_terminate_timeout = 60s giết các worker bị treo (infinite loop, HTTP call chậm...), giải phóng worker cho request khác.
5. Swap — nên hay không? Nên, nhưng phải biết cách
Nhiều người bảo "VPS RAM thấp thì tắt swap cho đỡ chậm I/O". Điều đó sai với WordPress. Swap trên VPS 1GB không phải để dùng thường xuyên, mà là phao cứu sinh cho những lần burst RAM bất ngờ — kiểu 10 request cùng lúc, MariaDB spike, hay cron plugin chạy background.
Không có swap, khi RAM hết kernel OOM killer sẽ giết process ngay — thường là MariaDB hoặc PHP-FPM. Có swap, kernel chỉ đẩy ít trang ít dùng xuống swap, không tới nỗi giết ai. Tất nhiên swap chậm như rùa (vài MB/s so với vài GB/s của RAM), nhưng chậm còn hơn sập.
# Tạo swap 1GB (nên bằng hoặc gấp đôi RAM với VPS RAM thấp)
fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
# Bật swappiness thấp — chỉ dùng swap khi thực sự cần thiết
echo 'vm.swappiness=10' >> /etc/sysctl.conf
sysctl -p
# Cho swap vào /etc/fstab để tự động bật sau reboot
echo '/swapfile none swap sw 0 0' >> /etc/fstab
swappiness=10 (mặc định 60) có nghĩa kernel sẽ ưu tiên dùng RAM tới 90% trước khi động vào swap. Swap chỉ là lưới an toàn, không phải RAM phụ.
si và so trong vmstat 1 luôn > 0), swap đang gánh quá nhiều — lúc đó bạn cần giảm tải (tắt bớt plugin) hoặc nâng lên VPS có nhiều RAM hơn, chứ không phải lỗi cấu hình.
6. Redis object cache — có đáng không trên 1GB?
Có, nếu bạn còn ~50-100MB. Redis cache query database, giảm tải MariaDB đáng kể. Một con Redis object cache cho WordPress chỉ dùng 10-30MB cho cache cơ bản. Giảm truy vấn DB đồng nghĩa với giảm spike RAM từ MariaDB — gián tiếp bảo vệ nguyên nhân OOM số 1.
# Cài Redis
apt install redis-server
# Cấu hình Redis — giới hạn RAM dùng cho cache
# Sửa /etc/redis/redis.conf:
maxmemory 50mb
maxmemory-policy allkeys-lru
# Cài plugin Redis Object Cache trong WordPress rồi bật
7. Lên dây cót: tóm tắt cấu hình cho VPS 1GB
Dưới đây là checklist những thứ cần làm ngay sau khi cài WordPress lên VPS 1GB:
- Đo RAM từng tiến trình trước khi tuning. Copy lệnh PHP-FPM ở mục 4 và chạy.
- Cấu hình MariaDB — set buffer pool 128-256M, giới hạn per-connection buffers, max_connections = 20-30.
- Cấu hình PHP-FPM — dùng công thức max_children, set pm.max_requests, request_terminate_timeout.
- Tạo swap 1GB + swappiness=10.
- Cài Redis (nếu còn RAM) + giới hạn 50MB.
- Cài OPcache (đã mặc định trong PHP 8.x — kiểm tra
opcache.memory_consumption=128trong php.ini). - Tối giản plugin — mỗi plugin tưởng nhẹ vài MB nhưng nhân lên 10 cái là hết RAM. Đặc biệt tránh mấy plugin "all-in-one" vì chúng load code cho mọi page, không chỉ trang bạn cần.
- Giám sát —
htop+vmstat 1+ check kernel log (dmesg | grep -i oom) sau mỗi lần thay đổi cấu hình để kịp phát hiện OOM sắp xảy ra. Xem thêm bài Cài Netdata Monitoring Trên VPS.
8. Có nên dùng OpenLiteSpeed thay Nginx để tiết kiệm RAM?
Có một số nguồn cho thấy OpenLiteSpeed dùng LSAPI thay PHP-FPM, giúp giảm RAM PHP mỗi request (vì PHP process được tái sử dụng hiệu quả hơn) và thời gian response nhanh hơn Nginx + PHP-FPM 15-40% TTFB trên WordPress (theo một benchmark từ bullenweg.com). Tuy nhiên con số chênh lệch RAM cụ thể khó xác định, và Nginx + PHP-FPM nếu được tuning đúng cách vẫn chạy ổn trên 1GB. Nếu bạn đã quen Nginx thì không cần chuyển — tuning đúng còn quan trọng hơn chọn web server. Nếu muốn tìm hiểu thêm về Nginx, xem bài Cài Nginx Reverse Proxy Trên VPS.
9. Câu chuyện OOM killer không phải chuyện đùa
Tôi kể lại câu chuyện thật từ blog.haicon.moe cho thấy ngay cả VM 2GB trên Google Cloud cũng bị OOM giết MariaDB nếu buffer pool sai — chứ đừng nói VPS 1GB. Cái sai phổ biến là nghĩ "cấu hình mặc định là ổn" và "còn 50% RAM là an toàn". Sự thật là OOM killer chỉ cần một lần cấp phát đột biến vượt ngưỡng là ra tay, bất kể RAM tổng còn bao nhiêu. Với VPS 1GB, không có chỗ cho sai số — mỗi MB đều phải được phân bổ có chủ đích. Đọc thêm bài Bảo Mật VPS Cho Người Mới để biết cách bảo vệ server sau khi tuning.
🖥️ Cần VPS 1GB Giá Rẻ Để Chạy WordPress?
VPS NAT từ 47K/tháng hoặc VPS Cloud IP riêng từ 130K/tháng tại TrumVPS — cài sẵn aaPanel, hỗ trợ 24/7, đủ sức chạy WordPress ngon lành nếu tuning đúng
Thuê VPS WordPress Ngay