I was using the Apache Bench ab
command to exercise some new code I'm writing in Datasette and I noticed I was getting a lot of errors:
ab -n 1000 -c 10 \
'http://127.0.0.1:8002/fixtures/compound_primary_key?_extra=count&_size=3&_extra=columns&_extra=primary_keys&_trace=1&_extra=debug'
Truncated output:
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
...
Complete requests: 1000
Failed requests: 953
(Connect: 0, Receive: 0, Length: 953, Exceptions: 0)
What's with the 953 failed requests? My server logged a 200 status code for each of them, so it seemed to think they were being returned without errors.
Thanks to Stack Overflow I learned that by default Apache Bench considers a request a "length" error if it does not match exactly the length of the first recieved page.
This particular Datasette response includes millisecond timing information in the JSON (thanks to the ?_trace=1
option), and since those timings differ the overall length differs between requests.
The solution is to use the -l
(lower case L) option, as documented in ab --help
like this:
Accept variable document length (use this for dynamic pages)
So the following command runs without showing those errors:
ab -l -n 1000 -c 10 \
'http://127.0.0.1:8002/fixtures/compound_primary_key?_extra=count&_size=3&_extra=columns&_extra=primary_keys&_trace=1&_extra=debug'
Truncated output:
Concurrency Level: 10
Time taken for tests: 1.407 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 2962382 bytes
HTML transferred: 2823382 bytes
Requests per second: 710.53 [#/sec] (mean)
Time per request: 14.074 [ms] (mean)
Time per request: 1.407 [ms] (mean, across all concurrent requests)
Transfer rate: 2055.52 [Kbytes/sec] received
Created 2023-02-08T11:26:45-08:00 · Edit