# Pulse & Health tab

Source: https://docs.externa.qiick.io/docs/pulse-and-health

Externa embeds **Laravel Pulse** for exceptions, queues, and slow jobs/queries. The Inertia dashboard **Health** tab shows native Externa-styled aggregates and charts — **not** an embedded Livewire Pulse UI and **not** a primary “Open Pulse” button. The full Livewire dashboard remains at `/pulse` for super-admin deep dives.

> **Upstream**
> [Laravel Pulse](https://laravel.com/docs/13.x/pulse) (Redis ingest + trimming) · UI: [Dashboard](/docs/dashboard) · Stack: [Minimal vs full](/docs/minimal-vs-full-stack) · Tuning: [Performance tuning](/docs/performance-tuning) · Machine probes: [Deployment — Health probes](/docs/deployment#health-probes) (`/health/live`, `/health/ready`)

## What Externa does

| Item                     | Detail                                                               |
| ------------------------ | -------------------------------------------------------------------- |
| Config                   | `config/pulse.php`                                                   |
| Ingest                   | Prefer `PULSE_INGEST_DRIVER=redis` + connection `pulse`              |
| Trim                     | Default keep **2 days** (`PULSE_STORAGE_KEEP` / `PULSE_INGEST_KEEP`) |
| Recorders on by default  | Exceptions, Queues, SlowJobs, SlowQueries                            |
| Recorders off by default | Cache interactions, slow requests/outgoing, user jobs/requests       |
| Gate                     | `viewPulse` — super-admin (full `/pulse` UI only)                    |
| Primary UI               | Dashboard → **Health** tab (`DashboardHealthMetrics`)                |
| Advanced UI              | `/pulse` (optional; no primary CTA from Health)                      |

## Env / commands

```ini
PULSE_ENABLED=true
PULSE_INGEST_DRIVER=redis
PULSE_REDIS_CONNECTION=pulse
PULSE_STORAGE_KEEP="2 days"
PULSE_INGEST_KEEP="2 days"
```

```bash
php84 artisan pulse:work
# After deploy:
php84 artisan pulse:restart
```

Without Redis, set `PULSE_INGEST_DRIVER=storage` (or `PULSE_ENABLED=false`) and skip `pulse:work`.

## Health tab vs `/pulse`

| Surface              | Contents                                                                                                                                                                          |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Dashboard **Health** | Queue/broadcast driver, Redis OK, pending/failed jobs; Pulse exception / slow-job / slow-query 24h counts + bar chart; Horizon status / pending / failed / throughput / workloads |
| `/pulse`             | Full Livewire Pulse dashboard (power users; bookmark)                                                                                                                             |

Do **not** mount Pulse Livewire inside Inertia — Health reads Pulse tables / Horizon Redis APIs and renders Externa cards instead. Empty states appear when Pulse is off or `pulse_aggregates` is missing.

## Native Pulse fields on Health

From `DashboardHealthMetrics::summary()`:

| Prop               | Source                                                      |
| ------------------ | ----------------------------------------------------------- |
| `pulse_enabled`    | `config('pulse.enabled')`                                   |
| `pulse_ingest`     | ingest driver name                                          |
| `pulse_available`  | enabled **and** `pulse_aggregates` table exists             |
| `exceptions_24h`   | sum of Pulse aggregates `type=exception` (last 24h buckets) |
| `slow_jobs_24h`    | `type=slow_job`                                             |
| `slow_queries_24h` | `type=slow_query`                                           |

Horizon fields on the same tab are documented on [Horizon](/docs/horizon) and [Dashboard](/docs/dashboard).

## Health badge prop

`HandleInertiaRequests` shares `healthBadge` from `DashboardHealthMetrics::badge()` (`ok` / `warn` / `fail`). Open Health via Dashboard → Health (`/dashboard?tab=health`); there is no sidebar badge. See [Dashboard](/docs/dashboard).

## Performance Settings quick link

Settings → **Performance** (`/settings/performance`) shows an **Observability** section with quick links to Jobs, Pulse, and Horizon (when the user has the relevant permissions). Super-admins with `viewPulse` can navigate to `/pulse` from there. The same page surfaces Public API cache **TTL** (`PUBLIC_API_CACHE_TTL`), per-epoch **hits/misses**, and **last flushed** at/by ([core#115](https://github.com/qiick-io/externa-core/issues/115)) — [Performance tuning](/docs/performance-tuning). See [Operations](/docs/operations).
