Rate Limiter

TsgcWSRateLimiter — a full-featured rate limiting component that protects server endpoints from excessive traffic, abuse and scraping. Three algorithms, four scopes, long-term quotas and standards-compliant HTTP 429 responses.

Cap Request Rate Per IP, API Key, User or Endpoint

Plug into TsgcWebSocketHTTPServer or TsgcWSServer_HTTPAPI in one assignment.

Three Strategies, Four Scopes

TsgcWSRateLimiter supports three algorithms — Token Bucket (with bursting), Sliding Window (strict SLA enforcement) and Fixed Window (cheap counter, billing-style buckets). Rules can be scoped per IP, per API key, per user or per endpoint, and a separate burst-protection module catches scrapers that flood the server with hundreds of requests in a few hundred milliseconds.

Long-term quotas (hour / day / month) sit on top of the rolling strategy so you can enforce a free-tier monthly cap independently of short-term burst behavior. The component shapes the HTTP 429 response with Retry-After and X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset headers so well-behaved clients can pace themselves.

  • Token Bucket strategy with configurable burst and refill rate
  • Sliding Window for strict rolling-SLA enforcement
  • Fixed Window for billing-style hourly / daily quotas
  • Per-IP, per-API-key, per-user and per-endpoint scopes
  • Long-term quotas: hour, day, month (per-key or global)
  • Burst protection with cooldown for scraper detection
  • Standards-compliant HTTP 429 with Retry-After / X-RateLimit-*
  • State persistence (SaveStateToFile / LoadStateFromFile)
TOKEN BUCKET

Pick the Algorithm That Matches Your Policy

Token Bucket — Burst-Friendly Average Rate

Maintains a bucket of up to Capacity tokens per key. The bucket refills at RefillRate tokens every RefillIntervalMs milliseconds. Each request consumes one token. Great when you want an average rate (10 req/sec) but allow well-behaved clients to burst (50 requests back-to-back) without throttling.

Sliding Window — Strict Rolling SLA

Stores a timestamp for every request and counts the timestamps that fall within a rolling window of WindowSec seconds. Rejects when the count would exceed MaxRequests. The window slides continuously so there is no hard reset moment where a burst can slip through.

Fixed Window — Cheap Billing Buckets

Counts requests within a fixed clock window of WindowSec seconds and resets the counter when the window elapses. Cheapest memory-wise. Use for billing-style quotas like "1000 requests per hour, counter resets on the hour".

Burst Protection — Scraper Catcher

Runs in parallel with the main strategy. If more than BurstThreshold requests arrive from the same key within BurstWindowMs milliseconds, the key is placed in a cooldown for CooldownSec seconds during which every request is rejected.

Delphi Example

Per-IP token bucket with burst protection and a monthly quota.

// Global Token Bucket: 50 burst, 10/sec sustained
sgcWSRateLimiter1.TokenBucket.Enabled := True;
sgcWSRateLimiter1.TokenBucket.Capacity := 50;
sgcWSRateLimiter1.TokenBucket.RefillRate := 10;
sgcWSRateLimiter1.TokenBucket.RefillIntervalMs := 1000;

// Per-IP sliding window: 60 req/min per IP
sgcWSRateLimiter1.PerIP.Enabled := True;
sgcWSRateLimiter1.PerIP.Strategy := rlsSliding;
sgcWSRateLimiter1.PerIP.MaxRequests := 60;
sgcWSRateLimiter1.PerIP.WindowSec := 60;

// Per-endpoint: expensive report = 10 req/min
sgcWSRateLimiter1.PerEndpoint.Enabled := True;
with sgcWSRateLimiter1.PerEndpoint.Rules.Add as TsgcRateLimitRuleItem do
begin
  Pattern := '*/api/v1/expensive-report*';
  Strategy := rlsSliding;
  MaxRequests := 10;
  WindowSec := 60;
end;

// Burst: 50 reqs in 500ms triggers 30s cooldown
sgcWSRateLimiter1.BurstProtection.Enabled := True;
sgcWSRateLimiter1.BurstProtection.BurstThreshold := 50;
sgcWSRateLimiter1.BurstProtection.BurstWindowMs := 500;
sgcWSRateLimiter1.BurstProtection.CooldownSec := 30;

// Monthly quota: 10000 requests/month per key
sgcWSRateLimiter1.Quotas.Enabled := True;
with sgcWSRateLimiter1.Quotas.Quotas.Add as TsgcRateLimitQuotaItem do
begin
  Period := qpMonth;
  Limit := 10000;
end;

// Assign to server
sgcWebSocketHTTPServer1.RateLimiter := sgcWSRateLimiter1;

When to Reach for the Rate Limiter

Public REST / WebSocket API

Per-IP token bucket prevents a single noisy client from starving everyone else. Burst protection catches scraper bots that flood the server with hundreds of requests in milliseconds.

Tiered SaaS Pricing

Free tier: 100 req/hour with monthly cap. Pro tier: 10,000 req/hour. Enterprise tier: 1M req/hour. Pair PerAPIKey with TsgcWSAPIKeyManager for tier-aware throttling.

Strict SLA Enforcement

You publish "max 100 req in any rolling 60s window". Sliding Window enforces it exactly — no edge-case bursts at window boundaries.

Expensive Endpoint Protection

Report-generation endpoint costs 5 seconds of CPU. Per-endpoint rule limits it to 10 req/min while cheap status endpoints stay at 1000 req/min.

Documentation & Demos

Deep-link to the component reference, grab the ready-to-run demo project, and download the trial.

Protect Your Endpoints From Abuse

Download the free trial and rate-limit your sgcWebSockets servers in minutes.