> For the complete documentation index, see [llms.txt](https://quantumphp.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://quantumphp.gitbook.io/docs/packages/ratelimit/adapters.md).

# Adapters

RateLimit stores counters through one adapter per configured backend.

Use the file adapter when you want a local default with no extra service. Use the Redis adapter when rate limits must be shared across multiple PHP processes or servers.

## Configure the default adapter

`RateLimiterFactory` reads `config/rate_limit.php` and uses `rate_limit.default` when you do not request an adapter explicitly.

A typical config looks like this:

```php
return [
    'default' => env('RATE_LIMIT_ADAPTER', 'file'),

    'file' => [
        'path' => base_dir() . DS . 'cache' . DS . 'data',
        'ttl' => 60,
        'prefix' => 'api-rate-limit:',
    ],

    'redis' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'port' => env('REDIS_PORT', 6379),
        'ttl' => 60,
        'prefix' => 'api-rate-limit:',
    ],
];
```

## File adapter

`FileRateLimitAdapter` stores one JSON state file per rate-limit key and uses a lock file to serialize updates.

Use it when the app runs on one machine or when each node can keep its own independent limits.

### Required config

* `path` - directory used for `.rate` and `.lock` files
* `ttl` - lifetime used only when you manually reset to a non-zero count
* `prefix` - optional namespace added before hashing the key

### What it guarantees

* The storage directory is created if it does not exist.
* Each hit stores `count` and `reset_at`.
* When the window expires, the next hit starts a fresh counter.
* `retryAfter()` returns `0` when the state file is missing or unreadable.

### Caveats

* File limits are local to the filesystem backing `path`.
* If the adapter cannot open or lock its state file, `hit()` returns `false`.
* Stored filenames are hashed, so inspecting the directory is useful for operations, not for human-readable debugging.

## Redis adapter

`RedisRateLimitAdapter` stores each counter as one Redis key.

Use it when multiple workers or servers must share the same limits.

### Required config

* `host`
* `port`
* `ttl` - lifetime used only when you manually reset to a non-zero count
* `prefix` - optional string prepended directly to the runtime key

### What it guarantees

* The first hit creates the key and sets its expiry to the route interval.
* Later hits increment the same key until the key expires.
* `retryAfter()` returns the Redis TTL in seconds, or `0` when Redis reports no usable expiry.

### Caveats

* The adapter only configures host and port. Authentication, database selection, and other Redis options are not part of this package contract.
* `prefix` is stored directly in Redis key names, unlike the file adapter where it only affects the hashed filename.
* Redis client errors are surfaced by the Redis client, so handle them in your app-level exception flow.

## Shared adapter behavior

Both built-in adapters support the same runtime contract:

* `hit($key, $limit, $interval)` increments and reports whether the request is still allowed
* `reset($key)` clears the counter
* `reset($key, $count)` seeds the counter and uses the adapter config `ttl`, not the route interval
* `retryAfter($key)` returns seconds until reset, or `0`

## Unsupported adapters

The factory only ships `file` and `redis`.

Passing any other adapter name to `RateLimiterFactory::get(...)` throws `RateLimitException::adapterNotSupported(...)`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://quantumphp.gitbook.io/docs/packages/ratelimit/adapters.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
