# `PushX.RateLimiter`
[🔗](https://github.com/cignosystems/pushx/blob/v0.11.0/lib/push_x/rate_limiter.ex#L1)

Client-side rate limiting for push notifications.

Prevents exceeding provider rate limits by tracking requests locally.
Uses a sliding window algorithm with ETS for fast, concurrent access.

## Configuration

    config :pushx,
      rate_limit_enabled: true,
      rate_limit_apns: 5000,      # requests per window
      rate_limit_fcm: 5000,       # requests per window
      rate_limit_window_ms: 1000  # 1 second window

## Usage

Rate limiting is automatically applied when enabled. You can also
check manually:

    case PushX.RateLimiter.check(:apns) do
      :ok -> # Proceed with sending
      {:error, :rate_limited} -> # Back off
    end

## How It Works

1. Each provider has a separate counter
2. Requests are counted within a sliding time window
3. When the limit is reached, new requests are rejected
4. The window slides forward, allowing new requests

# `provider`

```elixir
@type provider() :: :apns | :fcm
```

# `check`

```elixir
@spec check(provider()) :: :ok | {:error, :rate_limited}
```

Checks if a request would be allowed without incrementing.

# `check_and_increment`

```elixir
@spec check_and_increment(provider()) :: :ok | {:error, :rate_limited}
```

Checks if a request can be made and increments the counter.

Returns `:ok` if under the limit, `{:error, :rate_limited}` if over.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `current_count`

```elixir
@spec current_count(provider()) :: non_neg_integer()
```

Returns the current request count for a provider.

# `limit`

```elixir
@spec limit(provider()) :: pos_integer()
```

Returns the configured limit for a provider.

# `remaining`

```elixir
@spec remaining(provider()) :: non_neg_integer()
```

Returns remaining requests before rate limit is hit.

# `reset`

```elixir
@spec reset(provider()) :: :ok
```

Resets the rate limiter for a provider. Useful for testing.

# `reset_all`

```elixir
@spec reset_all() :: :ok
```

Resets all rate limiters.

# `start_link`

Starts the rate limiter process.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
