Hello,
in an Ubuntu 24.04 Server machine, im using HAProxy (2.8.5-1ubuntu3.3) to load balance my company’s API. Load Balancing works great but i am having issues with rate limiting of incoming requests. What I want is to limit 50 requests per second per source ip, so for example if a specific source ip is sending 60rps, I want HAProxy to allow the first 50 requests and limit the rest (10) for each second separately.
I read the official documentation: Traffic policing | HAProxy config tutorials
so in haproxy.cfg I created a stick table (inside frontend https_in):
stick-table type ip size 100k expire 30s store http_req_rate(1s)
Then i added an http-request track directive to store the client’s IP address with their request count in the stick table:
http-request track-sc0 src
And then an http-request return directive of status 299 and custom message if someone makes over 50rps:
http-request return status 299 content-type “text/plain” lf-string “Rate limit exceeded.” if { sc_http_req_rate(0) gt 50 }
In order to test this setup, I am using a hey script which makes many requests per second for 10 seconds.
What I expect is HAProxy to allow 50rps and a total of 500 requests, because the test lasts for 10s.
When test is completed, the report shows that only 50 responses were allowed (status code 200) and the rest of them got rate limited with status code 299.
Same with Apache JMeter..I am sending 60rps for 10s, but only 50 were allowed, instead of 500.
Can you please help me? This is my frontend https_in block config in haproxy:
frontend https_in
bind *:443
ssl crt /etc/ssl/private/myssl.pem
mode http
maxconn 9000
option httplog
option forwardfor
log-format “%ci:%cp [%t] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Tt %ST %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq TLS:%[ssl_fc_protocol] %r”
stick-table type ip size 100k expire 30s store http_req_rate(1s)
http-request track-sc0 src
http-request return status 299 content-type “text/plain” lf-string “Rate limit exceeded.” if { sc_http_req_rate(0) gt 50 }
acl invalid_method method TRACE OPTIONS TRACK CONNECT DELETE PUT HEAD
http-request deny if invalid_method
http-request del-header X-Powered-By
http-request del-header Server
acl host_test1 hdr(host) -i test1.mycompany.com
acl host_test2 hdr(host) -i test2.mycompany.com
use_backend test1 if host_test1
use_backend test2 if host_test2
default_backend reject_backend