Avoiding “length” errors in Apache Bench with the -l option
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 requestsCompleted 200 requests...Complete requests:      1000Failed 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:      10Time taken for tests:   1.407 secondsComplete requests:      1000Failed requests:        0Total transferred:      2962382 bytesHTML transferred:       2823382 bytesRequests 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