mockoon logo next to a clock and shield icon

Implement rate limiting with custom templates and rules

Learn how to implement rate limiting in your Mockoon APIs using custom templates and rules to control request frequency and protect your endpoints

In this tutorial, we will learn how to implement rate limiting in your Mockoon APIs using custom templates and rules to control request frequency and protect your endpoints from abuse.

Rate limiting is a crucial technique used to control the number of requests a client can make to an API within a specific time window. It helps prevent abuse, ensures fair usage, and protects your API from being overwhelmed.

In Mockoon, you can implement rate limiting using global variables to track request timestamps and counters, combined with template helpers and response rules to enforce the limits.

Let's explore different approaches to implement rate limiting, from simple time-based limits to more complex quota systems.

 1. Simple time-based rate limiting with templates

The simplest form of rate limiting is to limit requests based on time intervals. We'll create an endpoint that allows only one request every 500 milliseconds.

 Create a new endpoint

First, let's create a new HTTP GET route with the path /rate-limited:

new HTTP GET route showing the path /rate-limited

 Add the rate limiting template

In the response body, add the following template that implements time-based rate limiting:

Copy
{{#if (lt (subtract (now 'T') (getGlobalVar 'lastCall')) 500)}} {{status 429}} { "error": "Rate limit exceeded", "message": "Please wait at least 500ms between requests", "retry_after": 500 } {{else}} { "success": true, "message": "Request processed successfully", "timestamp": {{now 'T'}} } {{/if}} {{setGlobalVar 'lastCall' (now 'T')}}

This template uses our templating engine and does the following:

  • Checks the time difference between the current request and the last request using the following helpers: lt, subtract, now and getGlobalVar.
  • Returns a 429 status (Too Many Requests) if the interval is less than 500ms using the status helper.
  • Updates the timestamp for the next request using the setGlobalVar helper.
  • Provides helpful information about the rate limit in the JSON response.

template-based rate limiting response

 2. Rule-based rate limiting with multiple responses and a rule

For more complex scenarios, you can use response rules to serve different responses based on rate limiting conditions. The following example will use the same template as above but will use a response rule instead of conditional templating.

 Create a new endpoint with multiple responses

Create a new HTTP GET route with the path /rate-limited-rules:

new HTTP POST route showing the path /protected

 Add the default rate-limited response

The default response will handle rate-limited requests with a 429 status code and the following JSON body:

Copy
{ "error": "Rate limit exceeded", "message": "Too many requests.", "retry_after": 500 }

Set the status code to 429 for this response:

view of the response returning a 429 error

 Add a successful response with rate limiting rule

Add a new response by clicking the "Add response" button. Set the status code to 200 and add the following successful response JSON body:

Copy
{ "success": true, "message": "Request processed successfully" }

Now, click the "Rules" tab and add a "Custom templating" rule to check if enough time has passed since the last request. Custom rules allow you to define a target value to be evaluated using our templating engine. In the rule target field, enter:

Copy
{{gte (subtract (now 'T') (getGlobalVar 'lastCall')) 500}}{{setGlobalVar 'lastCall' (now 'T')}}

Then, set the rule value to true. This target will evaluate to true if at least 500 milliseconds have passed since the last request.

Similarly to the previous template, this rule does the following:

  • Checks if 500ms or more have passed since the last call using the following helpers: gte, subtract, now and getGlobalVar.
  • Updates the timestamp when the condition is met using the setGlobalVar helper.
  • Only serves the 200 response when the template evaluates to true.

view of the rule interface

 3. Testing your rate limiting implementations

To test your rate limiting, start your mock API server and use your favorite HTTP client to send multiple requests in quick succession.

 Testing the simple time-based limit

Send multiple GET requests to GET /rate-limited or GET /rate-limited-rules quickly:

Copy
curl -X GET http://localhost:3000/rate-limited

You should see:

  • First request: Success response (200)
  • Immediate second request: Rate limited response (429)
  • Request after 500ms: Success response (200)

 4. Advanced quota-based rate limiting

For more sophisticated rate limiting, let's implement a quota system that allows a configurable number of requests per time period.

 Create a data bucket for configuration

First, create a new data bucket to store the rate limiting configuration. Data buckets allow you to store and manage JSON data that can be accessed and manipulated in your templates and rules.

Go to the "Data" view, click "Add data", name it "rate_config" and add the following configuration:

Copy
{ "last_request_timestamps": [], "max_requests_per_seconds": 2 }

view of the new data bucket showing the above JSON template

This configuration allows 2 requests per second and will be used to track the timestamps of the last requests in the last_request_timestamps array.

 Create the quota-limited endpoint

Create a new HTTP GET route with the path /quota-limited:

Add the following advanced template to implement quota-based rate limiting:

Copy
{{setVar 'currentTime' (now 'T')}} {{setVar 'previousRequests' (dataRaw 'rate_config' 'last_request_timestamps')}} {{setVar 'maxRequests' (dataRaw 'rate_config' 'max_requests_per_seconds')}} {{setVar 'filteredTimestamps' (jmesPath (getVar 'previousRequests') (concat '[?to_number(@) > `' (subtract (getVar 'currentTime') 1000) '`]'))}} {{#if (gte (len (getVar 'filteredTimestamps')) (getVar 'maxRequests'))}} {{status 429}} { "error": "Quota exceeded", "message": "You have exceeded the rate limit of {{getVar 'maxRequests'}} per second." } {{else}} { "success": true, "message": "Request processed successfully" } {{/if}} {{setData 'push' 'rate_config' 'last_request_timestamps' (now 'T')}}

This template does the following:

  • Saves the current time and retrieves the previous request timestamps and the maximum requests per second from the rate_config data bucket using the dataRaw, setVar and now helpers.
  • Filters the timestamps to only include those within the last second using the jmesPath helper.
  • Checks if the number of requests in the last second exceeds the configured limit using the len and gte helpers.
  • Returns a 429 status (Too Many Requests) if the limit is exceeded, providing a detailed error message.
  • Pushes the last request timestamps in the rate_config array using the setData helper.

view of the above template in the user interface

 Testing the quota-based limit

Send multiple GET requests to /quota-limited:

Copy
curl -X GET http://localhost:3000/quota-limited

You should see a 429 response if you exceed the configured limit of 2 requests per second. The response will include information about the number of requests allowed.

 Going further

After completing this tutorial, you can enhance your rate limiting implementation by:

  • rate limiting based on user IP or other request attributes by storing request timestamps in a user-specific data bucket property, using the header or queryParam helpers.

  • Implementing more complex quota systems with different limits for different endpoints using a request path rule to serve different rate limits based on the request path.


By following this tutorial, you have learned how to implement rate limiting in Mockoon using custom templates and rules. You can now control request frequency, protect your APIs from abuse, and ensure fair usage across your endpoints. Experiment with different configurations and explore the flexibility of Mockoon's templating system to suit your specific rate limiting needs.

Download the example environment

You can download the example environment file created for this tutorial or directly open it in Mockoon desktop or CLI:

You might also be interested in these tutorials

Access environment variables in your templates

Learn how to access environment variables in your mock server templates to avoid exposing your API keys.

Read more

Validate your request payloads with JSON Schema

Learn how to validate your request payloads with JSON Schema in Mockoon to ensure your API clients send the correct data

Read more

Use persisting data buckets to share data across routes

Learn how to use Mockoon's data bucket feature to share data across routes and create more advanced scenarios with configuration endpoints

Read more