Reputation: 533
I'm trying to figure out a way to calculate how many QPS will happen at a certain time given that I am using Guava ratelimiter with warmpup. I read the comments here, but it's still unclear to me. Hopefully someone here can clarify for me.
My use case:
I call an external service which has a 50 TPS limit. The caveat is, the first ~500 times we call them must be well below the 50 TPS afterwards we can resume 50TPS. (If there is a better solution than using the ratelimiter, I'd love to hear it!)
Psuedocode:
RateLimiter rateLimiter = RateLimiter.create(50.0, 10, minutes);
for (String customerId : customerList) {
rateLimiter.acquire();
// call external service
}
Assuming we're only doing this with one thread. Is there a way to calculate what the TPS(QPS) will be at a given time? 3 minutes in? 5 minutes in? etc.
Upvotes: 3
Views: 3192
Reputation: 31234
The cold (minimum) rate of a RateLimiter
with a warmupPeriod
is 1/3 of the stable (maximum) rate (this is derived from the coldFactor
hardcoded to 3.0
in RateLimiter.java:147-184). Under saturated demand (i.e. uninterrupted requests for permits) the rate will increase at a constant rate until the stable (maximum) rate is reached.
As this is a linear equation we can write this in the form y = m * x + b
where
y
(a.k.a y(x)
), or qps(t)
), is our expected QPS given a saturated period (e.g. 3 minutes in),m
is the rate of change from our cold (minimum) rate to our stable (maximum) rate,x
(or t
) is the elapsed time under saturated demand, andb
is our cold (minimum) rate (1/3 of our stable (maximum) rate).Putting it altogether we have qps(t) = (stableRate - coldRate) / warmupPeriod * saturatedPeriod + coldRate
where coldRate = stableRate / 3
.
So for your example we can get the expected QPS at 3 minutes in:
qps(3) = (50.0 - 50.0/3.0) / 10.0 * 3.0 + 50.0/3.0 ~= 26.6666
Here is an implementation in Java:
/**
* Calculates the expected QPS given a stableRate, a warmupPeriod, and a saturatedPeriod.
* <p>
* Both specified periods must use the same time unit.
*
* @param stableRate how many permits become available per second once stable
* @param warmupPeriod the duration of the period where the {@code RateLimiter} ramps up
* its rate, before reaching its stable (maximum) rate
* @param saturatedPeriod the duration of the period for which the {@code RateLimiter} has
* been under saturated demand starting from a cold state
* @return The expected QPS assuming saturated demand starting from a cold state
*/
public static double qps(double stableRate, double warmupPeriod, double saturatedPeriod) {
if (saturatedPeriod >= warmupPeriod) {
return stableRate;
}
double coldRate = stableRate / 3.0;
return (stableRate - coldRate) * saturatedPeriod / warmupPeriod + coldRate;
}
Note that in practice using a single thread you will not be able to saturate the demand on a RateLimiter
so your actual QPS will be slightly lower than expected and will rarely (if ever) actually reach the stable (maximum) rate. Using multiple threads, however, will allow you to always have a pending permit request and saturate demand.
Upvotes: 4