RateLimitly Python client
ratelimitly is the official Python client for RateLimitly, a distributed admission-control service. An application asks whether it may begin work that consumes rate-limited resources. The decision can also depend on recent latency observations for services used by that work.
The library exposes two independent operations:
- A resource request atomically asks to consume quantities from zero or more rate buckets, subject to zero or more latency guards. A successful decision represents consumption of every requested quantity and authorizes the work to proceed.
- A latency report contributes measured service latencies to one or more trackers. It does not request resources or make an admission decision.
An empty resource request succeeds locally. A guard-only request is sent to RateLimitly and evaluated normally.
Installation
pip install ratelimitly
Request one token
In English, this request means: “Give me one token from the checkout bucket whose definition is 100 tokens per 1,000 ms.”
from ratelimitly import (
RCLIENT_OK,
RateLimitlyClient,
ResourceRequest,
r_client_derive_bucket_id,
)
window_size_ms = 1_000
rate_limit = 100
resource = ResourceRequest(
bucket_id=r_client_derive_bucket_id(
"checkout", # Exact application-defined bucket name.
window_size_ms, # Bucket window in milliseconds.
rate_limit, # Tokens available per window.
),
window_size_ms=window_size_ms,
rate_limit=rate_limit,
tokens_requested=1,
)
with RateLimitlyClient("rl-aes1...") as client:
status, result = client.check_rate_limit([resource])
if status != RCLIENT_OK:
print(f"No decision: client status {status}")
elif result.success:
print("Granted; perform the protected work")
else:
print("Denied; do not perform the protected work")
RCLIENT_OK means a valid RateLimitly decision was received; it does not mean the request was granted. Check result.success for the admission decision.
Report one measured latency
In English: “Add a 25 ms observation to the inventory-backend tracker defined by these storage settings.”
from ratelimitly import (
RateLimitlyClient,
ServiceLatencyReport,
r_client_derive_latency_tracker_id,
)
ttl_ms = 10_000
max_samples = 100
min_sample_threshold = 5
tracker_id = r_client_derive_latency_tracker_id(
"inventory-backend", # Exact application-defined tracker name.
ttl_ms, # Maximum sample lifetime.
max_samples, # Samples considered by the tracker.
min_sample_threshold, # Warm-up samples before guards take effect.
)
report = ServiceLatencyReport(
latency_tracker_id=tracker_id,
observed_latency_ms=25,
ttl_ms=ttl_ms,
max_samples=max_samples,
min_sample_threshold=min_sample_threshold,
)
with RateLimitlyClient("rl-aes1...") as client:
status = client.report_latency([report])
Measure the service operation, not the RateLimitly request. Reports are independent of resource requests and may be sent by a different process.
Add a latency guard
This request asks for the same token only when the tracker’s current latency is below 50 ms:
from ratelimitly import LatencyGuard
guard = LatencyGuard(
latency_tracker_id=tracker_id, # Same tracker definition as the report.
threshold_ms=50, # Admission requires current latency < 50 ms.
ttl_ms=ttl_ms,
max_samples=max_samples,
min_sample_threshold=min_sample_threshold,
)
with RateLimitlyClient("rl-aes1...") as client:
status, result = client.check_rate_limit(
resources=[resource],
guards=[guard],
)
Canonical IDs must agree across clients
Bucket IDs include the exact bucket-name bytes, window_size_ms, and rate_limit. Latency-tracker IDs include the exact tracker-name bytes, ttl_ms, max_samples, and min_sample_threshold; a guard threshold is deliberately not part of the tracker ID.
The Python helpers implement the same domain-separated binary preimage,
little-endian integer encoding, BLAKE2s-256 digest, and 16-byte truncation as
the coordinated wire-v2 C client. Do not replace them with hashing of formatted
text, and do not use hashlib.blake2s(..., digest_size=16): digest length is a
BLAKE2 parameter, so that produces a different ID.
See API reference for the exact formula and cross-client known-answer vectors.
High-availability policy
The default policy matches rl-c-client: unit_ms=20, one replay, a fixed one-unit round duration, one final receive-only unit, and completion delivery enabled. Its deduplication TTL and maximum decision horizon are 60 ms. The initial transmission goes to every discovered r-server, and the oldest known server’s response wins when it arrives within the first round.
See configuration for the complete parametrized policy and architecture for wire and selection semantics.
API layers
RateLimitlyClient is blocking. AsyncRateLimitlyClient provides the same serialized state machine through asyncio. A client preserves DNS results and UDP sockets across calls; call close() or use the context-manager forms to release them.
The client returns the same status-code family as the C library. It does not choose an application fail-open or fail-closed policy: the caller decides what to do when no RateLimitly decision is available.
Documentation
License
MIT
Metadata
Release files for ratelimitly 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ratelimitly-2.0.0.tar.gz | 24.4 kB | With provenance | Details for ratelimitly-2.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ratelimitly-2.0.0-py3-none-any.whl | Python 3 | none | any | Details for ratelimitly-2.0.0-py3-none-any.whl |
Total release size: 44.4 kB
Release files / ratelimitly-2.0.0.tar.gz
| Download URL | ratelimitly-2.0.0.tar.gz |
|---|---|
| Size | 24.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a8ad20896d6e93cba4f0d1a5891fb1e76a85e32d56692ff0da556da03acb7f1a
|
|
BLAKE2b-256 checksum How to use checksums |
9b0bbc34efb3e648bcb10827d007f66b3fead44faaa0687ccfd32a96ffe1052c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency logRelease files / ratelimitly-2.0.0-py3-none-any.whl
| Download URL | ratelimitly-2.0.0-py3-none-any.whl |
|---|---|
| Size | 20.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
02ade3cd18339502db1959a1e7ce772e61c57d7fbbab8168e9139812060c7032
|
|
BLAKE2b-256 checksum How to use checksums |
1a50a92cb1cc3f970106ec331c5cb976728115a17a5975de8ad756266586ba87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency logSecurity for ratelimitly 2.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for ratelimitly-2.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.