Tutorials

AWS Lambda Rate Limiting with Serverless Redis

In this tutorial, we will deploy a AWS Lambda function ratelimited based on the client's IP address using @upstash/ratelimit and Serverless Framework.

Prerequisites

  1. Install the Serverless Framework with npm i serverless -g

Project Setup

Create a Serverless Framework application with the following options:

  tutorials > serverlessServerless ϟ FrameworkWelcome to Serverless Framework V.4Create a new project by selecting a Template to generate scaffolding for a specific use-case. Select A Template: · AWS / Node.js / HTTP API Name Your Project: · ratelimit-serverless Template Downloaded Create Or Select An Existing App: · Create A New App Name Your New App: · ratelimit-serverlessYour new Service "ratelimit-serverless" is ready. Here are next steps: Open Service Directory: cd ratelimit-serverless Install Dependencies: npm install (or use another package manager) Deploy Your Service: serverless deploy
cd ratelimit-serverless

Create package.json with @upstash/ratelimit as a dependency:

package.json
{    "dependencies": {      "@upstash/ratelimit": "latest",      "@upstash/redis": "latest"    }  }

Install the dependencies:

npm install

Database Setup

Create a Redis database using Upstash Console or Upstash CLI and copy the UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN into your .env file.

.env
UPSTASH_REDIS_REST_URL=<YOUR_URL>UPSTASH_REDIS_REST_TOKEN=<YOUR_TOKEN>

Ratelimited Function Setup

Update handler.js:

handler.js
const { Ratelimit } = require("@upstash/ratelimit");const { Redis } = require("@upstash/redis");const ratelimit = new Ratelimit({  redis: Redis.fromEnv(),  limiter: Ratelimit.slidingWindow(10, "10 s"),  prefix: "@upstash/ratelimit",  analytics: true,});exports.ratelimit = async (event) => {  const identifier = event.requestContext.http.sourceIP;  const { success, limit, remaining, pending } = await ratelimit.limit(    identifier  );  const response = {    success: success,    limit: limit,    remaining: remaining,  };  // pending is a promise for handling the analytics submission  await pending;  if (!success) {    return {      statusCode: 429,      body: JSON.stringify(response),    };  }  return {    statusCode: 200,    body: JSON.stringify(response),  };};

Update serverless.yml to pass the environment variables:

serverless.yml
service: ratelimit-serverlessprovider:  name: aws  runtime: nodejs20.x  environment:    UPSTASH_REDIS_REST_URL: ${env:UPSTASH_REDIS_REST_URL}    UPSTASH_REDIS_REST_TOKEN: ${env:UPSTASH_REDIS_REST_TOKEN}functions:  ratelimit:    handler: handler.ratelimit    events:      - httpApi:          path: /          method: get

Developing

Run the following command to start your dev session.

serverless dev

Deployment

Run the following command to deploy your service.

serverless deploy

Visit the output url.

Loading search…