# Load testing (k6)

Run against **staging** only, with sandbox providers (`SOCIAL_FAKE_PROVIDERS` is refused outside local/testing, so staging uses provider test apps or a stub endpoint).

## 1. Dispatcher backlog

1. On staging, create a backlog: with `php artisan tinker`, approve and schedule a few thousand posts for the same minute across several tenants (or duplicate an approved post with the calendar's *series* action).
2. Start Horizon with production-like supervisors.
3. Run `k6 run -e BASE=https://acme.staging.example.com -e COOKIE='laravel_session=…' scripts/load/dispatcher.js` while the backlog drains.
4. Measure on the worker side:
   - time from `due_at` to `published_at` (p50/p95) in `post_targets`;
   - `publishing:dispatch-due` runtime (log line) and `publish_dispatch_index` rows claimed per run;
   - no target published twice (`publishing_attempts` count per target and version = 1 unless retried);
   - Horizon wait time per queue.
5. Pass criteria: p95 due→published < 60 s at 1,000 due targets/minute; page thresholds in the script pass; zero duplicate publications.

## 2. Composer

Record one Livewire update request of `/posts/create` with 20 selected accounts (browser dev tools → copy as JSON), then:

```
k6 run -e BASE=… -e COOKIE=… -e CSRF=… -e PAYLOAD="$(cat payload.json)" scripts/load/composer.js
```

Pass: p95 < 700 ms at 30 concurrent editors; no 5xx.

Record results (date, commit, numbers) at the bottom of this file.
