# Production without Redis

Source: https://docs.externa.qiick.io/docs/production-without-redis

Supported **degraded** production path when the host cannot run Redis: `QUEUE_CONNECTION=database`, broadcast `log`, no Horizon / Reverb. Prefer the full Redis stack when possible.

> Without Redis you lose Horizon, Echo push notifications, presence, and Pulse redis ingest. Database queues work for light operator teams; they are **not** recommended for busy multi-user realtime or large async fan-out.

> **Related**
> [Minimal vs full stack](/docs/minimal-vs-full-stack) · [Redis prerequisite](/docs/redis-prerequisite) · [Deployment](/docs/deployment) · [Operations](/docs/operations)

## Capability matrix

| Capability                       | Full (Redis)                | Without Redis                                   |
| -------------------------------- | --------------------------- | ----------------------------------------------- |
| Queues (zips, imports, webhooks) | Horizon / `redis`           | `QUEUE_CONNECTION=database` + `queue:work`      |
| Admin notifications              | Echo / Reverb push          | **60s unread poll only**                        |
| Presence / avatar connection dot | Online via presence channel | Offline / “Realtime off”                        |
| App cache                        | `CACHE_STORE=redis`         | `CACHE_STORE=database` (or `file`)              |
| Session                          | Often `redis`               | `SESSION_DRIVER=database`                       |
| Pulse Health cards               | Redis ingest + `pulse:work` | Off or storage ingest — limited                 |
| Horizon UI                       | `/horizon`                  | Unavailable — use Jobs monitor / failed_jobs    |
| AI imports / sync schedules      | Same jobs, Redis worker     | Same jobs, database worker (watch table growth) |

## `.env` (production-lean)

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

Ensure `jobs` / `failed_jobs` / `cache` / `sessions` migrations have run (`php artisan migrate --force`).

## Supervisor examples

### Queue worker

```ini
[program:externa-queue]
process_name=%(program_name)s
command=php /var/www/externa/artisan queue:work database --sleep=1 --tries=3 --timeout=300 --max-time=3600
directory=/var/www/externa
autostart=true
autorestart=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/log/externa-queue.log
stopwaitsecs=3600
```

### Scheduler

```ini
[program:externa-scheduler]
command=php /var/www/externa/artisan schedule:work
directory=/var/www/externa
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/log/externa-scheduler.log
```

Or classic cron:

```cron
* * * * * cd /var/www/externa && php artisan schedule:run >> /dev/null 2>&1
```

Do **not** run `horizon` or `reverb:start` on this profile. Restart `queue:work` on every deploy.

## When to switch back to Redis

- More than a handful of concurrent operators relying on live notifications
- Large zip / import backlogs
- You want Pulse/Horizon Health cards in production

Then follow [Redis prerequisite](/docs/redis-prerequisite) and [Horizon](/docs/horizon) / [Reverb](/docs/reverb-and-echo).
