# Throttling from several clients, based on url

**URL:** <https://discourse.haproxy.org/t/throttling-from-several-clients-based-on-url/2973>\
**Category:** Help!\
**Created:** [September 10, 2018, 12:56pm UTC](https://discourse.haproxy.org/t/throttling-from-several-clients-based-on-url/2973 "2018-09-10T12:56:22Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![lewe](https://avatars.discourse-cdn.com/v4/letter/l/3be4f8/32.png) [@lewe](https://discourse.haproxy.org/u/lewe)\
**Post date:** [September 10, 2018, 12:56pm UTC](https://discourse.haproxy.org/t/throttling-from-several-clients-based-on-url/2973/1 "2018-09-10T12:56:22Z")

</div>

Hi,

despite many examples and reading the haproxy docs, I still don’t manage to do the following:

note that we use haproxy 1.5.14

we use haproxy to distribute HTTP requests (roundrobin) over a number of backends.  
I would like to limit the number of HTTP requests on the frontend, regardless from which IP address they are coming.

Initially I used something like:

#frontend:  
stick-table type ip size 500k expire 2s store http\_req\_rate(1s)  
tcp-request connection track-sc1 src

#backend  
timeout tarpit 1000  
acl abuse\_xxx src\_http\_req\_rate(frontend\_name) ge 5  
http-request tarpit if abuse\_xxx

This worked when sending requests from 1 ip address, in this case allowing 5 requests per second.

As far as I understand, the stick-table type ip counts entries per IP address. We don’t want this, throttling has to be done on the total number of HTTP requests, independent from the client ip.

To throttle on the total, I expect I need to use the url path in some way, as these are the same for each client, only the client ip address differs.

So far I did not manage to do so, when using stick tables with type string, I did not find a way to store entries in this table in the frontend, when adding entries to the backend, socat shows 1 entry per request instead of a total.

so: I need some guidance here 🙂

Leon

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [September 10, 2018, 3:22pm UTC](https://discourse.haproxy.org/t/throttling-from-several-clients-based-on-url/2973/2 "2018-09-10T15:22:55Z")

</div>

I assume that your intention is to protect your backend server from overload. Is that correct? In that case, you are asking all the wrong questions. Request per seconds is not the correct metric to avoid overloading your server, concurrent (in flight) requests are.

You’d find out how many concurrent requests your backend server can handle, and then use maxconn to limit that number. If you server doesn’t handle concurrency well at all, you may even set the per server maxconn value to 1 (but whether this is a good idea for your deployment is something that you need to find out).

Then it’s as simple as setting the value:

```
backend blablabla
 server s1 192.168.1.100:80 check maxconn 20

```

On the other hand, stick table based abuse detection is there so that you can limit the request per source-IP, which is explicitly not what you want.

---

<div class="post-metadata">

**Author:** ![lewe](https://avatars.discourse-cdn.com/v4/letter/l/3be4f8/32.png) [@lewe](https://discourse.haproxy.org/u/lewe)\
**Post date:** [September 11, 2018, 9:09am UTC](https://discourse.haproxy.org/t/throttling-from-several-clients-based-on-url/2973/3 "2018-09-11T09:09:21Z")

</div>

Hi Lukas,

thanks for your fast reply, I was on the wrong track then, apparently.  
As indeed the idea was to protect the backend from overload.

Still, when trying your proposal, for testing I put the maxconn to 1

backend backend-xxx  
log global  
mode http  
balance roundrobin

```
server s1 172.16.1.3:38080 check maxconn 1
server s2 172.16.1.4:38080 check maxconn 1

```

I use SOAPUI to send HTTP requests with 10 threads in parallel to my frontend, and see 5 connections setup to each backend, where I would expect only 1 per backend,  
can you explain why?

tcp 0 0 172.16.1.1:54560 172.16.1.3:38080 ESTABLISHED 32130/haproxy  
tcp 0 0 172.16.1.1:54562 172.16.1.3:38080 ESTABLISHED 32130/haproxy  
tcp 0 0 172.16.1.1:54564 172.16.1.3:38080 ESTABLISHED 32130/haproxy  
tcp 0 0 172.16.1.1:54570 172.16.1.3:38080 ESTABLISHED 32130/haproxy  
tcp 0 0 172.16.1.1:54573 172.16.1.3:38080 ESTABLISHED 32130/haproxy  
tcp 0 0 172.16.1.1:57037 172.16.1.4:38080 ESTABLISHED 32130/haproxy  
tcp 0 0 172.16.1.1:57039 172.16.1.4:38080 ESTABLISHED 32130/haproxy  
tcp 0 0 172.16.1.1:57041 172.16.1.4:38080 ESTABLISHED 32130/haproxy  
tcp 0 0 172.16.1.1:57047 172.16.1.4:38080 ESTABLISHED 32130/haproxy  
tcp 0 0 172.16.1.1:57050 172.16.1.4:38080 ESTABLISHED 32130/haproxy

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [September 11, 2018, 9:21am UTC](https://discourse.haproxy.org/t/throttling-from-several-clients-based-on-url/2973/4 "2018-09-11T09:21:14Z")

</div>

`maxconn 1` guarantees that there are no more than 1 concurrent connections to the server at any given time. It does not multiplex or pool connections from different frontend connection to a single backend connection however.

Also, when the client closes the connection, the backend connection closes as well.

So it looks like your client did not use keepalive between the request (or maybe the server closed the connection), and that round-robin distributes the request fairly.
