# Hiệu năng và sức chứa

> Cách ZoPanel chạy hàng trăm website trên một VPS nhỏ: phân bổ RAM, PHP ngủ khi rảnh, page cache, nén bộ nhớ và giảm tải khi quá tải.

Source: https://zopanel.net/vi/docs/performance  
Updated: 2026-10-07

ZoPanel được thiết kế để chạy nhiều website trên một server nhỏ. Panel tự điều chỉnh theo cấu hình máy, dừng PHP của website vắng khách, cache trang, nén bộ nhớ rảnh và bảo vệ server khi thiếu RAM. Trang này giải thích từng cơ chế và sức chứa đã đo được.

## Phân bổ RAM

ZoPanel chia RAM thành hai phần:

- **phần dự trữ cho hệ thống**: MariaDB, mail, nginx, panel và kernel;
- **giới hạn cho khách**: mọi thứ khách chạy, gồm pool PHP, ứng dụng, shell và app Docker.

Giới hạn cho khách là giới hạn cứng. Khi một đợt truy cập dồn dập đánh thức hàng trăm website cùng lúc, tiến trình của khách bị làm chậm lại. Trường hợp xấu nhất, một số tiến trình bị dừng, nhưng chỉ trong phạm vi giới hạn này. PHP worker bị dừng trước và tự chạy lại ngay. SSH, panel, nginx và database vẫn giữ phần RAM của mình, nên bạn luôn đăng nhập được để xử lý.

Phần dự trữ lấy giá trị lớn hơn trong hai mức:

- **mức sàn cố định**: một phần ba RAM, tối thiểu 1 GB nhưng không quá 1 GB + 8% RAM, cộng thêm khoảng 0,75 MB cho mỗi tài khoản;
- **mức dùng thực tế**: mức hệ thống dùng cao nhất trong ngày qua, cộng 256 MB và 3% RAM.

Phần dự trữ không bao giờ vượt quá một nửa RAM. ZoPanel tính lại mỗi 10 phút. Khi cần giảm phần dự trữ, panel giảm ngay. Khi cần tăng, mỗi bước chỉ tăng tối đa 512 MB, để tiến trình của khách không bị dừng đột ngột.

Mức phân bổ hiện tại hiển thị ở **Cài đặt → Hệ thống → Hiệu năng PHP**.

Bộ cài cũng đặt buffer pool của MariaDB bằng 20% RAM. Trên server dưới 4 GB RAM và chưa có swap, bộ cài tạo một file swap từ 1 đến 4 GB.

## PHP ngủ khi rảnh

Mỗi tài khoản chạy pool PHP-FPM riêng. Tiến trình master của một pool tốn khoảng 25 MB kể cả khi không có ai truy cập. Với hàng trăm tài khoản vắng khách, con số này lên tới vài GB RAM bị lãng phí. Vì vậy ZoPanel dừng các pool rảnh:

1. PHP worker tự thoát 10 giây sau request cuối cùng.
2. Pool không còn worker nào trong suốt thời gian rảnh sẽ bị dừng. Thời gian rảnh mặc định là **30 phút**.
3. Lượt truy cập tiếp theo khởi động lại pool qua socket của nó (systemd socket activation). Việc này mất vài trăm mili giây và không làm mất request nào.

Đổi thời gian rảnh tại **Cài đặt → Hệ thống → Hiệu năng PHP → Dừng PHP rảnh sau**. Có thể chọn 5, 15, 30 (khuyên dùng), 60 hoặc 180 phút, hoặc **Không bao giờ (luôn chạy)**. Xem chi tiết ở [Hiệu năng PHP](/vi/docs/php-performance). Cùng thẻ này hiển thị số pool đang chạy, RAM PHP đang dùng và dung lượng bộ đệm mã biên dịch.

Khi thiếu RAM, pool rảnh bị dừng ngay, pool rảnh lâu nhất trước, mỗi lượt kiểm tra 20 pool, cho tới khi RAM ổn định lại. Pool đang phục vụ request không bao giờ bị dừng.

Với gói cao cấp, bật **PHP luôn chạy** trong gói hosting. PHP của các website này không bao giờ ngủ và được khởi động cùng server. Đổi lại, mỗi website tốn khoảng 20–60 MB RAM.

### Bộ đệm OPcache trên đĩa

Khi một pool đang ngủ được khởi động lại, PHP nạp mã đã biên dịch từ đĩa thay vì biên dịch lại. Nhờ vậy lượt truy cập đầu tiên gần nhanh bằng khi pool đang chạy. Mỗi tài khoản có thư mục cache riêng trong `/var/cache/zopanel/opcache/`. Script không được nạp trong 30 ngày sẽ bị xoá.

## Page cache

Page cache phục vụ trang từ cache của nginx, nên phần lớn khách truy cập không cần tới PHP và MariaDB. Đây là cách tăng tốc WordPress hiệu quả nhất.

Có hai cách bật page cache:

- bật cho từng website tại **Website → (website) → PHP & cấu hình → Page cache**;
- bấm **Áp dụng** ở trang **Tối ưu** để bật cho mọi website WordPress chưa có cache.

Cách page cache hoạt động:

- Người đã đăng nhập, trang quản trị, giỏ hàng, thanh toán và request POST luôn bỏ qua cache.
- Trang được cache trong 10 phút. Trang hết hạn vẫn được trả về ngay, trong khi một request cập nhật lại nó ở chế độ nền. Trang không được dùng trong một ngày sẽ bị loại khỏi cache.
- Website WordPress được cài một plugin must-use nhỏ. Plugin này xoá cache khi nội dung thay đổi (bài viết, bình luận, menu, theme, plugin), nên chỉnh sửa hiển thị ngay.
- **Xoá cache** làm trống cache của website bằng tay. Response có header `X-Cache` (`HIT`, `MISS`, …).

Với wp-admin, WooCommerce và người đã đăng nhập, dùng thêm **Redis object cache** trong cùng tab. Redis object cache lưu kết quả truy vấn database trong một Redis riêng của từng tài khoản.

## Nén bộ nhớ

Với Linux 6.8 trở lên, ZoPanel nén bộ nhớ rảnh của khách ngay trong RAM bằng zswap. Bộ nhớ rảnh gồm PHP master, OPcache và ứng dụng đang ngủ.

- Trang bộ nhớ của khách **không bao giờ bị ghi ra đĩa**. Trang không nén vừa thì tiếp tục nằm trong RAM.
- Tỷ lệ nén đo được khoảng **3,8–3,9 : 1**. Trang **Tối ưu** hiển thị tỷ lệ hiện tại.
- zswap cần có thiết bị swap, nhưng bộ nhớ của khách không bao giờ bị ghi vào đó. Nếu không có swap, tính năng nén không bật.

| Hệ điều hành | Kernel | Cần làm gì |
| --- | --- | --- |
| Ubuntu 24.04, Debian 13 | 6.8 trở lên | Không cần làm gì |
| Ubuntu 22.04 | 5.15 | Bộ cài mặc định thêm kernel HWE của Ubuntu |
| Debian 12 | 6.1 | Bộ cài sẽ hỏi; thêm `--kernel-backports` để cài kernel backports 6.12 mà không cần hỏi |

Với server đã cài xong, dùng lệnh mà trang **Tối ưu** gợi ý, rồi khởi động lại:

```bash
# Ubuntu 22.04
apt install --install-recommends linux-generic-hwe-22.04 && reboot

# Debian 12
echo 'deb http://deb.debian.org/debian bookworm-backports main' > /etc/apt/sources.list.d/backports.list
apt update && apt install -t bookworm-backports linux-image-amd64 && reboot
```

Trên Debian ARM64, cài `linux-image-arm64` thay cho `linux-image-amd64`. Nếu server chưa có swap, thêm swap bằng nút **Áp dụng** trên trang **Tối ưu**.

## Giảm tải khi quá tải

Khi server quá tải nặng, PHP có thể dồn hàng trăm request trong hàng đợi, dù người truy cập đã bỏ đi từ lâu. Nếu xử lý hết số request này, các pool tiếp tục chạy và server thiếu RAM rất lâu sau khi lượng truy cập đã giảm.

ZoPanel chỉ giảm tải trong tình huống thật sự khẩn cấp. Điều kiện là RAM của khách gần chạm giới hạn, hoặc tiến trình của khách phải chờ RAM 70% thời gian, kéo dài ít nhất một phút. Khi đó, nếu hàng đợi của một pool đầy liên tục 30 giây, các request đang chờ bị huỷ. Mỗi pool bị huỷ hàng đợi tối đa một lần mỗi phút.

Trong lúc quá tải, website PHP hoặc ứng dụng hiển thị **trang "đang bận, vui lòng thử lại"**. Trang này trả về HTTP 503 kèm `Retry-After: 30`, nên công cụ tìm kiếm coi đây là lỗi tạm thời. Nếu website có trang lỗi 502/503/504 riêng, trang riêng đó được dùng.

## Sức chứa đã đo

Kết quả trên server thử nghiệm. Ngoài các website WordPress, mỗi server chạy thêm 30 ứng dụng: 10 Node.js + MariaDB, 5 Flask + PostgreSQL, và 15 website Joomla, phpBB hoặc OpenCart.

| Server | WordPress không page cache | WordPress có page cache |
| --- | --- | --- |
| Ubuntu 24.04, 4 GB RAM, 4 vCPU | 100 website + 30 ứng dụng | 250 website + 30 ứng dụng |
| Debian 12, 3 GB RAM, 4 vCPU (profile full) | 50 website + 30 ứng dụng | 200 website + 30 ứng dụng |

Sau 8 phút quá tải nặng, server trở lại bình thường sau **5 phút** (Ubuntu) và **2 phút** (Debian) kể từ khi tải dừng. Kết quả thực tế phụ thuộc vào website, plugin và lượng truy cập của bạn.

## Mẹo tối ưu

1. **Bật page cache** cho mọi website WordPress không cần nội dung động cho khách truy cập. Đây là thay đổi tăng sức chứa nhiều nhất.
2. **Dùng kernel 6.8 trở lên** để bật được tính năng nén bộ nhớ.
3. **Giữ thời gian rảnh mặc định** (30 phút). Giảm xuống nếu server đông tài khoản. Chỉ dùng **PHP luôn chạy** cho gói cao cấp.
4. **Đặt giới hạn gói hợp lý.** Trang Tối ưu cảnh báo khi tổng số PHP worker được phép không vừa RAM. Khi đó hãy giảm **Số PHP worker** trong gói hosting hoặc nâng RAM.
5. **Làm theo trang Tối ưu.** Áp dụng gợi ý cho buffer MariaDB, swap và nginx worker, và theo dõi dự báo dung lượng đĩa.
6. **Dùng Redis object cache** cho website WooCommerce và website thành viên, vì nhiều trang của chúng bỏ qua page cache.
7. **Bật giới hạn tốc độ request** cho website bị bot truy cập nhiều (**PHP & cấu hình → Giới hạn tốc độ request**).
