ab -k -p: POST Bodies and KeepAlive
ab -p body.json -T application/json POSTs a fixed body on every request, and -k reuses connections with HTTP KeepAlive.
ApacheBench defaults to GET and one connection per request. For a realistic write path you need -p (a body file) with -T (its content type), and -k to stop paying a TCP handshake on every call.
What it does
With -p <file> ab switches to POST and sends the file contents as the request body on every request; -T sets the Content-Type header (there is no default, so it must be given). -k turns on KeepAlive so connections are reused, which changes both throughput and the connection-error profile. Use -u <file> for PUT.
Common usage
printf '{"name":"ci-run"}' > body.json
ab -n 5000 -c 50 -k \
-p body.json -T 'application/json' \
-H 'Authorization: Bearer test' \
http://localhost:8080/api/itemsOptions
| Flag | What it does |
|---|---|
| -p <file> | POST the file contents as the body |
| -u <file> | PUT the file contents instead |
| -T <type> | Content-Type for -p/-u (required with them) |
| -k | Enable HTTP KeepAlive (reuse connections) |
| -H <header> | Extra request header (repeatable) |
| -C <name=value> | Add a Cookie header |
In CI
Warm the endpoint with one request before the measured run so JIT/connection-pool cold start does not skew the first percentiles. Then gate on Non-2xx responses: being zero (a 401/422 from a bad payload will otherwise pass silently since ab still exits 0).
Common errors in CI
Forgetting -T with -p makes the server reject the body or misparse it, showing up as Non-2xx responses. ab: Could not open POST data file means a wrong path to the body file. If KeepAlive shows Keep-Alive requests: 0, the server closed each connection (often a missing Connection: keep-alive on its side), so -k gave no benefit.