Urgent.News

What's breaking now, across thousands of outlets.

Tech

API rate limiting: patterns, algorithms, and how to do it right

Cross-post. Original: stellarbytecapital.com/blog/api-rate-limiting Rate limiting looks trivial — "just count requests and block over N" — and quietly turns into a distributed-systems problem the moment you have more than one server, bursty traffic, or clients you actually care about. Done well, it protects your API from abuse and absorbs spikes without punishing legitimate callers. Done naively,…

Cross-post. Original: stellarbytecapital.com/blog/api-rate-limiting

Rate limiting may seem straightforward—just tally requests and halt when the count exceeds N—but it swiftly evolves into a distributed-systems challenge once multiple servers are in play, traffic becomes sporadic, or clients truly matter. When executed properly, it safeguards an API against misuse and mitigates spikes without penalizing genuine callers. However, when executed poorly, it suppresses legitimate requests, permits illicit ones, and deceives clients regarding when they can retry.

The primary objectives to safeguard depend on the desired outcome:

- Overload protection—prevents a traffic surge from crashing the service.

- Fair usage—prevents a noisy client from monopolizing resources, starving others.

- Abuse prevention—blocks brute-force attempts, scraping, and credential stuffing.

- Cost control—limits expensive endpoints, such as large language model calls or reports.

The core algorithms for rate limiting comprise:

- Fixed window: Counts requests per calendar interval (e.g., 100 requests per minute) and resets at the minute. Although simple, it fails to account for bursts, allowing a client to send 100 requests at the window's start and another 100 at the window's end, totaling 200 requests per second.

- Sliding window: Implements a rolling window instead of a fixed time frame and subtly smooths the count over time. It's more accurate but requires additional state management.

- Token bucket: Usually the preferred default algorithm. It maintains a bucket of up to N tokens that replenish at a steady rate. Each request consumes one token. This approach accommodates bursty behavior by enabling clients to accumulate tokens during quiet periods and utilize them during spikes. The leaky bucket variant enforces a steady output rate, ideal for downstream systems sensitive to bursts.

The primary challenge arises in distributed rate limiting. A per-instance counter in memory suffices until more than one server is introduced. In such cases, the per-instance limit escalates to N per second, where N is the number of instances. To address this, centralize the counter using Redis with atomic operations or Lua scripts to prevent race conditions that could result in double-counting.

However, trade-offs must be considered. Perfectly synchronized global limits introduce a latency penalty due to network overhead, while approximate local limits may exhibit slight overshoot but offer better performance. Rate limiting must also be scoped appropriately; typically, limits are defined per API key or user for fairness and billing purposes, per IP address to curb anonymous abuse (with caution when dealing with NATs or proxies), and per endpoint to establish tighter budgets for resource-intensive routes.

The client-facing response to rate limiting should adhere to HTTP standards:

- Return 429 (Too Many Requests) instead of generic 400 or 503 status codes.

- Include a Retry-After header to inform clients when to retry their requests.

- Expose rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) to enable clients to proactively pace themselves without exceeding limits.

Certain practices should be avoided, such as using fixed windows for critical rate limiting scenarios to prevent burst loopholes, relying on per-instance in-memory counters behind load balancers that can exceed configured limits, employing non-atomic check-then-increment operations susceptible to undercounting under heavy load, or implementing silent drops or incorrect status codes that hinder client back-off mechanisms.

Lastly, avoid applying a single global limit to all API calls without differentiation based on client identity or endpoint importance.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

How Traceroute Actually Works

The Internet is not One Wire When you open a website, it feels instant and it feels like one step. In reality, that request hops through a chain of routers — your home router, your ISP's equipment…

  • Traceroute identifies network latency by mapping data packet paths.
  • It uses TTL field to drop packets at each hop, revealing IP addresses.
  • ICMP error messages provide hop information, but may be blocked by routers.

rulereceipt

I'm building RuleReceipt, a tool that helps manage rules/configs across AI coding assistants (Claude, Copilot, Cursor, etc.) so you don't have to duplicate setup per tool. It's in early stages.

The undo has to exist before the write does

An agent that changes something runs in the order decide, act, report. Verification, where there is any, reads what already happened. That's a fine shape for a log.

  • Undo must precede write operation in revisionist logging approach
  • Each change given unique canonical identity with verified inverse
  • System requires inverse-capable tools, currently only 13.8% available

More from Sunday 30 August →