Skip to main content
The gateway now ships in the praisonai-bot package. praisonai serve gateway still works exactly as documented here; for a standalone install see praisonai-bot Migration.
The RateLimitPolicyProtocol lets you plug any rate limiter — per-tenant, Redis-backed, or cost-based — into the gateway’s connection handshake with a single check method. A built-in sliding window policy covers most use cases out of the box.

Quick Start

1

Use the built-in sliding window

2

Inject into the gateway

3

Configure via YAML

4

Write your own policy

Any object with a check(*, identity, scope, now) method satisfies the protocol — no base class needed:

How It Works

allowed=False maps to ConnectErrorCode.RATE_LIMITED on the wire and sets HelloError.retry_after_seconds so clients know when to retry. Wire details are in Gateway Handshake Protocol.

Imports


API Reference

RateLimitDecision

A frozen dataclass returned by every check() call.

RateLimitPolicyProtocol

@runtime_checkable Protocol — any class with a matching check signature satisfies it without inheriting:

SlidingWindowRateLimitPolicy

Config-driven, dependency-free default. Keyed per (scope, identity).

RateLimitPolicy

Backward-compat alias for RateLimitPolicyProtocol. New code should import RateLimitPolicyProtocol.

State Ownership

The built-in SlidingWindowRateLimitPolicy is not internally synchronised and reclaims (scope, identity) entries lazily on the next check.
  • Suitable for: bounded, authenticated identity spaces (tenants, endpoint classes, known API keys).
  • Not suitable for: unbounded / untrusted identity spaces (raw per-IP keys) — implement RateLimitPolicyProtocol in the wrapper layer and run periodic reclamation yourself.

Common Patterns

Per-tenant limiter with different quotas

Disable rate limiting (legacy always-allow)


Best Practices

check is called synchronously on the hot path. Avoid network calls inside it. Use a local in-process cache (e.g. a dict + sliding window) and sync to Redis asynchronously.
Clients use retry_after_seconds to back off correctly. Returning 0.0 on a rejection causes immediate retries and amplifies load. Return a meaningful value (5–60 s).
max_requests=0 is the default — it passes every request through, identical to having no policy. Use this when you want to add a policy object for future use without enforcing limits yet.
Set lockout_seconds to apply a cooldown after a caller hits the ceiling. Without a lockout, callers can burst exactly max_requests per window forever by timing their requests carefully.
The same user may appear across Telegram and Discord. Scope per (identity, scope) to set per-platform limits, or drop scope to share a single quota across all platforms.
RateLimitPolicyProtocol is @runtime_checkable — use isinstance(my_policy, RateLimitPolicyProtocol) to verify your custom class satisfies the contract before injecting it.

Gateway Handshake Protocol

ConnectErrorCode.RATE_LIMITED and HelloError.retry_after_seconds

Bot Rate Limiting

Messaging platform rate limits (Telegram, Discord, Slack)

Gateway Reliability

One-switch reliability preset for production deployments

Rate Limiter

LLM API rate limiting (requests per minute, token budget)