# Redis prerequisite

Source: https://docs.externa.qiick.io/docs/redis-prerequisite

Horizon, app cache (including public API response cache), Reverb (presence + fan-out / scaling), and Pulse **redis ingest** all expect a reachable Redis. Without it, run the **minimal** stack (database queue / cache + log broadcast) and skip Horizon / Pulse redis ingest / Echo.

> **Related**
> Full vs minimal: [Minimal vs full stack](/docs/minimal-vs-full-stack). Queues: [Operations](/docs/operations). Official: [Redis](https://laravel.com/docs/13.x/redis).

## What Externa uses Redis for

| Feature                                | Why Redis                                                                                                                                     |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| [Horizon](/docs/horizon)               | Queue backend + Horizon meta (`QUEUE_CONNECTION=redis`)                                                                                       |
| App cache / performance                | `CACHE_STORE=redis` on `REDIS_CACHE_DB=1` (distinct from queue DB `0`) — preferred for public API caching; `database` is fine for light local |
| [Reverb + Echo](/docs/reverb-and-echo) | Scaling / presence pub-sub (Herd Reverb still expects Redis for multi-node; local single-node benefits from Redis for the rest of the stack)  |
| [Pulse](/docs/pulse-and-health)        | `PULSE_INGEST_DRIVER=redis` stream + `pulse:work`                                                                                             |

## Herd

1. Enable **Redis** in Laravel Herd.
2. Confirm: `redis-cli ping` → `PONG`.
3. PHP needs `ext-redis` (Herd PHP 8.4 includes it).
4. Optional: enable **Reverb** under Herd Services (shared `:8080`) — see [Reverb & Echo](/docs/reverb-and-echo).

Operators can check Redis reachability from Settings → **Performance** (`/settings/performance`) — the **Status** section shows whether Redis responds to `ping()`. See [Operations](/docs/operations).

## Docker Compose

`compose.yaml` / `compose.prod.yaml` run a `redis` service. App env uses `REDIS_HOST=redis`. See [Installation — Docker](/docs/installation#docker-compose-local-full-stack).

## Env

```ini
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_STORE=redis
# Dedicated DBs:
# REDIS_DB=0          # default / Horizon / queues
REDIS_CACHE_DB=1      # app cache (keep separate from queues)
# REDIS_PULSE_DB=2    # Pulse ingest (config/database.php connection "pulse")
```

Externa registers a dedicated Redis connection named **`pulse`** so Pulse ingest does not share Horizon/queue keys ([Pulse Redis ingest](https://laravel.com/docs/13.x/pulse#redis-ingest)). Use `REDIS_CACHE_DB=1` so Laravel cache keys do not collide with Horizon/queue data on DB `0`.

## Without Redis

Set:

```ini
QUEUE_CONNECTION=database
CACHE_STORE=database
BROADCAST_CONNECTION=log
PULSE_ENABLED=false
# or PULSE_INGEST_DRIVER=storage
```

Then use `composer run dev` (`queue:listen`) instead of Horizon + Pulse workers. Notifications fall back to the **60s unread poll** only in this mode.

**Production hosts without Redis:** capability matrix + supervisor — [Production without Redis](/docs/production-without-redis).
