UPDATE: We have developed
Upstash Rate Limiting SDK. We recommend
it with Upstash Redis.
In this tutorial, we will throttle AWS Lambda functions using Serverless Redis
based on the client’s IP address.
See
code.
See demo.
1
Serverless Project Setup
If you do not have it already, install serverless framework via:
npm install -g serverless
In any folder run serverless
as below:
>> serverless
Serverless: No project detected. Do you want to create a new one? Yes
Serverless: What do you want to make? AWS Node.js
Serverless: What do you want to call this project? serverless-rate-limiting
Project successfully created in 'serverless-rate-limiting' folder.
You can monitor, troubleshoot, and test your new service with a free Serverless account.
Serverless: Would you like to enable this? No
You can run the “serverless” command again if you change your mind later.
See Using AWS SAM, if you prefer AWS SAM
over Serverless Framework.
Inside the project folder create a node project with the command:
Then install the redis client and rate limiting libraries with:
npm install ioredis async-ratelimiter request-ip
Update the serverless.yml
as below. Copy your Redis URL from console and
replace below:
service: serverless-rate-limiting
frameworkVersion: "2"
provider:
name: aws
runtime: nodejs12.x
lambdaHashingVersion: 20201221
functions:
hello:
handler: handler.hello
events:
- httpApi:
path: /hello
method: get
For the best performance choose the same region for your Lambda function and
Upstash database.
2
Create a Redis (Upstash) Database
Create a database from Upstash console
3
Code
Edit handler.js and replace your REDIS_URL below.
This example uses ioredis, you can copy the connection string from the
Node tab in the console.
const RateLimiter = require("async-ratelimiter");
const Redis = require("ioredis");
const { getClientIp } = require("request-ip");
const rateLimiter = new RateLimiter({
db: new Redis("YOUR_REDIS_URL"),
max: 1,
duration: 5_000,
});
module.exports.hello = async (event) => {
const clientIp = getClientIp(event) || "NA";
const limit = await rateLimiter.get({ id: clientIp });
if (!limit.remaining) {
return {
statusCode: 429,
body: JSON.stringify({
message: "Sorry, you are rate limited. Wait for 5 seconds",
}),
};
}
return {
statusCode: 200,
body: JSON.stringify({
message: "hello!",
}),
};
};
Above, we have configured the rate limiting to accept 1 request from the same IP
address in 5 seconds.
4
Deploy and Try the API
Deploy your functions with:
The command will deploy the function and show the endpoint url. Click to the
endpoint url. If you refresh your page, you will see that your request is
throttled.