---
# System prepended metadata

title: Token Buckets Test plan

---

# Token Buckets Test plan

## Constant Arrival Rate
- Set to 30 seconds
- Doubling the amount until it breaks, then look for the optimal value.
- The container has 2000 maximum RUs/s share by all the collections.


### Local Application

The fist round was 100 reqs/s. The application managed it without any issues. The median request took 142ms, while the longest took 480ms.

The test took 30 seconds, but the DB itself took 7 minutes to complete all patch operations.

It was found that about 130 reqs/s was the limit.

### Azure Function Apps

The first round was 200 reqs/s. The application failed for several rounds, yielding an error on IRepository's CreateAsync method. It is possibly related to a 429 errorn on Cosmos, but all logs (even Azure's) registers an error code 500.

It was found the limit is about 150 reqs/s. This was the number where the first 500 errors appeared.

## Burst
- Doubling the amount of VUs and iterations that are made in one go, until it breaks.

### Local Application

For a burst of 400 requests, all of them were succesful.

The application maintained about 130 reqs/s, taking a median of 1.9 seconds.

It took 1 minute and 56 seconds for azure to process all patch operations.


### Azure Function Apps

For a burst of 400 requests, all of them were successful.

The application maintained about 180 reqs/s, with a median of 1.48 seconds per request.

It took 6 seconds for Cosmos to process all patch operations.

With a burst of 800, the application maintained 150 reqs/s, with a median of 2.91 seconds per request. Cosmos took 20 seconds to process all patch operations.

## Conclusions

This test highlights a clear advantage of the new flow.

Previously, the same flow was responsible for creating the transactions, and also making the Bucket entity changes. 

One thing to note is that, even with a huge volume of patch operations, no timeouts from Cosmos were noticed. But when the application was forcefully stopped, all patch operations ceased. The patch operations resumed after the application was restarted. This restart happened even when the Function App was started instead of the local application.

The patch operations resulted in no timeouts whatsoever, no matter how long the operations would take. With the old flow, the default timeout of 30 seconds would be enforced if the connection waited for a late patch operation to conclude.

This advantage greatly improves the client's waiting time overall. Now, the client doesn't need to wait for the bucket to update before receiveing a callback of success. Most of the work happens in the background.

In the design side of things, having two different flows handling two different types of operation makes the overall application much more resilient and elegant.