-
Notifications
You must be signed in to change notification settings - Fork 1
RateLimit
Marco Breveglieri edited this page Jul 20, 2026
·
2 revisions
The Rate Limit pattern controls the rate of operations to prevent system overload using a token bucket algorithm.
- Calling rate-limited third-party APIs
- Protecting your own services from overload
- Preventing resource exhaustion
- Controlling costs (pay-per-request APIs)
- Operations without rate limits
- Single or infrequent operations
- When client-side queuing is better
uses Murphy.Policy.RateLimit;
var
Policy: IRateLimitPolicy;
begin
Policy := TRateLimitBuilder
.Handle(Exception)
.Allow(100)
.Within(TTimeSpan.FromMinutes(1))
.Build;
Policy.Execute(procedure begin MakeAPICall; end);
end;type
TTwitterClient = class
private
FRateLimit: IRateLimitPolicy;
public
constructor Create;
procedure Tweet(Status: string);
end;
constructor TTwitterClient.Create;
begin
// Twitter: 300 tweets per 3 hours
FRateLimit := TRateLimitBuilder
.Handle(Exception)
.Allow(300)
.Within(TTimeSpan.FromHours(3))
.Build;
end;
procedure TTwitterClient.Tweet(Status: string);
begin
try
FRateLimit.Execute(procedure begin PostTweet(Status); end);
except
on E: ERateLimitRejectedException do
ShowMessage('Please wait before tweeting again');
end;
end;procedure ProcessItems(Items: TList<string>);
var
Policy: IRateLimitPolicy;
begin
Policy := TRateLimitBuilder
.Handle(Exception)
.Allow(100)
.Within(TTimeSpan.FromMinutes(1))
.Build;
for var Item in Items do
begin
try
Policy.Execute(procedure begin ProcessItem(Item); end);
except
on E: ERateLimitRejectedException do
begin
WriteLn('Rate limit reached, waiting 60 seconds...');
Sleep(60000);
Policy.Execute(procedure begin ProcessItem(Item); end);
end;
end;
end;
end;// Enforce both per-second AND per-hour limits
var
PerSecond: IRateLimitPolicy;
PerHour: IRateLimitPolicy;
begin
PerSecond := TRateLimitBuilder.Handle(Exception)
.Allow(1).Within(TTimeSpan.FromSeconds(1)).Build;
PerHour := TRateLimitBuilder.Handle(Exception)
.Allow(1000).Within(TTimeSpan.FromHours(1)).Build;
// Check both limits
PerSecond.Execute(procedure
begin
PerHour.Execute(procedure begin MakeRequest; end);
end);
end;- Match API limits - Configure to match actual rate limits
- Handle rejections gracefully - Queue or retry after delay
- Add margin - Set limit slightly lower than actual (e.g., 95 instead of 100)
- Monitor usage - Track how often limits are hit
- Consider multiple windows - Some APIs have per-second AND per-hour limits
- Bucket refills completely when time window expires
- Allows bursts (all tokens can be used immediately)
- Does not carry over unused tokens