DEV Community

Cover image for wrk: Cách kiểm thử tải API từ dòng lệnh
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

wrk: Cách kiểm thử tải API từ dòng lệnh

Bạn đã triển khai một endpoint. Nó chạy tốt trên trình duyệt của bạn, nhưng điều đó chưa trả lời được các câu hỏi quan trọng: khi 400 người truy cập cùng lúc thì độ trễ có ổn định không? P99 có tăng vọt không? Server chịu được 1.000 request/giây hay bắt đầu nghẽn ở mức 300?

Thử Apidog ngay hôm nay

wrk giúp bạn đo các con số đó. Đây là công cụ dòng lệnh dùng để tạo tải HTTP lên một URL và báo cáo tốc độ phản hồi của server dưới tải.

wrk là gì và khi nào nên dùng?

wrk là công cụ benchmark HTTP hiện đại. Nó tạo tải từ một máy đa lõi duy nhất, đo thông lượng request và độ trễ phản hồi của server.

Bên dưới, wrk dùng nhiều thread kết hợp với event loop có khả năng mở rộng:

  • epoll trên Linux
  • kqueue trên macOS

Vì vậy, một instance wrk có thể tạo ra lượng tải lớn mà không cần nhiều máy load generator.

Dùng wrk khi bạn cần trả lời các câu hỏi như:

  • Endpoint này duy trì được bao nhiêu request/giây?
  • Độ trễ trung bình, P90, P99 là bao nhiêu?
  • Server có ổn định dưới tải kéo dài không?
  • Thay đổi code mới làm hiệu năng tốt hơn hay tệ hơn?

Lưu ý: wrk là công cụ benchmark, không phải bộ kiểm thử chức năng. Nó đo tốc độ, nhưng không xác nhận JSON response đúng hay sai, status code có phải 200 hay không, hoặc API có tuân thủ contract không.

Nếu bạn cần nền tảng về các khái niệm load testing, xem thêm hướng dẫn kiểm thử tải API.

Cài đặt wrk

macOS

Cách đơn giản nhất là dùng Homebrew:

brew install wrk
Enter fullscreen mode Exit fullscreen mode

Trên Apple Silicon, nên ưu tiên binary từ Homebrew. Việc build từ source có thể gặp lỗi với LuaJIT ARM64.

Kiểm tra cài đặt:

wrk --version
Enter fullscreen mode Exit fullscreen mode

Linux

Trên Linux, bạn thường cần build từ source.

Cài toolchain và OpenSSL headers:

sudo apt-get install build-essential libssl-dev git -y
Enter fullscreen mode Exit fullscreen mode

Clone repo và build:

git clone https://github.com/wg/wrk.git
cd wrk
make
Enter fullscreen mode Exit fullscreen mode

Sau khi build, binary wrk nằm trong thư mục hiện tại. Di chuyển nó vào PATH:

sudo cp wrk /usr/local/bin
Enter fullscreen mode Exit fullscreen mode

Kiểm tra:

wrk --version
Enter fullscreen mode Exit fullscreen mode

Chạy benchmark đầu tiên

Cú pháp cơ bản:

wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html
Enter fullscreen mode Exit fullscreen mode

Trong đó:

  • -t, --threads: số thread hệ điều hành mà wrk tạo ra.
  • -c, --connections: tổng số kết nối HTTP được giữ mở.
  • -d, --duration: thời gian chạy benchmark.

Ví dụ trên nghĩa là:

  • 12 thread
  • 400 connection
  • chạy trong 30 giây
  • benchmark URL http://127.0.0.1:8080/index.html

Một cấu hình thực tế hơn khi test API local:

wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Nên bật --latency trong hầu hết các lần chạy để xem phân phối độ trễ, đặc biệt là P90 và P99.

Các flag quan trọng

-t: số thread

Ví dụ:

-t8
Enter fullscreen mode Exit fullscreen mode

Điểm khởi đầu hợp lý là một thread cho mỗi CPU core.

Nếu máy chạy wrk có 8 core:

wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Nếu CPU của máy client bị đầy, kết quả benchmark có thể phản ánh giới hạn của máy tạo tải thay vì giới hạn của server.

-c: số connection

Ví dụ:

-c200
Enter fullscreen mode Exit fullscreen mode

Flag này mô phỏng số client đồng thời. -c200 nghĩa là wrk giữ 200 kết nối HTTP mở trong suốt bài test.

Tăng dần connection để tìm điểm server bắt đầu bão hòa:

wrk -t8 -c50  -d30s --latency http://localhost:3000/api/users
wrk -t8 -c100 -d30s --latency http://localhost:3000/api/users
wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
wrk -t8 -c400 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Quan sát:

  • Requests/sec còn tăng không?
  • P99 có tăng mạnh không?
  • Timeout hoặc error có xuất hiện không?
  • CPU, memory, DB connection pool của server ra sao?

-d: thời lượng test

Ví dụ:

-d30s
Enter fullscreen mode Exit fullscreen mode

wrk chấp nhận các giá trị như:

-d10s
-d30s
-d2m
-d1h
Enter fullscreen mode Exit fullscreen mode

Dùng vài giây cho smoke test nhanh. Dùng 30 giây đến vài phút để có kết quả ổn định hơn.

--latency

Luôn bật flag này khi bạn quan tâm trải nghiệm người dùng:

wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Trung bình thường che giấu tail latency. P99 mới là con số giúp bạn thấy một phần nhỏ request đang bị chậm đến mức nào.

--timeout

Dùng để giới hạn thời gian chờ response:

wrk -t8 -c200 -d30s --latency --timeout 2s http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Nếu request không nhận được response trong 2 giây, wrk ghi nhận timeout.

Đọc kết quả wrk

Ví dụ output:

Running 5s test @ http://10.135.232.163:3000
  2 threads and 5 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.82ms    2.64ms  26.68ms   85.81%
    Req/Sec   550.90    202.40     0.98k    68.00%
  5494 requests in 5.01s, 1.05MB read
Requests/sec:   1096.54
Transfer/sec:    215.24KB
Enter fullscreen mode Exit fullscreen mode

Đọc từ dưới lên.

Requests/sec

Requests/sec:   1096.54
Enter fullscreen mode Exit fullscreen mode

Đây là thông lượng trung bình: server xử lý được khoảng 1.096 request/giây.

Dùng con số này để so sánh:

  • trước và sau khi tối ưu code
  • giữa các endpoint
  • giữa các cấu hình server
  • giữa HTTP và HTTPS
  • giữa các mức concurrency

Transfer/sec

Transfer/sec:    215.24KB
Enter fullscreen mode Exit fullscreen mode

Đây là lượng dữ liệu truyền mỗi giây.

Chỉ số này hữu ích khi:

  • response payload lớn
  • bạn nghi ngờ bị giới hạn bởi network bandwidth
  • benchmark endpoint trả file hoặc dữ liệu lớn

Latency

Latency     3.82ms    2.64ms  26.68ms   85.81%
Enter fullscreen mode Exit fullscreen mode

Ý nghĩa:

  • Avg: độ trễ trung bình
  • Stdev: độ lệch chuẩn
  • Max: độ trễ cao nhất
  • +/- Stdev: phần trăm mẫu nằm trong một độ lệch chuẩn

Trong ví dụ:

  • trung bình: 3.82ms
  • cao nhất: 26.68ms

Max cao hơn nhiều so với Avg cho thấy một số request chậm hơn đáng kể so với phần lớn request.

Req/Sec

Req/Sec   550.90    202.40     0.98k    68.00%
Enter fullscreen mode Exit fullscreen mode

Đây là số request/giây theo từng thread, kèm phân phối của nó.

Nếu giá trị này dao động mạnh, có thể server hoặc client load generator đang không ổn định.

Xem phân phối độ trễ với --latency

Khi thêm --latency, wrk in thêm phần phân vị:

Latency Distribution
   50%    3.21ms
   75%    4.86ms
   90%    7.09ms
   99%   14.13ms
Enter fullscreen mode Exit fullscreen mode

Cách đọc:

  • P50: 50% request hoàn thành trong 3.21ms
  • P75: 75% request hoàn thành trong 4.86ms
  • P90: 90% request hoàn thành trong 7.09ms
  • P99: 99% request hoàn thành trong 14.13ms

P99 là chỉ số nên theo dõi kỹ. Nếu average thấp nhưng P99 cao, một nhóm nhỏ người dùng vẫn gặp response chậm.

Gửi POST request với Lua script

Mặc định wrk gửi request GET.

Để gửi POST, body hoặc custom header, dùng Lua script với flag -s.

Tạo file post.lua:

wrk.method = "POST"
wrk.body   = '{"name": "Ada", "role": "engineer"}'
wrk.headers["Content-Type"] = "application/json"
Enter fullscreen mode Exit fullscreen mode

Chạy benchmark:

wrk -t4 -c100 -d30s -s post.lua --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Trong script:

  • wrk.method: HTTP method
  • wrk.body: request body
  • wrk.headers: bảng chứa HTTP headers

Gửi form-encoded POST

Ví dụ body dạng application/x-www-form-urlencoded:

wrk.method = "POST"
wrk.body   = "foo=bar&baz=quux"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
Enter fullscreen mode Exit fullscreen mode

Chạy:

wrk -t4 -c100 -d30s -s post.lua --latency http://localhost:3000/api/form
Enter fullscreen mode Exit fullscreen mode

Thêm header bằng -H

Nếu chỉ cần thêm một hoặc hai header, bạn có thể dùng -H thay vì Lua script:

wrk -t4 -c100 -d30s \
  -H "Authorization: Bearer TOKEN123" \
  --latency \
  http://localhost:3000/api/protected
Enter fullscreen mode Exit fullscreen mode

Thêm nhiều header:

wrk -t4 -c100 -d30s \
  -H "Authorization: Bearer TOKEN123" \
  -H "X-Tenant-Id: tenant_123" \
  --latency \
  http://localhost:3000/api/protected
Enter fullscreen mode Exit fullscreen mode

Quy tắc thực tế:

  • Dùng -H cho header đơn giản.
  • Dùng Lua script khi cần body, method khác GET, hoặc logic tùy biến theo từng request.

Một workflow benchmark thực tế

Thay vì chạy một lệnh duy nhất, hãy tăng tải theo từng bước.

Ví dụ:

URL="http://localhost:3000/api/users"

wrk -t8 -c50  -d30s --latency "$URL"
wrk -t8 -c100 -d30s --latency "$URL"
wrk -t8 -c200 -d30s --latency "$URL"
wrk -t8 -c400 -d30s --latency "$URL"
Enter fullscreen mode Exit fullscreen mode

Ghi lại cho mỗi lần chạy:

  • Requests/sec
  • P50
  • P90
  • P99
  • timeout/error nếu có
  • CPU server
  • memory server
  • DB CPU/query latency
  • connection pool usage

Mục tiêu không chỉ là tìm request/giây cao nhất. Bạn cần tìm mức tải mà hệ thống vẫn giữ được latency ổn định.

Một dấu hiệu bão hòa thường gặp:

  • Requests/sec không tăng thêm dù tăng -c
  • P99 tăng mạnh
  • timeout bắt đầu xuất hiện
  • CPU server hoặc database đạt ngưỡng cao
  • queue trong app hoặc DB tăng

Giới hạn: wrk không kiểm tra tính đúng đắn

wrk cho bạn biết server phản hồi nhanh như thế nào. Nó không cho bạn biết response có đúng hay không.

Ví dụ: nếu endpoint trả HTTP 500 cho mọi request, wrk vẫn có thể báo Requests/sec rất cao. Lý do là wrk chỉ đo giao dịch HTTP hoàn thành, không xác thực:

  • status code
  • response body
  • JSON schema
  • business logic
  • API contract

Lỗi thậm chí có thể trông “nhanh” hơn, vì server từ chối request sớm và làm ít việc hơn.

Vì vậy:

  • wrk trả lời: “Endpoint có đủ nhanh dưới tải không?”
  • Test chức năng trả lời: “Endpoint có đúng không?”

Bạn cần cả hai. Đây là lý do nhiều nhóm kết hợp benchmark tool với bộ kiểm thử chức năng.

Vị trí của Apidog trong workflow kiểm thử

Một workflow rõ ràng nên có hai lớp.

Bước 1: xác thực hành vi API

Trước khi đo tốc độ, hãy xác nhận endpoint hoạt động đúng.

Trong Apidog, bạn có thể tạo test scenario để gửi request thật và kiểm tra:

  • status code
  • field trong JSON
  • response schema
  • logic nghiệp vụ
  • dữ liệu truyền giữa các bước
  • cùng một scenario trên nhiều environment

Lớp này giúp bắt lỗi mà wrk không phát hiện, ví dụ endpoint trả 500 nhưng vẫn phản hồi rất nhanh.

Bước 2: benchmark thông lượng

Sau khi hành vi đã đúng, dùng wrk để benchmark các endpoint đó dưới concurrency và tải liên tục.

Apidog cũng có kiểm thử hiệu năng tích hợp nếu bạn muốn giữ kiểm thử chức năng và kiểm thử tải trong cùng một nơi. Còn wrk phù hợp khi bạn cần benchmark dòng lệnh nhanh, thô và dễ script hóa.

Chạy Apidog CLI trong CI

Lớp kiểm thử chức năng nên chạy trong CI, không chỉ trên máy cá nhân.

Cài Apidog CLI:

npm install -g apidog-cli
Enter fullscreen mode Exit fullscreen mode

Chạy scenario hoặc test suite đã lưu theo ID:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t <scenarioOrSuiteId> \
  -e <environmentId> \
  -r cli,html,junit
Enter fullscreen mode Exit fullscreen mode

Ý nghĩa:

  • -t: ID của scenario, folder hoặc test suite
  • -e: ID environment
  • -r: định dạng report, ví dụ cli, html, json, junit

Report JUnit có thể được tích hợp vào hầu hết hệ thống CI để kiểm tra pass/fail.

Với test chạy theo dữ liệu, thêm -d hoặc --iteration-data:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t <scenarioOrSuiteId> \
  -e <environmentId> \
  -d ./data.csv \
  -r cli,html,junit
Enter fullscreen mode Exit fullscreen mode

Apidog CLI chạy các scenario và test suite đã lưu. Nó là công cụ headless để kiểm tra tính đúng đắn, không phải load generator.

Một cách phân chia hợp lý:

Apidog CLI  -> kiểm tra API đúng hay sai
wrk         -> đo API nhanh hay chậm dưới tải
Enter fullscreen mode Exit fullscreen mode

Bạn có thể xem thêm hướng dẫn CI/CD với CLI, hướng dẫn GitHub Actions, hoặc tài liệu tham khảo CLI đầy đủ.

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

wrk khác gì ab, ApacheBench?

Cả hai đều tạo tải HTTP và báo cáo request/giây.

Khác biệt chính:

  • wrk đa luồng và dùng event loop.
  • ab đơn luồng.
  • wrk thường tạo được tải lớn hơn từ một máy duy nhất.
  • Cả hai đều không xác thực tính đúng đắn của response.

Nếu bạn cần benchmark concurrency cao từ một máy, wrk thường phù hợp hơn.

Nên dùng bao nhiêu thread và connection?

Bắt đầu với một thread cho mỗi CPU core.

Ví dụ máy có 8 core:

wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Sau đó tăng dần -c:

-c50
-c100
-c200
-c400
Enter fullscreen mode Exit fullscreen mode

Nếu throughput không tăng nhưng latency tăng mạnh, có thể server đã bão hòa.

Nếu CPU trên máy chạy wrk đạt 100%, kết quả có thể bị giới hạn bởi client load generator.

wrk có test được HTTPS không?

Có.

Chỉ cần dùng URL https://:

wrk -t8 -c200 -d30s --latency https://example.com/api/users
Enter fullscreen mode Exit fullscreen mode

HTTPS có thêm chi phí TLS, nên thông lượng có thể thấp hơn HTTP thuần. Trên Linux, đây là lý do bạn cần libssl-dev khi build wrk.

wrk có xác thực status code hoặc response body không?

Không.

wrk đo thời gian và đếm HTTP transaction hoàn thành. Nó không kiểm tra status code, JSON body hoặc schema.

Nếu cần xác thực tính đúng đắn, hãy dùng bộ kiểm thử chức năng như test suite chạy qua Apidog CLI, sau đó dùng wrk để đo thông lượng.

Một bài load test nên chạy bao lâu?

Tối thiểu nên chạy đủ lâu để vượt qua các hiệu ứng khởi động như cache lạnh hoặc JIT warm-up.

Gợi ý:

  • 5s đến 10s: kiểm tra nhanh
  • 30s: mặc định hợp lý
  • vài phút: tốt hơn để phát hiện suy giảm dưới tải kéo dài
  • lâu hơn: hữu ích khi tìm memory leak hoặc degradation chậm

Ví dụ mặc định:

wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Khi nào nên nghi ngờ kết quả wrk?

Hãy kiểm tra lại nếu:

  • endpoint đang trả lỗi nhưng Requests/sec vẫn cao
  • máy chạy wrk bị CPU 100%
  • network giữa client và server bị giới hạn
  • database hoặc dependency bên ngoài không giống production
  • thời lượng test quá ngắn
  • không bật --latency
  • chỉ nhìn average latency mà bỏ qua P99

Benchmark tốt không chỉ là một con số Requests/sec. Nó phải đi kèm latency distribution, error/timeout và metrics từ server.

Top comments (0)