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.
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.
Plug into TsgcWebSocketHTTPServer or TsgcWSServer_HTTPAPI in one assignment.
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.
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.
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.
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".
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.
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;
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.
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.
You publish "max 100 req in any rolling 60s window". Sliding Window enforces it exactly — no edge-case bursts at window boundaries.
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.
Deep-link to the component reference, grab the ready-to-run demo project, and download the trial.