Skip to main content

Protecting Your API with Rate-Limit and Slow-Down

· 6 min read
Adrian Escutia
Rebel Innovator

Imagine you're waiting in line at a coffee shop. There's a customer in front of you who keeps ordering one drink after another, hogging the cashier's time while everyone else waits. Eventually, the barista tells them to wait a few minutes before placing another order, and if they persist, they're asked to leave. This is how rate-limiting and slow-down work in the API world: they ensure no single user can hog all the resources, protecting your system from being overwhelmed.

In today's world of high-traffic apps and services, it's vital to prevent abuse and overuse of your servers. Without these protections, a few users or malicious actors can degrade the experience for everyone. Rate-limiting and request slow-downs help regulate API usage, providing a fair environment for all users.

Let’s dive into why this is important and how you can easily implement it using express-rate-limit and express-slow-down in your Express.js application.


Why Implement Rate Limiting and Slow-Down?

APIs, by nature, can be accessed by multiple users simultaneously. But what happens when one user sends too many requests too quickly, or worse, when a malicious actor tries to flood your system with traffic (a DDoS attack)? Your server resources can get consumed rapidly, causing performance issues for legitimate users.

This is where rate-limiting and slow-down techniques come in handy:

  • Rate-Limiting: Like a bouncer at a club, it blocks a user after a certain number of requests in a set time period.
  • Slow-Down: If users start sending too many requests, it adds delays between responses, encouraging them to back off without cutting them off completely.

Together, these techniques provide an effective way to balance user traffic, protect against abuse, and ensure fair use of your API.


Step-by-Step: How to Implement Rate-Limiting and Slow-Down in Express.js

Let’s walk through how you can implement these techniques in your Express.js app to protect your APIs.

Step 1: Install Dependencies

First, you need to install the necessary libraries:

npm install express express-rate-limit express-slow-down
  • express-rate-limit: Limits the number of requests a user can make within a set time period.
  • express-slow-down: Slows down responses for users who make too many requests in a short time, by adding delays.

Step 2: Set Up a Basic Express Server

Create a new file called index.js or app.js and set up a basic Express server:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
res.send('Hello, World!');
});

app.listen(port, () => {
console.log(`Server running on port ${port}`);
});

Step 3: Configure express-rate-limit

Now, let's configure express-rate-limit to limit how many requests a user can make in a specific time window. For example, we’ll allow 100 requests per 15 minutes:

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per windowMs
message: 'Too many requests, please try again later.',
});

Step 4: Configure express-slow-down

Next, set up express-slow-down to add delays after a certain number of requests. Let’s configure it to add a delay of 500ms after 50 requests in 15 minutes:

const slowDown = require('express-slow-down');

const speedLimiter = slowDown({
windowMs: 15 * 60 * 1000, // 15 minutes
delayAfter: 50, // After 50 requests, start slowing down
delayMs: 500, // Add 500ms delay per request after 50
});

Step 5: Apply Middleware to Routes

You can now apply the rate-limiter and speed limiter to your routes. You can either apply them globally or to specific routes.

Apply Globally:

app.use(limiter); // Rate limit applied globally
app.use(speedLimiter); // Slow down applied globally

Apply to Specific Routes:

If you want to apply these protections to specific routes only (e.g., an API endpoint), do this:

app.get('/api', limiter, speedLimiter, (req, res) => {
res.send('This is an API endpoint with rate limiting and slow down!');
});

Step 6: Test Your Implementation

Your Express.js app should now look like this:

const express = require('express');
const rateLimit = require('express-rate-limit');
const slowDown = require('express-slow-down');

const app = express();
const port = 3000;

// Rate Limiter
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per windowMs
message: 'Too many requests, please try again later.',
});

// Slow Down
const speedLimiter = slowDown({
windowMs: 15 * 60 * 1000, // 15 minutes
delayAfter: 50, // Allow 50 requests, then start slowing down
delayMs: 500, // Add 500ms delay per request after 50
});

// Apply middlewares
app.use(limiter);
app.use(speedLimiter);

app.get('/', (req, res) => {
res.send('Hello, World!');
});

app.get('/api', (req, res) => {
res.send('This is an API endpoint with rate limiting and slowdown!');
});

app.listen(port, () => {
console.log(`Server running on port ${port}`);
});

Practical Scenarios

Scenario 1: Preventing DDoS Attacks

Imagine your API is hit by a sudden surge of requests from a malicious bot. Without rate limiting, this flood of traffic could overwhelm your server, taking it offline. Rate-limiting ensures that each IP address can only make a certain number of requests in a defined period, preventing your API from being overwhelmed.

Scenario 2: Encouraging Fair Use

Let’s say you’re offering a free tier of your API with limits on how many requests users can make. Rate-limiting ensures that users adhere to those limits. By combining this with slow-down, you can gently nudge users towards better behavior by delaying excessive requests instead of cutting them off entirely.


Why This is Critical for Your API's Health

Security: Your API is vulnerable to abuse, whether intentional (DDoS) or accidental (high-traffic spikes). Rate-limiting and slow-down mechanisms serve as gatekeepers, ensuring that all users have fair access while protecting your infrastructure.

Performance: APIs are meant to be fast and efficient, but overloading your server with too many requests can degrade performance for all users. Slowing down repeated requests ensures everyone gets a smooth experience.

Fairness: Whether it’s a free-tier user hitting their limits or a rogue actor trying to exploit your API, these protections ensure that your server isn’t overloaded by a few bad actors.


Conclusion

Rate-limiting and slow-down mechanisms are critical for any public-facing API. By controlling traffic, you can protect your server, improve user experience, and ensure fairness across all users. Implementing these techniques in Express.js is straightforward with express-rate-limit and express-slow-down. Now, your API can serve more users safely and efficiently while maintaining the performance and security your business relies on.


Let us know your thoughts

By continuing you agree to our

Privacy Policy