Understanding show table output and rate limiting weirdness

Hello guys,

I’m using the docker image 2.5.7-2ef551d with basic rate limiting configured like this:

backend test
  acl test_rate_limit_by_ip_exceeds_limit src,table_http_req_rate(test_rate_limit_by_ip) gt 50000
  http-request deny deny_status 429 if test_rate_limit_by_ip_exceeds_limit
  http-request track-sc0 src table test_rate_limit_by_ip

  acl test_rate_limit_api_exceeds_limit req.hdr(authorization),table_http_req_rate(test_rate_limit_api) gt 100
  http-request deny deny_status 429 if test_rate_limit_api_exceeds_limit
  http-request track-sc1 req.hdr(authorization) table test_rate_limit_api if { path -i -m beg "/api" }

  acl test_rate_limit_graphql_exceeds_limit req.hdr(x-api-key),table_http_req_rate(test_rate_limit_graphql) gt 100
  http-request deny deny_status 429 if test_rate_limit_graphql_exceeds_limit
  http-request track-sc2 req.hdr(authorization) table test_rate_limit_graphql if { path -i -m beg "/graphql" }

  server s1 10.0.0.1:80
  server s2 10.0.0.2:80

backend test_rate_limit_by_ip
  stick-table type ipv6 size 1m expire 24h store http_req_rate(5m)

backend test_rate_limit_api
  stick-table type string size 1m expire 24h store http_req_rate(3m)

backend test_rate_limit_graphql
  stick-table type string size 1m expire 24h store http_req_rate(3m)

Now I have some users reporting they are blocked (getting a 429) even though they don’t perform a lot of requests. To analyze I ran show table table_rate_limit_by_ip, but the output looks a bit weierd to me. Here’s an anonymized extract:

0x55cfd58df130: key=::ffff:1.2.3.1 use=0 exp=1498762521 http_req_rate(300000)=1181926
0x55cfd627f840: key=::ffff:1.2.3.2 use=0 exp=1599966154 http_req_rate(300000)=80740
0x55cfda287e00: key=::ffff:1.2.3.3 use=0 exp=58273431 http_req_rate(300000)=0
0x55cfd5cd5320: key=::ffff:1.2.3.4 use=0 exp=2006327751 http_req_rate(300000)=1606589
  1. What’s the value of exp? It doesn’t seem to be a unix timestamp (not even in milliseconds), nor does it seem to be the number of (milli)seconds till the entry expires. Unfortunately, I can’t find any documentation about it.

  2. The http_req_rate (which should be the rate within the last 5 minutes for this table) is extremely (unrealistic) high for many entries. How is this possible?

Is my configuration broken? Is it a bug? …?

Thanks for any help,
Corin

PS: Is there any way to filter the output of show table table_rate_limit_by_ip by key (by ip in my case)? In the docs, I only find how to filter by value (by http_req_rate in my case).

exp returns the milliseconds until an entry in the table becomes invalid.

I have also observed this situation and can not explain it.

I have observed that the rate is not calculated correctly, perhaps these problems are related.
My opened Github-Issue: The rate calculation in stick-tables is not correct · Issue #1913 · haproxy/haproxy · GitHub