FIELD NOTE 028TypeScriptReviewed July 2026

Throttle API Requests

Prevents excessive API calls by throttling requests to specified rate limit

Copy the complete example or adapt its typed interface to your project. Comments are kept inside the snippet so the intent travels with the code.

pattern.ts
/**
 * Throttle API requests with rate limiting
 * @param fn Async function to throttle
 * @param limit Maximum requests per minute
 * @returns Throttled async function
 */
function throttleApiRequests<T extends (...args: any[]) => Promise<any>>(
  fn: T,
  limit = 60 // 60 requests per minute (1 per second)
): T {
  const requestTimes: number[] = [];
  const interval = 60000 / limit; // Milliseconds between requests

  return async function(this: ThisParameterType<T>, ...args: Parameters<T>) {
    const now = Date.now();
    
    // Remove timestamps older than 1 minute
    requestTimes.filter(time => now - time < 60000);
    
    if (requestTimes.length >= limit) {
      const oldestRequest = requestTimes[0];
      const waitTime = interval - (now - oldestRequest);
      
      if (waitTime > 0) {
        await new Promise(resolve => setTimeout(resolve, waitTime));
      }
    }
    
    requestTimes.push(Date.now());
    return fn.apply(this, args);
  } as T;
}

// Usage Example
const fetchData = throttleApiRequests(async (url: string) => {
  const response = await fetch(url);
  return response.json();
}, 30); // 30 requests per minute

// Safe to call multiple times - will be throttled automatically
fetchData('https://api.example.com/data');
fetchData('https://api.example.com/data');
fetchData('https://api.example.com/data');

Critical for applications consuming APIs with rate limits, preventing 429 Too Many Requests errors

Implementation note

Review the input assumptions and browser or runtime support before adopting a utility unchanged. Small helpers are easiest to maintain when their contract stays narrow.

How it works

The queue tracks recent request timestamps and delays new work until the configured window has capacity. Each task eventually executes while call volume stays under the client-side rate policy.

What to watch for

A browser limiter cannot enforce a server quota across tabs, devices, users, or processes. Retries, cancellation, task failure, burst rules, clock behavior, and an unbounded queue all need deliberate production handling.

Production use

Use client throttling to reduce accidental bursts and improve interface feedback, never as the only protection for an API. The server remains authoritative and should return clear limit headers plus retry guidance.

Before you ship

  • Confirm the input contract with tests that cover empty, invalid, boundary, and representative real-world values before sharing the helper across a codebase.
  • Keep the function focused on one responsibility and name any project-specific policy explicitly instead of hiding it inside a generic-looking utility.
  • Measure behavior in the browsers or runtime versions your product supports, especially when timing, storage, DOM state, locale, or network access is involved.
  • Document the return type, mutation behavior, failure mode, and performance characteristics beside the call site so future maintainers can evaluate changes safely.
  • Compare the example with current official platform documentation when it relies on a browser API, language feature, or runtime behavior that may change over time.
  • If the helper crosses a trust boundary, validate again on the server and avoid treating browser-side checks, TypeScript annotations, or formatted output as a security guarantee.
  • Add a small regression test whenever a real edge case is discovered; concrete examples preserve the reason behind a guard more reliably than a general comment.