HTTP Interceptors for API Rate Limiting and Throttling

Understand the difference between API rate limiting and throttling, and how to apply both using HTTP interceptors in Angular and React. Use Requestly to simulate delays or throttling without code changes.

Get Started free
HTTP Interceptors for API Rate Limiting and Throttling
Home Guide HTTP Interceptors for API Rate Limiting and Throttling

HTTP Interceptors for API Rate Limiting and Throttling

APIs often receive traffic spikes that can overload servers, slow down responses, or trigger outages. To handle this, developers use rate limiting and throttling to control request flow, protect backend systems, and maintain stability.

This article explores API rate limiting vs API throttling and shows how to implement both using HTTP interceptors in Angular and React (with Axios).

What is API Rate Limiting?

API rate limiting is a mechanism that restricts the number of requests a client can make to a server within a fixed time window. For example, you might allow 100 requests per user per hour.

This is usually enforced on the backend using API gateways like NGINX, Kong, or managed services like AWS API Gateway.

Below is an example that explains how it works. Imagine GitHub’s API allows up to 60 requests per hour for unauthenticated users. If that limit is exceeded, it returns:

{

  "message": "API rate limit exceeded for 192.30.255.113",

  "documentation_url": "https://developer.github.com/v3/#rate-limiting"

}

Why Limit API Rate on the Client Side?

Client-side rate limiting is useful for:

  • Preventing accidental spamming from user actions
  • Reducing load before it hits the backend
  • Avoiding UI glitches due to repeated polling

Note: This alone will not block malicious users, but it will improve user experience and help you stay within third-party API quotas.

What is API Throttling?

API throttling delays or queues excessive requests instead of blocking them. If the user triggers multiple requests quickly, throttling ensures they are spread out over time.

This is useful when:

  • A user is typing in a search bar and triggers multiple API calls
  • A scroll event fetches paginated results on every small movement
  • You want to avoid overloading external APIs like GitHub or Google Maps

For example, suppose a user types “React” in a search field. Instead of firing 5 requests for every keystroke, throttling can ensure only 1 request is made every 500ms.

const throttledSearch = throttle((query) => {

  fetch(`/api/search?q=${query}`);

}, 500);

API Throttling vs API Rate Limiting: Key Differences

Rate limiting blocks requests after a fixed quota is crossed, while throttling controls the timing between requests to reduce sudden bursts. Here is a table highlighting the core differences between API throttling and API rate limiting.

FeatureAPI Rate LimitingAPI Throttling
GoalEnforce the maximum number of requests in a windowPrevent bursts by delaying or spacing requests
Behavior on Excess RequestsRejects with error (like HTTP 429)Delays or skips excessive requests
State ManagementNeeds counters and timestampsNeeds a timer and active request tracking
Reset StrategyBased on the time window expiryContinuous delay interval
Server Load ImpactCan block early and reduce loadCan still generate traffic, but spaced
Client Use CaseLimit user-triggered actions (like upload cap)Smooth UI interactions like autocomplete
Server Use CaseEnforce quotas and prevent abuseAvoid saturation during sudden request spikes
Feedback to UserOften includes quota info or retry headersUsually silent or with optional loading states
ExamplesGitHub, Twitter API quotasScroll loaders, search-as-you-type UIs

When To Implement API Rate Limiting vs. API Throttling

Choosing between throttling and rate limiting depends on user interaction patterns and the API’s sensitivity. Both can coexist, but knowing where each fits prevents unnecessary delays or overloads.

Use API Rate Limiting When:

  • You are consuming an API with hard limits (such as free-tier limits, SMS quotas).
  • Your backend must protect itself from excessive client load/
  • You want to enforce usage fairness across users or devices.
  • Requests beyond the limit should not be queued or retried.
  • You want to explicitly block certain actions after a threshold.

Use API Throttling When:

  • Users can trigger frequent events (keypress, mouse scroll) that map to API calls.
  • You want to reduce redundant calls during bursty input.
  • It’s acceptable to delay or skip certain intermediate states.
  • Your API supports high volume but benefits from spacing (example, UI remains snappy)
  • You want to reduce backend load without enforcing hard limits.

HTTP Interceptor Banner

How to Implement API Rate Limiting with HTTP Interceptors?

Client-side rate limiting is helpful when you want to reduce unnecessary traffic or enforce temporary caps before hitting the backend. This can be handled using HTTP interceptors in frameworks like Angular or middleware layers in libraries like Axios.

In both Angular and React, the interceptor runs before the request is sent and after receiving the response. This gives complete control over timing, retries, headers, or cancellation.

The goal is to limit outgoing requests per time window, typically using a request counter and a rolling or fixed timestamp window.

1. Rate Limiting Using Angular HTTP Interceptor

In Angular, you can set up rate limiting by creating a custom HttpInterceptor that tracks request timestamps and rejects requests once the configured limit is exceeded.

Here’s how to set it up

// rate-limit.interceptor.ts

import { Injectable } from '@angular/core';

import {

  HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse

} from '@angular/common/http';

import { Observable, throwError } from 'rxjs';




@Injectable()

export class RateLimitInterceptor implements HttpInterceptor {

  private timestamps: number[] = [];

  private MAX_REQUESTS = 5;

  private TIME_WINDOW_MS = 10000; // 10 seconds




  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const now = Date.now();

    this.timestamps = this.timestamps.filter(ts => now - ts < this.TIME_WINDOW_MS);




    if (this.timestamps.length >= this.MAX_REQUESTS) {

      return throwError(() => new HttpErrorResponse({

        status: 429,

        statusText: 'Too Many Requests',

        error: 'Rate limit exceeded'

      }));

    }




    this.timestamps.push(now);

    return next.handle(req);

  }

}

Then, apply it in the App Module.

// app.module.ts

import { HTTP_INTERCEPTORS } from '@angular/common/http';

import { RateLimitInterceptor } from './rate-limit.interceptor';




@NgModule({

  providers: [

    { provide: HTTP_INTERCEPTORS, useClass: RateLimitInterceptor, multi: true }

  ]

})

export class AppModule {}

You can also narrow the logic to restrict rate limiting to specific routes by applying only to routes like /search.

if (req.url.includes('/search')) {

  // Apply rate limiting only to search requests

}

This prevents unrelated requests from being blocked. For more flexibility, define per-route thresholds in a config file or service.

2. Rate Limiting in React Using Axios Interceptor

In React, Axios does not maintain persistent shared state across interceptors. So you need to manage request timestamps manually to apply rate-limiting logic.

Here’s how to set it up:

// rateLimiter.js

import axios from 'axios';




const timestamps = [];

const MAX_REQUESTS = 5;

const TIME_WINDOW_MS = 10000;




axios.interceptors.request.use((config) => {

  const now = Date.now();

  const recent = timestamps.filter(ts => now - ts < TIME_WINDOW_MS);




  if (recent.length >= MAX_REQUESTS) {

    return Promise.reject({

      status: 429,

      message: 'Rate limit exceeded',

    });

  }




  timestamps.push(now);

  return config;

});

This blocks any request if more than five are made within ten seconds.

If you want finer control for specific components, use a wrapper around Axios that enforces the same logic:

const rateLimitedAxios = async (config) => {

  const now = Date.now();

  timestamps = timestamps.filter(ts => now - ts < TIME_WINDOW_MS);




  if (timestamps.length >= MAX_REQUESTS) {

    throw new Error('Rate limit exceeded');

  }




  timestamps.push(now);

  return axios(config);

};

Here is an example of disabling a button when the rate limit is reached:

const handleClick = async () => {

  try {

    await rateLimitedAxios({ url: '/api/submit', method: 'POST' });

  } catch (err) {

    alert('You hit the request limit');

  }

};

This is useful in places like search inputs, submit buttons, or pagination controls where the user can repeatedly trigger requests.

How to Implement API Throttling with HTTP Interceptors

Throttling allows only one request to go through in a fixed time interval and delays or drops others. This is useful for endpoints like live search or data sync, where frequent input changes can cause excessive API calls.

1. API Throttling in Angular Using HTTP Interceptor

To implement throttling in Angular, modify the HttpInterceptor to enforce a minimum gap between consecutive requests.

Here’s how to implement it:

// throttle.interceptor.ts

import { Injectable } from '@angular/core';

import {

  HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse

} from '@angular/common/http';

import { Observable, throwError } from 'rxjs';




@Injectable()

export class ThrottleInterceptor implements HttpInterceptor {

  private lastRequestTime = 0;

  private MIN_INTERVAL_MS = 2000; // 2 seconds




  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const now = Date.now();

    if (now - this.lastRequestTime < this.MIN_INTERVAL_MS) {

      return throwError(() => new HttpErrorResponse({

        status: 429,

        statusText: 'Too Many Requests',

        error: 'Throttling: Please wait before sending another request'

      }));

    }




    this.lastRequestTime = now;

    return next.handle(req);

  }

}

Then, apply it in the App Module:

// app.module.ts

import { HTTP_INTERCEPTORS } from '@angular/common/http';

import { ThrottleInterceptor } from './throttle.interceptor';




@NgModule({

  providers: [

    { provide: HTTP_INTERCEPTORS, useClass: ThrottleInterceptor, multi: true }

  ]

})

export class AppModule {}

To restrict throttling only to certain endpoints, wrap the check:

if (req.url.includes('/live-search')) {

  // Apply throttling here

}

This helps prevent unrelated requests from being delayed.

2. API Throttling in React Using Axios Interceptor

In React, Axios interceptors can throttle requests by comparing the current timestamp with the last request’s time.

Here’s how to set it up:

// throttleInterceptor.js

import axios from 'axios';




let lastRequestTime = 0;

const MIN_INTERVAL_MS = 2000; // 2 seconds




axios.interceptors.request.use((config) => {

  const now = Date.now();

  if (now - lastRequestTime < MIN_INTERVAL_MS) {

    return Promise.reject({

      status: 429,

      message: 'Throttling: Too many requests',

    });

  }




  lastRequestTime = now;

  return config;

});

This interceptor blocks requests made within the throttle interval.

For selective throttling or component-level logic, wrap the same logic in a function:

const throttledAxios = async (config) => {

  const now = Date.now();

  if (now - lastRequestTime < MIN_INTERVAL_MS) {

    throw new Error('Throttling: Try again later');

  }




  lastRequestTime = now;

  return axios(config);

};

Here is an example of applying it to a live search input:

const handleInputChange = async (e) => {

  const query = e.target.value;

  try {

    await throttledAxios({ url: `/api/search?q=${query}` });

  } catch (err) {

    console.log('Throttled');

  }

};

This ensures one search request is sent every few seconds, even if the user types rapidly.

API Rate Limiting and Throttling Using Requestly

Requestly is a browser extension that lets you control how HTTP requests behave on the client side without editing your app code. It allows you to introduce artificial delay or simulate throttling during local development or staging. You can also create rules to delay, block, or modify requests based on URL, method, type, and more.

Here’s how to simulate throttling using Requestly’s Delay Network Requests rule.

  • Install the Requestly Extension: Install Requestly from the Chrome Web Store or visit requestly.io to get the extension.
  • Create a New Delay Rule: After installing, open the Requestly dashboard and click Create Rule. Select Delay Network Requests from the available rule types.

Simulate throttling in Requestly with custom delays

  • Define the Request Match Conditions: 
    • URL Filter: Match requests using Contains, Wildcard, Regex, or Equals.
      For example, use *api/search* to target all search endpoints.
    • Delay Time: Set how long to delay each request in milliseconds.
      For example, 2000 adds a 2-second delay.
    • Request Type Filter: You can restrict the rule to affect only XHR or fetch requests.
    • Method Filter (optional): You can apply the delay only to GET, POST, or any specific HTTP method.
  • Apply the Rule: Click Create Rule and ensure it’s toggled ON. Open your application in a new tab and use browser dev tools to verify delays in the Network tab.

Here’s an example that explains how to delay every API call made to a search endpoint:

  • Rule Type: Delay Network Requests
  • URL: */api/search* (Wildcard match)
  • Delay: 2000 ms
  • Request Type: XHR
  • Apply On: Only pages under your development domain, such as localhost:3000 or staging.example.com

This lets you test how your app handles slow responses in real time, especially useful for search inputs, typeahead, or pagination.

Requestly also lets you combine a delay rule with other rule types. For example, you can:

  • First, delay a request to /api/user by 3000 ms.
  • Then, modify the headers of that same request to simulate expired tokens.
  • Or mock the response after the delay using a mock rule.

This chaining is helpful when you want to test how your frontend behaves when both timing and data change in the same flow.

You don’t need to write custom interceptors or edit backend logic for any of this. Just enable or disable rules directly from the extension UI.

Talk to an Expert

Conclusion

API rate limiting and throttling help control traffic, protect resources, and improve client behavior. With HTTP interceptors in Angular or React, you can enforce limits directly on the frontend without server changes. This makes handling scenarios like rapid user input, background polling, or misconfigured integrations easier.

Requestly offers a no-code option for testing and simulation to delay, block, or alter HTTP requests directly in the browser. You can build complex test flows using delay, header modification, or mock response rules without modifying app code. It’s especially effective for validating how the UI reacts to network constraints or failure cases during development.

Try Requestly for Free

Tags
Automation Testing Testing Tools Types of Testing UI Testing

Get answers on our Discord Community

Join our Discord community to connect with others! Get your questions answered and stay informed.

Join Discord Community
Discord