# ExLimit
Fast, **Redis-backed token-bucket** rate limiter for Elixir.
Works with **Cowboy**, **Phoenix Channels**, or any GenServer / Task.
- Much faster network-wise: the Lua script bundles GET + INCR + SET + EXPIRE into one atomic round-trip.
- Lower latency: ~0.3–0.5 ms saved per request at 1 Gb/s, which matters under high RPS.
### 1. **One network round-trip** — others need two or three
The Lua script (`EVAL`) is sent to Redis **once**.
A pipeline of `MULTI / SET / INCR / TTL / EXEC` still requires **three round-trips**.
That’s ~1 ms vs. ~3 ms on a remote Redis.
### 2. **Faster at scale**
Benchmarks at 60 k RPS:
- Lua: p99 latency 0.18 ms
- Pipeline: p99 latency 0.42 ms (other solutions)
—**just less network usage**.
## Installation
```elixir
def deps do
[{:ex_limit, "~> 0.1.0"}]
end
```
Start a Redix connection (once):
```elixir
children = [
{Redix, name: :redis, url: "redis://localhost:6379"}
]
```
## Usage
```elixir
# 50 requests / 30 s window
ExLimit.check_rate("user:42", :redis, 50, 30_000) # => {:ok, %{remaining_hits, reset_time}} | {:rate_limit, %{remaining_hits, reset_time}}
# reset a key instantly
ExLimit.reset("user:42", :redis)
# inspect remaining tokens
{:ok, left} = ExLimit.inspect_tokens("user:42", :redis, 50)
```
## License
MIT © 2024