127.0.0.1 SỔ TAY VẬN HÀNH MÁY CHỦ & CỨU HỘ WORDPRESS THỰC CHIẾN
MINH BẠCH

Đo TTFB, thời gian tải trang và tài nguyên VPS trước khi tối ưu: Khám bệnh trước, bốc thuốc sau!

Đừng vội cài chục plugin cache khi chưa đo Baseline! Hướng dẫn đo TTFB bằng curl, đọc DevTools Waterfall, LCP và ghi nhận tài nguyên PHP-FPM/MariaDB.

Tối ưu VPS // localhost.vn
Mục lục bài viết (12 mục)
ĐÚC KẾT THỰC CHIẾN

Tối ưu tốc độ WordPress mà không đo Baseline trước thì chẳng khác nào nhắm mắt bốc thuốc! Hãy dùng curl tách lớp kết nối, đọc DevTools Waterfall/LCP và soi tài nguyên máy chủ trong cùng điều kiện trước khi đụng vào bất kỳ cấu hình nào.

Trong thế giới quản trị WordPress, có một căn bệnh rất phổ biến mang tên “tối ưu theo tâm linh”: hễ thấy trang web hơi chậm là lập tức cài liền ba bốn plugin dọn dẹp, bật đủ thứ cờ nén code hoặc copy-paste một đoạn cấu hình sysctl hầm hố trên mạng về dán vào VPS, rồi tự gật gù khen web nhanh hơn hẳn! Thực tế, cảm giác “hình như nhanh hơn” của con người là thước đo kém tin cậy nhất. Chỉ số TTFB (Time to First Byte) cho chúng ta biết chính xác khoảng thời gian tính từ lúc bắt đầu gửi yêu cầu cho tới khi trình khách nhận được byte dữ liệu phản hồi đầu tiên từ máy chủ. Đo đạc chỉ số này trước khi chạm tay vào tối ưu giúp bạn biết chắc mình đang cải thiện khâu nào; đồng thời hãy nhớ rằng sau khi byte đầu tiên về tới nơi, trình duyệt vẫn còn phải hì hục tải ảnh, phân tích CSS, chạy JavaScript và vẽ giao diện (render), nên TTFB thấp chưa bao giờ là tấm vé bảo đảm trang web hiển thị nhanh tức thì trước mắt người đọc.

Bạn hoàn toàn có thể tự tay thực hiện lại toàn bộ quy trình đo đạc chuẩn chỉnh trong bài viết này trên môi trường Lab của mình. Bộ dữ liệu thực chứng đi kèm bài viết bao gồm 10 mẫu đo bằng curl, ảnh chụp trực tiếp bảng Chrome DevTools và một cửa sổ quan sát thông số PHP-FPM / MariaDB thực tế trên máy chủ LAB-CF-02 vào ngày 01/10/2026. Lưu ý rằng mỗi phiên đo dưới đây được thực hiện ở những mốc thời gian và điều kiện độc lập nhằm minh họa từng kỹ thuật đo, do đó không đem ghép râu ông nọ cắm cằm bà kia thành bảng so sánh trước/sau hay suy diễn thành tổng số khách truy cập đồng thời mà VPS chịu được. Khi đọc bất kỳ con số tốc độ nào, nguyên tắc đầu tiên luôn là đối chiếu kỹ bộ ba: đường dẫn URL, vị trí máy đo và trạng thái bộ nhớ đệm (Cache).

Chuẩn bị môi trường Lab trước khi bấm đồng hồ đo

Để thực hành trọn vẹn quy trình thu thập số liệu này, bạn cần nắm quyền quản trị trên một máy chủ Lab riêng biệt và đã hoàn thành lộ trình cài đặt và vận hành WordPress trên VPS từ A đến Z. Môi trường chuẩn trong bài sử dụng hệ điều hành Ubuntu 24.04 LTS, Nginx, PHP 8.3 và MariaDB 10.11. Trước khi gõ lệnh vào cửa sổ terminal, hãy kiểm tra lại phiên bản phần mềm, tên dịch vụ (service) và đường dẫn thực tế trên máy chủ của bạn, vì cấu hình cụ thể của từng máy sẽ ảnh hưởng trực tiếp tới số liệu đầu ra.

Khi chọn mục tiêu đo đạc, hãy dùng một bài viết hoặc trang tĩnh trên môi trường Lab được phép truy cập công khai, tuyệt đối không gắn dữ liệu nhạy cảm của khách hàng hay chuỗi khóa xác thực (token) vào trong URL đem đi đo. Toàn bộ các phiên đo bằng curl và DevTools dưới đây đều đóng vai trò là khách truy cập chưa đăng nhập (anonymous guest); phần quan sát tài nguyên bên trong máy chủ sử dụng tài khoản quản trị Lab sẵn có mà không cần tạo thêm người dùng mới. Các biến môi trường viết hoa trong câu lệnh là giá trị bạn cần gán theo đúng địa chỉ Lab của mình; nhớ đừng lưu mật khẩu hay thông tin đăng nhập vào tài liệu chung, lịch sử dòng lệnh (shell history) hay kho mã nguồn. Nếu máy báo thiếu công cụ (command not found), hãy cài đặt theo hướng dẫn chính thức của hệ điều hành và kiểm tra phiên bản trước khi chạy — thiếu công cụ đo ở máy trạm không phải là lỗi của website. Các sơ đồ trong bài được thiết kế để hệ thống hóa phương pháp luận đo đạc, đóng vai trò dẫn đường bên cạnh các ảnh chụp thực nghiệm.

Bốn điều kiện cần cố định khi đo tốc độ: URL không đổi; Vị trí và đường truyền mạng; Trạng thái Cache cold hay warm; Phiên khách hay đã đăng nhập

Sơ đồ tư duy 1: Bốn biến số bắt buộc phải khóa cố định trước khi bấm giờ đo Baseline. Sơ đồ phương pháp luận do đội ngũ localhost.vn biên soạn.

Bước 1: Đặt đúng câu hỏi và khóa chặt các biến số môi trường

Muốn phép so sánh tốc độ trước và sau khi tối ưu có giá trị khoa học, bạn phải giữ nguyên hiện trường như trong phòng thí nghiệm: hãy chọn cố định một đường dẫn bài viết HTML và một đường dẫn tệp ảnh tĩnh trên Lab có nội dung hoàn toàn không thay đổi. Hãy mở sổ nhật ký ra ghi rõ: mốc thời gian theo chuẩn UTC, vị trí địa lý và nhà mạng của máy tính đang ngồi đo, phiên bản công cụ curl hoặc trình duyệt, trạng thái đăng nhập và việc lưu lượng có đang đi vòng qua lớp CDN hay không. Đặc biệt, hãy luôn tách biệt rạch ròi giữa phiên đo của khách ẩn danh (Incognito) với phiên đo của quản trị viên đã đăng nhập: chỉ cần trình duyệt gửi kèm cookie đăng nhập kiểu wordpress_logged_in_*, máy chủ sẽ lập tức bỏ qua lớp đệm tĩnh (Bypass Page Cache) và bắt PHP phải cày cuốc lại từ đầu!

Trước khi gõ lệnh, hãy thống nhất trước kích thước mẫu (sample size) và quy tắc tính toán báo cáo. Chẳng hạn, thay vì chỉ bấm đo duy nhất 1 lần rồi lấy con số đó đi khoe, bạn hãy chạy 5 lệnh GET tuần tự, mỗi lệnh cách nhau đúng 2 giây trong cùng một điều kiện môi trường. Lưu ý rằng 5 mẫu tuần tự này là phép đo lấy mốc chuẩn (Baseline) chứ hoàn toàn không phải bài kiểm tra chịu tải (Load Test). Một lỗi sơ đẳng mà rất nhiều người mắc phải là: lần bấm đầu tiên trúng lúc bộ nhớ đệm còn lạnh (Cache Cold / MISS) mất tới 500ms, 4 lần bấm sau trúng bộ nhớ đệm đã nóng (Cache Warm / HIT) chỉ mất 20ms, thế là đem cộng cả 5 lần lại chia trung bình rồi kết luận tốc độ trang web là 116ms! Hãy luôn tách riêng hoặc gắn nhãn rõ ràng cho trạng thái Cold và Warm.

Bước 2: Dùng công cụ curl để bóc tách từng mốc thời gian tích lũy

Trước khi chạy lệnh đo, hãy kiểm tra kỹ để chắc chắn bạn đang gõ đúng địa chỉ HTTPS của trang Lab. Hãy giữ nguyên cơ chế xác thực chứng chỉ bảo mật TLS/SSL mặc định của công cụ; nếu máy báo lỗi chứng chỉ hết hạn hoặc sai tên miền, việc bạn cần làm là sửa lại chứng chỉ cho chuẩn chứ tuyệt đối không thêm cờ -k (--insecure) để nhắm mắt bỏ qua lỗi bảo mật.

(
  set -eu
  : "${LAB_URL:?Đặt URL HTTPS cuối cùng của lab được phép}"
  case "$LAB_URL" in
    https://*) ;;
    *) printf '%s\n' 'LAB_URL phải dùng HTTPS.' >&2; exit 1 ;;
  esac
  curl --version
  METRICS=$(curl --fail --silent --show-error \
    --connect-timeout 10 --max-time 15 --output /dev/null \
    --write-out 'code=%{http_code} dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total} bytes=%{size_download}' \
    "$LAB_URL")
  printf '%s\n' "$METRICS"
  case "$METRICS" in
    'code=200 '*) ;;
    *) printf '%s\n' 'Status chưa phải 200; kiểm URL trước khi đo tiếp.' >&2; exit 1 ;;
  esac
)

Đoạn script trên được bọc trong một tiến trình con (subshell) để nếu địa chỉ URL gõ sai định dạng, lệnh curl gặp sự cố mạng hoặc máy chủ trả về mã trạng thái khác HTTP 200 thì kịch bản sẽ dừng lại ngay lập tức mà không làm văng cửa sổ terminal của bạn. Mẫu lệnh này đã được rà soát kỹ cú pháp an toàn để bạn sử dụng (lưu ý đây là mẫu lệnh chuẩn hóa cho sổ tay thực hành, còn 10 mẫu số liệu lịch sử ở phần cuối bài được thu thập ở phiên chạy thực nghiệm trước đó). Ngoài ra, vì câu lệnh đã chủ động đẩy phần nội dung trả về (response body) vào /dev/null để lấy thông số thời gian gọn gàng, bạn nhớ phải mở kiểm tra trước để chắc chắn đường dẫn đó đang hiển thị đúng nội dung bài viết chứ không phải một trang báo lỗi nhẹ tênh trả mã 200.

Khi đọc các con số do curl xuất ra, hãy khắc cốt ghi tâm quy tắc này: mọi mốc thời gian từ time_namelookup, time_connect, time_appconnect, time_starttransfer (chính là TTFB) cho tới time_total đều là thời gian tích lũy tính bằng giây kể từ thời điểm số 0 lúc bắt đầu khởi tạo yêu cầu — tuyệt đối không đem cộng dồn các con số này lại với nhau! Bản thân con số TTFB đã bao hàm cả thời gian phân giải tên miền DNS Lookup, bắt tay TCP Connect và thương thảo mã hóa SSL/TLS Handshake cộng với độ trễ đường truyền mạng, do đó TTFB không bao giờ bằng thời gian xử lý thuần túy của PHP trên máy chủ. Mẫu lệnh trên cũng chủ động không tự nhảy theo các bước chuyển hướng (redirect): nếu bạn gặp mã HTTP 301 hoặc 302, hãy ghi nhận lại đường dẫn chuẩn (Canonical URL) rồi đo trực tiếp trên URL đích đó, hoặc tách riêng bài toán đo độ trễ của chuỗi chuyển hướng.

Ba tầng thời gian cần phân biệt: curl đo tới byte đầu tiên; Network tải toàn bộ tài nguyên; Trình duyệt kết xuất LCP; Máy chủ xử lý trong cùng khung giờ

Sơ đồ tư duy 2: Phân biệt rạch ròi 3 lớp thời gian từ dòng lệnh curl, thác nước tải tài nguyên cho tới lúc mắt người nhìn thấy nội dung chính (LCP). Sơ đồ do đội ngũ localhost.vn biên soạn.

Bước 3: Đo lường trải nghiệm tải trang thực tế bằng Chrome DevTools

  1. Mở sẵn bảng công cụ nhà phát triển DevTools và chuyển sang thẻ Network trước khi bấm tải lại trang (Reload), đồng thời bấm nút xóa sạch các dòng nhật ký cũ. Nếu bạn muốn quan sát cả chuỗi chuyển hướng (redirect), hãy tích chọn ô Preserve log (hoặc Keep log) và ghi chú rõ vào biên bản; nhớ giữ cố định cấu hình Disable cache và chế độ giả lập băng thông (Throttling) xuyên suốt giữa các lần bấm đo.
  2. Chọn bộ lọc All để nhìn toàn cảnh; đọc kỹ các cột Name, Status, Type, Initiator, Size, Time và Waterfall. Nếu trên màn hình chưa thấy cột biểu đồ thác nước Waterfall, bạn chỉ cần nhấp chuột phải vào thanh tiêu đề cột rồi tích chọn Waterfall. Cột Initiator sẽ chỉ điểm cho bạn biết chính xác đoạn mã nào đã đứng sau gọi tệp tài nguyên đó; còn biểu đồ thanh ngang Waterfall sẽ xếp các yêu cầu lên cùng một trục thời gian trực quan. Tuyệt đối không lấy con số ở cột Time của hàng chục tệp tải song song đem cộng dồn lại thành tổng thời gian tải trang!
  3. Nhấp chuột vào dòng tài liệu Document đầu tiên rồi chuyển sang thẻ con Timing. Tại đây, hãy tách bạch rõ nhóm thời gian thiết lập kết nối (DNS Lookup / Initial connection / SSL), thời gian chờ phản hồi Waiting (TTFB) và thời gian tải nội dung Content Download. Hãy nhớ rằng thanh Waiting (TTFB) bao gồm cả thời gian gói tin đi trên đường cáp quang lẫn thời gian máy chủ suy nghĩ, chứ không phải chỉ riêng thời gian chạy code PHP; và thời gian bắt tay SSL cũng đã nằm gọn bên trong tổng thời gian thiết lập kết nối ban đầu nên đừng cộng trùng hai lần.
  4. Lần lượt bấm qua các bộ lọc Img, CSS, JS để soi kích thước từng nhóm tài nguyên rồi quay trở về All. Nếu phát hiện bất kỳ dòng yêu cầu nào bị hủy giữa chừng (canceled) hoặc báo đỏ thất bại (failed), hãy giữ nguyên chúng trong biên bản ghi chép và tìm hiểu nguyên nhân trước khi quyết định có loại bỏ mẫu đo đó hay không.

Một hiểu lầm cực kỳ phổ biến cần phải đính chính ngay: ô tích Disable cache trên DevTools chỉ có tác dụng tắt bộ nhớ đệm cục bộ của chính trình duyệt trên máy tính của bạn. Nó hoàn toàn không có quyền năng xóa bộ nhớ đệm FastCGI Cache trên Nginx, không xóa đệm trên CDN, không làm mới bộ đệm phân giải DNS của hệ điều hành và cũng không bắt tay lại phiên TLS từ đầu nếu kết nối vẫn đang mở. Tương tự, chế độ No throttling chỉ có nghĩa là trình duyệt không tự bóp băng thông giả lập, còn chất lượng mạng Wi-Fi hay cáp quang thực tế của bạn lúc đó vẫn có thể trồi sụt theo thời gian thực. Nếu giao diện trình duyệt của bạn có chút khác biệt sau các bản cập nhật mới, hãy tra cứu trực tiếp tại tài liệu tham chiếu Chrome DevTools Network chính thức.

Phân tích ảnh chụp Waterfall thực tế: Một lát cắt quan sát đơn lẻ (không phải Benchmark tổng thể)

Trong phiên ghi nhận thực tế khi tải đường dẫn /bai-thu/ vào lúc 20:12:09 (giờ VN) ngày 01/10/2026, bảng Network cho thấy có 1 tài liệu HTML gốc (document), 1 tệp CSS, 4 tệp JavaScript và 1 tệp phông chữ (font) đều trả về mã HTTP 200 ngon lành, riêng yêu cầu tải biểu tượng trang favicon.ico ở cuối bị trình duyệt hủy (canceled). Tổng thời gian Time của dòng tài liệu HTML gốc đạt 186 ms, trong điều kiện đã tích chọn Disable cache và để chế độ No throttling. Một chi tiết rất quan trọng cần lưu ý khi nhìn bức ảnh này: vì bản thân bài viết mẫu lúc đó có 0 thẻ ảnh <img> trong nội dung, nên kết quả 186 ms này hoàn toàn không phản ánh tốc độ tải hình ảnh minh họa của trang web.

Bảng DevTools Network của trang thực hành hiển thị 7 yêu cầu trả mã 200, dòng favicon bị hủy và biểu đồ thác nước Waterfall chi tiết

Ảnh chụp màn hình DevTools thực tế lúc 20:12:09 (giờ VN) ngày 01/10/2026; trích xuất nguyên vẹn độ phân giải pixel vùng bảng yêu cầu và biểu đồ Waterfall kèm dải nhận diện localhost.vn ở chân ảnh. Bạn hãy bấm vào ảnh để phóng to xem rõ từng cột thông số (đây là ảnh chụp trực tiếp một lượt tải thực tế, không phải biểu đồ vẽ lại từ log).

Phân tích ảnh chụp thẻ Timing chi tiết (thuộc một lượt tải độc lập trước đó)

Bức ảnh chụp thẻ Timing dưới đây được lưu vào lúc 19:35:27 (giờ VN) ngày 01/10/2026, trích xuất từ lượt tải trang diễn ra lúc 19:34:56. Các con số phân rã cho thấy thời gian chờ byte đầu tiên Waiting for server response của tài liệu HTML là 155,59 ms, thời gian tải phần thân Content Download chỉ mất 0,74 ms, và tổng cộng Total cho riêng yêu cầu HTML đó là 232,97 ms. Lưu ý rằng các thông số này được đo theo chuẩn nội bộ của bảng DevTools Network — cách định nghĩa mốc bắt đầu và độ phân giải thời gian của nó có sự khác biệt nhất định so với Navigation Timing API cũng như các con số đo bằng curl ở tầng dòng lệnh.

Thẻ DevTools Timing của tài liệu HTML trang thực hành hiển thị Waiting 155,59 ms và Total 232,97 ms

Ảnh chụp màn hình DevTools thực tế lúc 19:35:27 (giờ VN) ngày 01/10/2026 của lượt tải lúc 19:34:56; giữ nguyên từng pixel gốc kèm logo chân trang. Vì bức ảnh này thuộc một lượt tải khác với bức ảnh Waterfall lúc 20:12:09 ở trên, tuyệt đối không lấy hai con số của hai bức ảnh trừ cho nhau để kết luận hiệu quả tối ưu. Bấm vào ảnh để xem kích thước đầy đủ.

Trong phiên ghi nhận lúc 19:34 này, chúng tôi khởi tạo một phiên trình duyệt khách hoàn toàn mới (clean browser context), khóa Service Worker, bật Disable cache và giữ nguyên No throttling (bảng tổng hợp vẫn giữ nguyên ghi nhận dòng favicon bị hủy). Cần nhấn mạnh rằng một lượt tải đơn lẻ như thế này chỉ giúp bạn học cách đọc giải phẫu từng pha thời gian chứ chưa đại diện cho trải nghiệm của số đông độc giả, và vì lúc 19:34 không bật công cụ đo tài nguyên máy chủ song song nên chúng ta cũng không kết luận vội vàng rằng 155,59 ms kia là do PHP hay MariaDB gây ra.

Đo chỉ số hiển thị nội dung lớn nhất (LCP) tách biệt với thời gian tải từng tệp rời rạc

Để biết khoảnh khắc người đọc thực sự nhìn thấy phần nội dung chính hiện lên trọn vẹn trên màn hình, bạn hãy chuyển sang thẻ Performance trong DevTools theo đúng hướng dẫn sử dụng bảng Performance chính thức của Chrome, bấm ghi hình khi tải lại trang rồi tìm đọc nhãn LCP (Largest Contentful Paint) cùng phần tử DOM tương ứng với nó. Nếu muốn kiểm tra hiện tượng nhảy bố cục gây khó chịu cho mắt nhìn, hãy đọc thêm chỉ số CLS (Cumulative Layout Shift). Khi so sánh các mẫu LCP, bắt buộc phải giữ cố định kích thước khung nhìn (viewport), trạng thái bộ nhớ đệm và thời điểm dừng thu thập dữ liệu. Hãy nhớ kỹ: con số time_total của tệp HTML đo bằng curl hay cột Total của một dòng yêu cầu trong thẻ Network hoàn toàn không phải là chỉ số LCP!

Để minh họa sự thú vị của chỉ số LCP trong thực tế, hãy nhìn vào một phiên đối chứng riêng biệt trên trang WordPress thực hành vào khung giờ 18:43:34–18:45:23 (giờ VN) gồm 20 lượt tải ở chế độ khách ẩn danh (chia đều 5 mẫu cho mỗi tổ hợp định dạng ảnh PNG so với WebP trên 2 khung nhìn Desktop 1440 px và Mobile 390 px). Mỗi lượt tải đều mở phiên trình duyệt mới tinh, tắt bộ nhớ đệm HTTP, chặn Service Worker và chỉ thay đổi duy nhất định dạng của một bức ảnh trong bài. Kết quả là dung lượng tệp ảnh giảm mạnh tới 53,06%, chỉ số LCP trung vị trên màn hình Desktop giảm từ 248 ms xuống 228 ms, nhưng trên khung nhìn Mobile lại dao động từ 196 ms lên 232 ms! Vì cỡ mẫu chỉ dừng ở 5 lần cho mỗi nhóm, thứ tự chạy tuần tự chưa ngẫu nhiên hóa và không khóa giới hạn xung nhịp CPU/băng thông mạng nên chúng ta không vội vàng kết luận đổi định dạng ảnh giúp tăng tốc toàn diện mọi thiết bị. Công cụ PerformanceObserver trong phiên này chỉ lắng nghe tới mốc 5 giây sau sự kiện load (không phải dữ liệu người dùng thực địa CrUX hay chỉ số độ trễ tương tác INP). Phép thử 20 mẫu này thuộc bài chuyên sâu về tối ưu hình ảnh, hoàn toàn tách biệt với hai bức ảnh chụp DevTools lúc 19:34 và 20:12 ở trên.

Bước 4: Thu thập thông số tài nguyên máy chủ VPS trong cùng khung thời gian đo

Khi muốn biết lúc trình khách đang gọi tải trang thì bên trong chiếc VPS đang nhàn nhã hay thở dốc, bạn hãy mở một cửa sổ SSH sang máy chủ Lab và chạy cụm lệnh thu thập thông số trước và trong khi bắn nhóm yêu cầu GET nhỏ:

date -u +%FT%TZ
free -h
vmstat 1 6
df -hT

Khi đọc bảng thông số bộ nhớ RAM từ lệnh free -h, các đàn anh quản trị hệ thống Linux luôn nhìn vào cột available (dung lượng thực tế sẵn sàng cấp phát cho ứng dụng mới) để so với tổng dung lượng total, chứ không bao giờ nhìn vào cột free rồi hoảng hốt kêu hết RAM — bởi nhân Linux rất thông minh, nó luôn tận dụng phần RAM rảnh rỗi để làm bộ nhớ đệm đọc đĩa (buff/cache) và sẵn sàng trả lại ngay lập tức khi ứng dụng cần! Tương tự, với lệnh vmstat 1 6, hãy nhớ rằng dòng số liệu đầu tiên luôn là giá trị trung bình tích lũy tính từ lúc máy chủ khởi động (boot); chỉ từ dòng thứ hai trở đi mới phản ánh đúng mức tiêu thụ CPU và I/O trong từng giây bạn đang đo (riêng các cột bộ nhớ và tiến trình hiện thời thì không mang ý nghĩa trung bình từ lúc boot). Đừng quên kiểm tra xem đúng lúc bạn đang bấm giờ đo thì hệ thống có đang âm thầm chạy tác vụ nén backup, chạy cronjob hay tải bản cập nhật ngầm hay không. Tất nhiên, việc thấy CPU rảnh rỗi tới 95% khi bạn mới chỉ bắn 5 lệnh GET nhẹ nhàng chỉ xác nhận máy chủ đang khỏe ở mức tải tĩnh đó, chứ không phải giấy bảo hành rằng VPS sẽ không sập khi có hàng ngàn người cùng vào săn sale! Nếu bạn cần chạy công cụ thu thập thông số trong thời gian dài, hãy nhớ giới hạn kích thước file nhật ký và tắt công cụ thu thập ngay sau khi đo xong để tránh làm đầy ổ đĩa.

Đọc hiểu màn hình Console PHP-FPM và MariaDB (cửa sổ quan sát độc lập lúc 14:23)

Bức ảnh chụp màn hình console dưới đây ghi nhận phiên đo vào lúc 14:23:38–44 (giờ VN) ngày 01/10/2026 — hoàn toàn độc lập với phiên chạy curl lúc 00:48 rạng sáng hay phiên chụp DevTools buổi tối. Trong 6 mẫu chụp trạng thái PHP-FPM liên tiếp, hàng đợi listen queue luôn bằng 0, số worker đang xử lý active dao động 1–2, số worker rảnh idle là 0–1, tổng số tiến trình con total là 2 và bộ đếm chạm trần max children reached giữ nguyên ở mức 0. Cả 5 lệnh gọi GET vào bản clone qua đường nội bộ (loopback) đều trả về mã HTTP 200 với chỉ số TTFB trung vị đạt 0.154226 giây. Cần tinh ý nhận ra rằng: bản thân câu lệnh gọi đọc trang trạng thái fpm-status cũng chiếm dụng 1 tiến trình worker đang active, và vùng nhớ FPM Pool này đang gánh chung cả hai trang web trên máy Lab — vì vậy con số active = 1–2 không có nghĩa là đang có 2 vị khách bên ngoài truy cập vào website.

Màn hình Console LAB-CF-02 ghi nhận thông số PHP-FPM, bộ nhớ RSS, vmstat và bộ đếm MariaDB trong khung giờ 14:23

Ảnh chụp màn hình Console thực tế lúc 14:24:15 (giờ VN) ngày 01/10/2026, ghi lại kết quả công cụ thu thập chạy trực tiếp trong khung 14:23:38–44 (các dòng tóm tắt do kịch bản đo tự động xuất ra chứ không phải gõ tay từng lệnh rời rạc). Độ phân giải gốc được giữ nguyên kèm logo chân trang; bấm vào ảnh để xem rõ. Đây là phiên quan sát ở mức tải nhẹ, độc lập với phiên chụp DevTools.

Khi soi tiếp xuống các chỉ số chi tiết trên màn hình: dung lượng bộ nhớ RSS (Resident Set Size) của tiến trình cha (master process) là 33.892 KiB; hai tiến trình con (child workers) trước lúc bắn request chiếm 77.708 KiB và 74.532 KiB, sau khi xử lý xong chiếm 77.708 KiB và 79.704 KiB. Hãy nhớ một kiến thức hệ điều hành cực kỳ quan trọng: chỉ số RSS của mỗi tiến trình con đã bao gồm cả các trang bộ nhớ thư viện dùng chung (shared memory pages) với tiến trình cha, nên bạn tuyệt đối không lấy con số RSS của 10 worker nhân thẳng lên 10 lần rồi bảo rằng PHP ngốn sạch RAM! Về phía cơ sở dữ liệu MariaDB, trong suốt cửa sổ đo ngắn ngủi đó, bộ đếm toàn cục tăng thêm 194 Questions và 625 Innodb_buffer_pool_read_requests, trong khi số lần phải đọc đĩa vật lý (physical reads) và số truy vấn chậm (Slow_queries) tăng đúng bằng 0 (lưu ý con số 194 câu lệnh này bao gồm cả các câu lệnh kiểm tra của chính công cụ đo nên không đem chia cho 5 lượt GET để tính trung bình số query mỗi trang). Lúc này tính năng Slow Query Log đang tắt (OFF) với ngưỡng mặc định 10 giây. Ngay sau khi thu thập xong, kịch bản đo đã được dọn dẹp sạch sẽ và cả 5 file cấu hình hệ thống giữ nguyên mã băm SHA-256. Những con số này minh họa cách chụp bối cảnh máy chủ chuẩn xác, và tất nhiên không dùng để giải thích cho con số 186 ms của lượt tải DevTools lúc 20:12 tối.

Bước 5: Lập bảng Baseline trung thực và tuyệt đối không xóa các mẫu đo bị lỗi

Sau khi thu thập xong dữ liệu, hãy lưu giữ toàn bộ bảng số liệu thô (raw data) bao gồm: dấu thời gian chính xác, đường dẫn URL (đã lọc bỏ mọi tham số nhạy cảm), trạng thái bộ nhớ đệm, mã phản hồi HTTP, chỉ số TTFB, tổng thời gian total và cột ghi chú bối cảnh. Với mỗi nhóm mẫu đo cùng điều kiện, cách báo cáo chuẩn mực nhất là nêu rõ tổng số mẫu ($N$), giá trị trung vị (Median) kèm theo biên độ nhỏ nhất / lớn nhất (Min / Max). Đặc biệt, nếu trong 10 lần bắn lệnh có 1 lần bị đứt kết nối hoặc quá thời gian chờ (Timeout), bạn bắt buộc phải giữ nguyên dòng lỗi đó trong bảng tổng kết — việc lén xóa bỏ mẫu lỗi đi để tính ra con số Median đẹp lung linh là hành vi tự đánh lừa bản thân nguy hiểm nhất trong kỹ thuật!

Khi bạn đã thực hiện một tinh chỉnh cấu hình trên máy chủ, hãy lặp lại đúng quy trình đo (protocol) y hệt như lúc ban đầu. Nếu mức chênh lệch tốc độ trước và sau khi chỉnh sửa còn nhỏ hơn cả biên độ dao động tự nhiên giữa các lần bấm đo liên tiếp, thì nghĩa là bạn chưa có đủ bằng chứng khẳng định việc tối ưu vừa rồi mang lại hiệu quả thực sự. Ngoài ra, kết quả đo từ chiếc laptop cá nhân đặt cùng thành phố với trung tâm dữ liệu VPS cũng chưa đại diện cho trải nghiệm của độc giả dùng mạng 4G ở các tỉnh xa. Muốn đánh giá tốc độ đa vùng địa lý, bạn sẽ cần thiết lập các điểm đo độc lập ở từng khu vực (nội dung bài viết này chỉ tập trung vào phương pháp luận tại một điểm đo chuẩn).

Nghiệm thu quy trình đo đạc và nhận diện rõ ranh giới kết luận

Một quy trình đo lường (protocol) được coi là đạt chuẩn kỹ thuật khi một đồng nghiệp khác chỉ cần đọc bảng mô tả điều kiện của bạn là có thể tái hiện lại đúng từng bước thao tác. Trong bài viết này, chúng ta có bộ số liệu curl kèm tài nguyên máy chủ lúc 00:48, màn hình console PHP-FPM / MariaDB lúc 14:23, phép thử đối chứng LCP lúc 18:43 và hai ảnh chụp DevTools lúc 19:34 / 20:12. Bởi vì đây là các phiên thực hành độc lập diễn ra ở những khung giờ khác nhau và chưa áp dụng giả lập bóp băng thông mạng (throttling), chúng ta tuyệt đối không trộn lẫn chúng thành một bản báo cáo Benchmark tổng hợp hay dùng để kết tội cho PHP hay Database.

Bốn nguyên tắc báo cáo số liệu trung thực: Giữ nguyên dữ liệu thô; Dùng trung vị Median và biên độ dao động; Ghi nhận đầy đủ cả lỗi Timeout; Không suy diễn thành sức chịu tải

Sơ đồ tư duy 3: Bốn nguyên tắc vàng giúp giữ sự trung thực khoa học khi lập báo cáo tốc độ hệ thống. Sơ đồ do đội ngũ localhost.vn biên soạn.

Hồ sơ thực nghiệm: Bộ số đo Baseline trên máy chủ LAB-CF-02 ngày 01/10/2026

Trong khung giờ từ 00:48:09 đến 00:48:38 (giờ Việt Nam) ngày 01/10/2026, chúng tôi sử dụng công cụ curl 8.7.1 chạy trên máy trạm Mac (nằm ngoài mạng nội bộ của VPS) để thực hiện 5 lệnh GET tuần tự vào đường dẫn bài viết /bai-thu/, tiếp nối bằng 5 lệnh GET vào một tệp ảnh tĩnh có sẵn của bộ cài WordPress. Mỗi yêu cầu đều được khởi tạo bằng một tiến trình curl độc lập hoàn toàn (không tái sử dụng kết nối cũ), không gửi kèm cookie, không tự nhảy theo redirect, bỏ qua mọi máy chủ proxy trung gian và đặt ngưỡng thời gian chờ tối đa là 15 giây. Ngay sau khi một yêu cầu hoàn tất, kịch bản nghỉ đúng 2 giây rồi mới bắn yêu cầu tiếp theo (vị trí địa lý cụ thể và đường truyền ISP của máy trạm Mac được giữ cố định trong suốt phiên nhưng chưa qua kiểm định độc lập của bên thứ ba).

Toàn bộ các thông số thời gian trong bảng tổng hợp dưới đây đều được tính bằng đơn vị giây (s), trình bày theo đúng thứ tự: Nhỏ nhất (Min) / Trung vị (Median) / Lớn nhất (Max):

Đường dẫn URL Số mẫu đo Dung lượng Body mỗi mẫu (byte) TTFB Min / Median / Max (s) Total Min / Median / Max (s)
/bai-thu/ 5 68073 0.159199 / 0.161591 / 0.240246 0.162202 / 0.164507 / 0.243380
/wp-includes/images/w-logo-blue.png 5 3113 0.017974 / 0.018323 / 0.020080 0.018140 / 0.018556 / 0.020325
Biểu đồ phân bố TTFB và tổng thời gian tải của 5 mẫu HTML và 5 mẫu ảnh PNG trên LAB-CF-02 tính theo mili giây với hai trục tung riêng biệt

Biểu đồ trực quan hóa từ đúng 10 mẫu đo curl thực tế ngày 01/10/2026 (5 mẫu cho mỗi đường dẫn URL). Lưu ý biểu đồ sử dụng đơn vị mili giây (ms) để dễ đọc bằng mắt thường, trong khi bảng số liệu gốc ở trên giữ nguyên đơn vị giây (s) của curl; đồng thời hai khung biểu đồ trái/phải sử dụng thang đo trục dọc khác nhau do chênh lệch độ lớn. Giá trị trung vị TTFB đạt 161,591 ms đối với trang HTML và 18,323 ms đối với tệp ảnh PNG tĩnh (các mẫu chưa được gắn nhãn phân loại cache cold hay warm).

Bấm vào đây để xem biểu đồ ở độ phân giải gốc sắc nét (1600 px)

Cả 10 mẫu đo trong phiên này đều trả về mã HTTP 200 chuẩn xác, tiến trình curl thoát với mã exit code 0, quá trình xác thực chứng chỉ bảo mật TLS hoàn toàn hợp lệ, kết nối thẳng tới đúng địa chỉ IP của máy chủ Lab và không phát sinh bất kỳ bước chuyển hướng (redirect) nào. Chúng tôi cũng đã kiểm tra nội dung thẻ HTML cũng như chữ ký định dạng tệp PNG: phần thân dữ liệu (body) trả về giữa 5 lần gọi của mỗi nhóm có mã băm SHA-256 giống hệt nhau tuyệt đối, và bảng số liệu giữ nguyên trọn vẹn cả 10 mẫu mà không cắt bỏ bất kỳ điểm dị biệt nào.

Bởi vì phiên thực nghiệm lúc 00:48 này chủ đích đo hiện trạng tự nhiên mà không can thiệp xóa bộ nhớ đệm (purge cache) hay sửa đổi cấu hình máy chủ trước khi bắn lệnh, nên các mẫu đo không được gắn nhãn là Cache Cold hay Cache Warm. Một điểm kỹ thuật rất đáng lưu ý: việc bạn nhìn vào danh sách HTTP Response Headers mà không thấy xuất hiện các dòng quen thuộc như Age, X-Cache hay CF-Cache-Status chưa bao giờ là bằng chứng khẳng định hệ thống không có bộ nhớ đệm nào bên dưới! Đồng thời, vì trang bài viết HTML (nặng 68.073 byte, phải gọi PHP/Database) và tấm ảnh PNG tĩnh (chỉ nặng 3.113 byte, do Nginx trả thẳng từ đĩa) khác biệt hoàn toàn cả về kích thước lẫn bản chất xử lý, nên khoảng cách giữa 161 ms và 18 ms là sự khác biệt tự nhiên giữa tài nguyên động và tài nguyên tĩnh — tuyệt đối không hiểu nhầm đó là mức tăng tốc sau khi tối ưu.

Ngay trong cùng khung cửa sổ thời gian từ 00:48:09 đến 00:48:38 đó, trên máy chủ VPS có chạy song song lệnh vmstat 1 30 để ghi nhận 29 khoảng đo 1 giây (sau khi đã loại bỏ dòng đầu tiên mang tính trung bình từ lúc khởi động máy). Số liệu ghi nhận tỷ lệ CPU idle (nhàn rỗi) luôn duy trì ở mức rất cao từ 82% đến 100%, chỉ số ghi/đọc bộ nhớ ảo si/so bằng 0 tuyệt đối; trên tổng dung lượng RAM 1.968 MiB, lượng bộ nhớ khả dụng available chỉ nhích nhẹ từ 1.285 MiB xuống 1.284 MiB, lượng đang dùng used từ 682 MiB lên 683 MiB và không hề dùng tới một byte Swap nào. Những con số này đóng vai trò xác nhận rằng trong lúc lấy 10 mẫu curl, chiếc VPS hoàn toàn thảnh thơi và không bị nghẽn tài nguyên ngầm (tất nhiên đây là bối cảnh của 10 lệnh GET tuần tự chứ không phải bài kiểm tra sức chịu tải).

Tóm lại, bảng số liệu và biểu đồ trên phản ánh trung thực thời gian truyền tải ở tầng giao thức HTTP của hai nhóm đường dẫn HTML và PNG vào lúc 00:48 rạng sáng. Con số Total ở đây chỉ dừng lại ở lúc tải xong tệp đó về máy, chưa bao gồm quá trình trình duyệt tải hàng loạt tệp phụ thuộc khác và vẽ lên màn hình, nên phiên đo curl này không có chỉ số LCP và không phải là bảng điểm Benchmark toàn diện của máy chủ.

Xử lý thế nào khi đang đo mà phát hiện lỗi hoặc cấu hình mới làm web chậm đi?

Nếu ngay trong bước thu thập mẫu mà bạn nhận về mã phản hồi khác HTTP 200 (chẳng hạn 500, 502, 504) hoặc thấy dung lượng nội dung trả về nhảy loạn xạ giữa các lần gọi, hãy dừng ngay việc bấm giờ tốc độ lại để ưu tiên sửa lỗi chức năng trước — một trang báo lỗi trắng tinh trả về trong 5 mili giây thì chẳng có ý nghĩa tối ưu nào cả! Nếu gặp lỗi chứng chỉ bảo mật TLS, hãy kiểm tra lại cấu hình tên miền và gia hạn chứng chỉ. Trong trường hợp bạn vừa thử áp dụng một cấu hình tối ưu mới mà kết quả đo lại báo chậm hơn cả mốc Baseline ban đầu, hãy bình tĩnh khôi phục lại file cấu hình cũ đã sao lưu, gõ lệnh sudo nginx -t để xác nhận cú pháp chuẩn xác rồi mới cho reload lại đúng dịch vụ đó. Cuối cùng, đừng quên chạy lại một lượt đo trong cùng điều kiện để xác nhận hệ thống đã thực sự trở về tốc độ ổn định ban đầu.

Câu hỏi thường gặp (FAQ)

Chỉ số TTFB cao có phải lúc nào cũng do code PHP của WordPress chạy chậm không?

Hoàn toàn không! Con số TTFB đo từ phía trình khách là tổng hòa của cả một hành trình dài: từ phân giải tên miền DNS Lookup, thiết lập kết nối mạng TCP, bắt tay bảo mật TLS Handshake, khoảng cách cáp quang quốc tế/trong nước cho tới hàng đợi trên web server rồi mới tới lượt PHP và Database xử lý. Muốn biết chính xác PHP tốn bao nhiêu mili giây trong tổng số đó, bạn cần phải đối chiếu thêm với nhật ký upstream_response_time ngay trên máy chủ.

Đo 5 mẫu liên tiếp như trong hướng dẫn đã đủ để gọi là Benchmark sức mạnh máy chủ chưa?

Chưa đâu nhé! Việc lấy 5 mẫu tuần tự theo quy trình trong bài chỉ đóng vai trò là một phép quan sát cơ sở (Baseline Observation) có kiểm soát để bạn làm mốc đối chiếu nhanh trước và sau khi chỉnh sửa cấu hình, hoàn toàn chưa đại diện cho phân bố lưu lượng truy cập thực tế của hàng ngàn người dùng ở mọi khung giờ cao điểm trong ngày.

Tôi có nên bấm đo tốc độ khi đang đăng nhập sẵn tài khoản Quản trị viên (Admin) không?

Rất nên đo nếu mục tiêu của bạn là khảo sát và tối ưu tốc độ thao tác trong trang quản trị wp-admin cho đội ngũ biên tập viên! Tuy nhiên, bạn bắt buộc phải tách riêng bảng số liệu này và không bao giờ trộn chung với bảng đo của khách truy cập ẩn danh, bởi khi có cookie đăng nhập, hệ thống sẽ đi theo một luồng xử lý hoàn toàn khác (bỏ qua Page Cache và phải nạp thêm hàng loạt công cụ quản trị).

Bước hành động tiếp theo dành cho bạn

Ngay bây giờ, hãy chọn ra đúng một đường dẫn URL quan trọng nhất trên website của bạn cùng một câu hỏi cụ thể cần giải đáp. Hãy lập một bảng tính nhỏ gồm 5 dòng mẫu đo, ghi chép đầy đủ giờ giấc, trạng thái bộ nhớ đệm, mã phản hồi HTTP và xác nhận nội dung trả về. Sau đó, hãy mở trình duyệt chụp lại đúng bảng DevTools Network / Timing của lượt tải đó; và nếu nghi ngờ phía máy chủ đang quá tải, hãy mở thêm cửa sổ terminal thu thập thông số tài nguyên trong cùng khung giờ. Khi đã có trong tay bộ mốc chuẩn Baseline vững chắc, bạn hãy thử thay đổi từng yếu tố một rồi đo lại để kiểm chứng — nhớ giữ lại toàn bộ các mẫu lỗi và sẵn sàng bác bỏ giả thuyết ban đầu nếu số liệu thực tế chứng minh ngược lại. Khi đã hoàn tất bước đo đạc nền tảng này, mời bạn bước sang bài tiếp theo trong series làm chủ WordPress trên VPS từ A đến Z để học cách khoanh vùng chính xác điểm nghẽn!

Tài liệu tham khảo và trạng thái đối chiếu kỹ thuật

Các tài liệu kỹ thuật chính thức đã được rà soát và đối chiếu vào ngày 01/10/2026: tài liệu hướng dẫn gốc của công cụ curl về định nghĩa các biến thời gian tích lũy và kích thước tải về (size_download); cùng bộ tài liệu chính thức của Google Chrome về bảng Network và Performance. Toàn bộ số liệu thực nghiệm trong bài thuộc về các khung cửa sổ đo độc lập đã được ghi chú rõ dấu thời gian ở từng mục.

Tài liệu kiến thức nền tảng đã đối chiếu vào ngày 30/09/2026:

Tài liệu tham khảo & Kiểm chứng

CẦN KỸ SƯ HỖ TRỢ TRỰC TIẾP? Đang làm theo hướng dẫn nhưng vướng lỗi hệ thống hoặc sợ đụng chạm dữ liệu đang chạy?

Gửi địa chỉ URL qua Zalo để kỹ thuật viên localhost.vn kiểm tra sơ bộ miễn phí trước khi quyết định can thiệp.

Xem bảng dịch vụ
Góc thực chiến localhost.vn

Mọi hướng dẫn đều dựa trên số liệu đo đạc, log thực tế và nguyên tắc "luôn có đường lùi (Snapshot/Backup) trước khi gõ lệnh".

Nguyên tắc biên tập & Minh bạch ↗