Skip to content

vsthrottle.is_denied is triggering with less requests per second than configured. #237

@ClemOzil

Description

@ClemOzil

Hey Guillaume, hope you're doing well.

Varnish version : 7.7
Varnish-module version : 0.26.0

We're using the vsthrottle module to add a global overall RQPS limit on our Varnish cache :

sub vcl_recv {
    if (vsthrottle.is_denied("global", 5000, 1s)) {
        std.log("rate_limit");
        return (synth(503, "Service Unavailable"));
    } else {
        std.log("ratelimit remaining: " + vsthrottle.remaining("global", 5000, 1s));
    }
}

When I start a ~4000 rqps benchmark run :

varnishstat looks like :

NAME                                              CURRENT        CHANGE       AVERAGE        AVG_10       AVG_100      AVG_1000 
MAIN.client_req                                       3927754       4194.72       3677.67       4013.30       4010.94       4010.94

AVERAGE, AVG_10, AVG_100 and AVG_1000 never goes over 4050.

But when I do :

varnishstat -1 -f MAIN.client_req

MAIN.client_req         651137      2615.01 Good client requests received
MAIN.client_req         655773      2623.09 Good client requests received
MAIN.client_req         659421      2627.18 Good client requests received
MAIN.client_req         662447      2628.76 Good client requests received
MAIN.client_req         666296      2633.58 Good client requests received

Already we can see some discrepancies between the values, but not the issue here.

I know that I'm doing ~4000 rqps, because I have full control on the tool that I use to simulate players.

Then I do

varnishlog

-   VCL_Log        ratelimit remaining: 180
-   VCL_Log        ratelimit remaining: 177
-   VCL_Log        ratelimit remaining: 172

After a few minutes, the "ratelimit remaining" log keeps on getting smaller and smaller even though the RQPS from my benchmark tool is staying at ~4000.

-   VCL_Log        ratelimit remaining: 3
-   VCL_Log        ratelimit remaining: 5
-   VCL_Log        ratelimit remaining: 4

Then I hit the vsthrottle.isdenied limit and I start to see 503 - Service unavailable.
In this state the "ratelimit remaining" oscillate between 200 and 0.

Around 10% of my requests are blocked, so around 400/seconds.

So, basically :

  • I use vsthrottle.is_denied("global", 5000, 1s)
  • I generate 4000 requests per second with my benchmark tool
  • varnishstat returns AVG_10,100,1000 = ~4000
  • varnishstat -1 -f MAIN.client_req returns a much lower value.
  • Around 10% of my requests end up being blocked even though I'm still kinda far from the limit.

After some testing, it feels like the higher the values (rqps and vsthrottle value), the more evident this issue is.
I hit a 100k rqps vsthrottle limit, with "only" ~75k real rqps.

Every exemple I've seen using this library has much much lower values, and is usually used to do a RQPS limit/client, not a global limit : https://docs.varnish-software.com/varnish-enterprise/vmods/vsthrottle/

Are you aware of such a limitation ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions