> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Redis

> Redis instellen en gebruiken voor cache, sessies, queues en Pub/Sub in een Laravel-applicatie

Redis is een in-memory key-value store die als backend dient voor veel functionaliteit van Laravel.
Van configuratie tot bewerkingen en Pub/Sub: hier leer je hoe je Redis gebruikt in Laravel.

<CardGroup cols={3}>
  <Card title="Cache" icon="database" href="/nl/cache">
    Redis gebruiken als cachedriver
  </Card>

  <Card title="Queues" icon="list" href="/nl/queues">
    Redis gebruiken als queuedriver
  </Card>

  <Card title="Broadcasting" icon="radio" href="/nl/broadcasting">
    Realtime communicatie met Pub/Sub
  </Card>
</CardGroup>

## Wat is Redis

[Redis](https://redis.io) is een open source, razendsnelle key-value store.
Redis ondersteunt uiteenlopende datastructuren zoals strings, hashes, lijsten, sets en sorted sets, en wordt daarom ook wel een datastructuurserver genoemd.

In Laravel wordt Redis gebruikt voor de volgende doeleinden.

```mermaid theme={null}
flowchart LR
    A["Laravel-<br>applicatie"] --> B["Redis"]

    subgraph uses ["Belangrijkste toepassingen"]
        C["Cache"]
        D["Sessies<br>Session"]
        E["Queues<br>Queue"]
        F["Broadcasting"]
    end

    B --> C
    B --> D
    B --> E
    B --> F
```

## Een client kiezen

Laravel ondersteunt twee clients: **PhpRedis** (een PHP-extensie) en **Predis** (een PHP-package).

| Aspect              | PhpRedis                     | Predis                                                |
| ------------------- | ---------------------------- | ----------------------------------------------------- |
| Implementatie       | PHP-extensie geschreven in C | Puur PHP-package                                      |
| Installatie         | Vereist een PECL-extensie    | Volstaat met `composer require`                       |
| Prestaties          | Snel                         | Iets langzamer dan PhpRedis                           |
| Laravel Sail        | Standaard geïnstalleerd      | Moet apart worden geïnstalleerd                       |
| Aanbevolen omgeving | Productie                    | Ontwikkeling of omgevingen waar installatie lastig is |

<Info>
  In Laravel 13 is PhpRedis de standaardclient. Voor productieomgevingen wordt PhpRedis aanbevolen.
  Gebruik je Laravel Sail, dan is PhpRedis al geïnstalleerd.
</Info>

## Configuratie

### config/database.php

De Redis-configuratie beheer je in de `redis` array in `config/database.php`.

```php theme={null}
'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
    ],

    'default' => [
        'url' => env('REDIS_URL'),
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'username' => env('REDIS_USERNAME'),
        'password' => env('REDIS_PASSWORD'),
        'port' => env('REDIS_PORT', '6379'),
        'database' => env('REDIS_DB', '0'),
    ],

    'cache' => [
        'url' => env('REDIS_URL'),
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'username' => env('REDIS_USERNAME'),
        'password' => env('REDIS_PASSWORD'),
        'port' => env('REDIS_PORT', '6379'),
        'database' => env('REDIS_CACHE_DB', '1'),
    ],

],
```

### Omgevingsvariabelen

Stel de verbindingsgegevens in via `.env`.

```ini theme={null}
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=null
REDIS_DB=0
REDIS_CACHE_DB=1
```

Je kunt de verbinding ook in URL-vorm opgeven.

```php theme={null}
'default' => [
    'url' => 'tcp://127.0.0.1:6379?database=0',
],

'cache' => [
    'url' => 'tls://user:password@127.0.0.1:6380?database=1',
],
```

### TLS/SSL-verbindingen

Wil je TLS-versleuteling gebruiken, geef dan de `scheme` optie op.

```php theme={null}
'default' => [
    'scheme' => 'tls',
    'url' => env('REDIS_URL'),
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'username' => env('REDIS_USERNAME'),
    'password' => env('REDIS_PASSWORD'),
    'port' => env('REDIS_PORT', '6379'),
    'database' => env('REDIS_DB', '0'),
],
```

### Clustering

Wil je meerdere Redis-servers als cluster gebruiken, gebruik dan de `clusters` sleutel.

```php theme={null}
'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
    ],

    'clusters' => [
        'default' => [
            [
                'url' => env('REDIS_URL'),
                'host' => env('REDIS_HOST', '127.0.0.1'),
                'username' => env('REDIS_USERNAME'),
                'password' => env('REDIS_PASSWORD'),
                'port' => env('REDIS_PORT', '6379'),
                'database' => env('REDIS_DB', '0'),
            ],
        ],
    ],

],
```

Standaard staat `options.cluster` op `redis`, waardoor native Redis-clustering wordt gebruikt.
Omdat dit failover automatisch afhandelt, is dit de aanbevolen configuratie voor productieomgevingen.

Wil je client-side sharding gebruiken met Predis, verwijder dan `options.cluster`.
Client-side sharding handelt failover echter niet af en is daarom alleen geschikt voor tijdelijke data zoals cache.

### Predis configureren

Om Predis te gebruiken installeer je het `predis/predis` package en wijzig je `REDIS_CLIENT` naar `predis`.

```shell theme={null}
composer require predis/predis
```

```ini theme={null}
REDIS_CLIENT=predis
```

Je kunt Predis-specifieke [verbindingsparameters](https://github.com/nrk/predis/wiki/Connection-Parameters) toevoegen.

```php theme={null}
'default' => [
    'url' => env('REDIS_URL'),
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'username' => env('REDIS_USERNAME'),
    'password' => env('REDIS_PASSWORD'),
    'port' => env('REDIS_PORT', '6379'),
    'database' => env('REDIS_DB', '0'),
    'read_write_timeout' => 60,
],
```

#### Retry-configuratie voor Predis

Vanaf Predis 3.4.0 zijn ingebouwde retry- en backoff-instellingen beschikbaar. Met de `max_retries` optie stel je het aantal retries in en met de `retry` optie de backoff-strategie. Aan de `retry` optie geef je een array door met als sleutel een van de klassenamen `NoBackoff`, `EqualBackoff` of `ExponentialBackoff`.

```php theme={null}
use Predis\Retry\Strategy\ExponentialBackoff;

'default' => [
    'url' => env('REDIS_URL'),
    // ...
    'retry' => [
        ExponentialBackoff::class => [
            env('REDIS_BACKOFF_BASE', 100),
            env('REDIS_BACKOFF_CAP', 1000),
            true, // Jitter inschakelen
        ],
    ],
    'max_retries' => env('REDIS_MAX_RETRIES', 3),
],
```

Gebruik je Predis met een Redis-cluster, dan configureer je retries via de `parameters` optie in de clusterconfiguratie.

```php theme={null}
use Predis\Retry\Strategy\NoBackoff;

'clusters' => [
    'default' => [
        // ...
    ],
],

'options' => [
    'cluster' => env('REDIS_CLUSTER', 'redis'),
    'parameters' => [
        'retry' => [
            NoBackoff::class => [],
        ],
        'max_retries' => env('REDIS_MAX_RETRIES', 3),
    ],
],
```

### PhpRedis configureren

PhpRedis installeer je via PECL (in Laravel Sail is het al geïnstalleerd).
PhpRedis ondersteunt de volgende extra opties:
`name`, `persistent`, `persistent_id`, `prefix`, `read_timeout`, `retry_interval`,
`max_retries`, `backoff_algorithm`, `backoff_base`, `backoff_cap`, `timeout`, `context`

```php theme={null}
'default' => [
    'url' => env('REDIS_URL'),
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'username' => env('REDIS_USERNAME'),
    'password' => env('REDIS_PASSWORD'),
    'port' => env('REDIS_PORT', '6379'),
    'database' => env('REDIS_DB', '0'),
    'read_timeout' => 60,
    'context' => [
        // 'auth' => ['username', 'secret'],
        // 'stream' => ['verify_peer' => false],
    ],
],
```

#### Retry- en backoff-configuratie

Zo stel je het retrygedrag bij een mislukte verbinding in.
Ondersteunde backoff-algoritmen: `default`, `decorrelated_jitter`, `equal_jitter`, `exponential`, `uniform`, `constant`

```php theme={null}
'default' => [
    'url' => env('REDIS_URL'),
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'username' => env('REDIS_USERNAME'),
    'password' => env('REDIS_PASSWORD'),
    'port' => env('REDIS_PORT', '6379'),
    'database' => env('REDIS_DB', '0'),
    'max_retries' => env('REDIS_MAX_RETRIES', 3),
    'backoff_algorithm' => env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter'),
    'backoff_base' => env('REDIS_BACKOFF_BASE', 100),
    'backoff_cap' => env('REDIS_BACKOFF_CAP', 1000),
],
```

#### Verbinden via een Unix-socket

Draait Redis op dezelfde server, dan kun je met een Unix-socket de TCP-overhead verminderen.

```ini theme={null}
REDIS_HOST=/run/redis/redis.sock
REDIS_PORT=0
```

#### Serialisatie en compressie

Bij PhpRedis kun je de serialisatie en het compressie-algoritme van opgeslagen data configureren.

```php theme={null}
'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
        'serializer' => Redis::SERIALIZER_MSGPACK,
        'compression' => Redis::COMPRESSION_LZ4,
    ],

],
```

Ondersteunde serializers:

| Constante                    | Beschrijving                  |
| ---------------------------- | ----------------------------- |
| `Redis::SERIALIZER_NONE`     | Geen serialisatie (standaard) |
| `Redis::SERIALIZER_PHP`      | PHP-serialisatie              |
| `Redis::SERIALIZER_JSON`     | JSON                          |
| `Redis::SERIALIZER_IGBINARY` | igbinary                      |
| `Redis::SERIALIZER_MSGPACK`  | MessagePack                   |

Ondersteunde compressie-algoritmen:

| Constante                 | Beschrijving                |
| ------------------------- | --------------------------- |
| `Redis::COMPRESSION_NONE` | Geen compressie (standaard) |
| `Redis::COMPRESSION_LZF`  | LZF                         |
| `Redis::COMPRESSION_ZSTD` | Zstandard                   |
| `Redis::COMPRESSION_LZ4`  | LZ4                         |

## Werken met Redis

### De Redis-facade

Met de `Redis` facade kun je elk Redis-commando uitvoeren.
De facade stuurt commando's via magic methods door naar de Redis-server.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Redis;
use Illuminate\View\View;

class UserController extends Controller
{
    public function show(string $id): View
    {
        return view('user.profile', [
            'user' => Redis::get('user:profile:'.$id)
        ]);
    }
}
```

Commando's die argumenten verwachten geef je die argumenten gewoon als methodeargumenten mee.

```php theme={null}
use Illuminate\Support\Facades\Redis;

Redis::set('name', 'Taylor');

$values = Redis::lrange('names', 5, 10);
```

Met de `command` methode kun je de commandonaam en argumenten ook expliciet opgeven.

```php theme={null}
$values = Redis::command('lrange', ['name', 5, 10]);
```

### Meerdere verbindingen gebruiken

Je kunt meerdere Redis-verbindingen definiëren in `config/database.php` en ertussen schakelen met de `connection()` methode.

```php theme={null}
// Een named connection ophalen
$redis = Redis::connection('connection-name');

// De standaardverbinding ophalen
$redis = Redis::connection();
```

### Transacties

De `transaction()` methode omhult de `MULTI`/`EXEC` commando's van Redis.
Alle commando's binnen de closure worden atomair uitgevoerd.

```php theme={null}
use Redis;
use Illuminate\Support\Facades;

Facades\Redis::transaction(function (Redis $redis) {
    $redis->incr('user_visits', 1);
    $redis->incr('total_visits', 1);
});
```

<Warning>
  Binnen een transactie kun je geen waarden uit Redis ophalen.
  De hele closure wordt eerst uitgevoerd en daarna met `EXEC` in één keer verwerkt.
</Warning>

### Lua-scripts

Met de `eval()` methode kun je Lua-scripts atomair uitvoeren.
Dit is flexibeler dan een transactie, omdat je binnen het script waarden uit Redis kunt lezen en bijwerken.

```php theme={null}
$value = Redis::eval(<<<'LUA'
    local counter = redis.call("incr", KEYS[1])

    if counter > 5 then
        redis.call("incr", KEYS[2])
    end

    return counter
LUA, 2, 'first-counter', 'second-counter');
```

Volgorde van de argumenten: Lua-script → aantal sleutels → sleutelnamen... → extra argumenten...

`KEYS[1]` en `KEYS[2]` zijn de sleutelnamen; vanaf `ARGV[1]` worden de extra argumenten doorgegeven.

### Pipelining

Je kunt een groot aantal commando's in één keer versturen en zo netwerk-roundtrips verminderen.

```php theme={null}
use Redis;
use Illuminate\Support\Facades;

Facades\Redis::pipeline(function (Redis $pipe) {
    for ($i = 0; $i < 1000; $i++) {
        $pipe->set("key:$i", $i);
    }
});
```

```mermaid theme={null}
sequenceDiagram
    participant App as Laravel-<br>app
    participant Redis

    Note over App,Redis: Normaal (roundtrip per commando)
    App->>Redis: SET key:0 0
    Redis-->>App: OK
    App->>Redis: SET key:1 1
    Redis-->>App: OK

    Note over App,Redis: Pipeline (gebundeld versturen)
    App->>Redis: SET key:0 0 / SET key:1 1 / ...
    Redis-->>App: OK / OK / ...
```

<Tip>
  Een pipeline verstuurt commando's alleen gebundeld en is niet atomair.
  Heb je atomaire operaties nodig, gebruik dan een transactie of een Lua-script.
</Tip>

## Pub/Sub

Met de `publish` / `subscribe` commando's van Redis kun je berichten uitwisselen via channels.

### Subscriber

`subscribe()` is een langlopend proces en roep je daarom aan binnen een Artisan-commando.

```php theme={null}
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;

class RedisSubscribe extends Command
{
    protected $signature = 'redis:subscribe';

    protected $description = 'Subscribe to a Redis channel';

    public function handle(): void
    {
        Redis::subscribe(['test-channel'], function (string $message) {
            echo $message;
        });
    }
}
```

### Publisher

Vanuit een ander request of proces verstuur je berichten.

```php theme={null}
use Illuminate\Support\Facades\Redis;

Route::get('/publish', function () {
    Redis::publish('test-channel', json_encode([
        'name' => 'Adam Wathan'
    ]));
});
```

### Wildcard-subscriptions

Met `psubscribe()` kun je subscriptions met patroonmatching maken.

```php theme={null}
// Abonneren op alle channels
Redis::psubscribe(['*'], function (string $message, string $channel) {
    echo $message;
});

// Abonneren op channels die voldoen aan het patroon users.*
Redis::psubscribe(['users.*'], function (string $message, string $channel) {
    echo $message;
});
```

## Samenvatting

<AccordionGroup>
  <Accordion title="Een client kiezen">
    * **Productieomgeving**: PhpRedis (PECL-extensie, hoge prestaties)
    * **Ontwikkelomgeving of wanneer installatie lastig is**: Predis (Composer-package)
    * **Laravel Sail**: PhpRedis is standaard geïnstalleerd
  </Accordion>

  <Accordion title="Aandachtspunten bij de verbindingsconfiguratie">
    * Definieer meerdere Redis-verbindingen in `config/database.php` en gebruik ze per doel (`default` / `cache`, enz.)
    * Gebruik in een clusteromgeving de `clusters` sleutel
    * Overweeg in productie TLS-verbindingen en het instellen van inloggegevens
  </Accordion>

  <Accordion title="Welke bewerking gebruik je wanneer">
    | Bewerking                   | Gebruik                                                              |
    | --------------------------- | -------------------------------------------------------------------- |
    | Facademethoden              | Gewone Redis-commando's                                              |
    | `transaction()`             | Atomaire uitvoering van meerdere commando's (waarden lezen kan niet) |
    | `eval()`                    | Lua-scripts (atomaire operaties inclusief lezen)                     |
    | `pipeline()`                | Snel versturen van grote aantallen commando's (niet atomair)         |
    | `subscribe()` / `publish()` | Channelmessaging (Pub/Sub)                                           |
  </Accordion>
</AccordionGroup>


## Related topics

- [Cache](/nl/cache.md)
- [Laravel Sail](/nl/sail.md)
- [Rate limiting aanpassen](/nl/advanced/rate-limiting.md)
- [Queues en jobs](/nl/queues.md)
- [Laravel Pulse](/nl/pulse.md)
