How to Force ApacheBench (ab) to Send HTTP/1.1 Requests Instead of HTTP/1.0


2 views

When using ApacheBench (ab) for performance testing, you might encounter servers that strictly require HTTP/1.1 connections. By default, ab sends requests with HTTP/1.0 in the request line:


GET / HTTP/1.0
Host: example.com

While the -k flag adds Connection: keep-alive header, it doesn't actually change the HTTP version in the request line.

The most reliable solution is to modify the source code. Here's how to change the HTTP version in ab's source:


// In src/main.c (around line 1500 in Apache 2.4.41)
// Change from:
apr_snprintf(reqbuf, reqbufsize, "%s %s HTTP/1.0\r\n", method, path);
// To:
apr_snprintf(reqbuf, reqbufsize, "%s %s HTTP/1.1\r\n", method, path);

After making this change, recompile ab:


./buildconf
./configure
make

If modifying source code isn't an option, consider these alternatives that natively support HTTP/1.1:


# wrk - modern HTTP benchmarking tool
wrk -t12 -c400 -d30s http://example.com

# hey - modern ab replacement
hey -n 100000 -c 100 http://example.com

# vegeta - flexible load testing tool
echo "GET http://example.com" | vegeta attack -duration=30s -rate=100/s

To confirm your requests are using HTTP/1.1, capture traffic with tcpdump:


tcpdump -i any -A -s0 port 80 | grep 'HTTP/1'

Or use Wireshark to inspect the full protocol details of each request.


When benchmarking web servers that strictly require HTTP/1.1, many developers encounter limitations with ApacheBench's default behavior. The ab tool ships with HTTP/1.0 as its default protocol version, which can cause compatibility issues with modern web servers.

While the -k flag enables keep-alive connections by adding Connection: keep-alive header, it doesn't actually change the protocol version in the request line:

GET / HTTP/1.0
Host: example.com
Connection: keep-alive

The most reliable workaround involves creating a custom request file that explicitly specifies HTTP/1.1:

# Create a file named http11.req
GET / HTTP/1.1
Host: yourserver.com
Connection: keep-alive

# Then run ab with:
ab -k -n 1000 -c 10 -p http11.req -T 'application/x-www-form-urlencoded' http://yourserver.com/

For teams needing more flexibility, consider these alternatives:

# Using wrk (supports HTTP/1.1 natively)
wrk -t12 -c400 -d30s http://yourserver.com

# Using hey (Google's modern ab alternative)
hey -n 1000 -c 50 -m GET http://yourserver.com

To confirm your requests are using HTTP/1.1, capture traffic with:

tcpdump -i any -w traffic.pcap port 80
# Analyze with Wireshark or:
tcpdump -A -r traffic.pcap | grep 'HTTP/1.1'