---
name: runlot-operate
description: Operate a deployed Runlot app — live and stored logs (`runlot logs`), request lookup by Runlot-Request-Id, Runlot Errors issues, capacity risks with `runlot health`, usage, per-project memory and CPU limits, the org spending limit and 429 budget_exhausted, out-of-memory restarts and exceededCpu, load testing a preview with k6, and filing a problem with Runlot via `runlot bug-report`. Use when a Runlot app is slow, failing, restarting, over a limit or about to launch, or when the fault looks like the platform's rather than the app's.
---

# Operate a Runlot app

Runlot collects request records, worker exits, memory, CPU and errors for every project with
no SDK. Start from the symptom, find the request or the check that explains it, then fix the
code or the limit.

## Triage in four commands

```bash
runlot health                    # open capacity risks, the numbers behind them, what to do next
runlot logs --since 1h --level error
runlot errors                    # Runlot Errors issues: unresolved, events, users, last seen
runlot logs request <id>         # one request: outcome, logs, span waterfall, related issues
```

Every response carries a `Runlot-Request-Id` header (32 hex characters); error pages show the
same ID. Ask the user for it, or read it from the response, and look it up.

## Symptoms

| Symptom | Likely cause | Look at |
|---|---|---|
| `429 budget_exhausted` on every project of the org | Daily Free budget or Pro spending limit used up | `runlot usage`, `runlot org spending-limit --org <org>` |
| `500`, outcome `exceededCpu` | One request used more CPU than its limit (60 s default) | `runlot health` (`request_cpu`); move work to a queue |
| App restarts, `app_out_of_memory` issue | App process over its memory limit (256 MiB default) | `runlot health` (`app_memory`), `runlot project limits` |
| `57014` / `53300` from the database | Statement over 10 s / waited 10 s for a connection | `runlot health` (`db_admission`); the `runlot-database` skill |
| Slow only when busy | Requests queueing behind CPU-heavy ones | `runlot health` (`busy_latency`, `app_cpu`) |
| `429 too_many_concurrent` from `env.ai` | Free AI concurrency (2 per project) | `runlot ai` |
| Works locally, fails deployed | `fetch` to a private address, missing secret, compatibility date | `runlot secret list`, `runlot logs` |

Details: [references/logs-and-errors.md](references/logs-and-errors.md),
[references/health-and-limits.md](references/health-and-limits.md).

## Before a launch

1. `runlot health` — no open alerts; read the capacity estimate if there is one.
2. `runlot health --users 1000 --requests-per-user 100 --peak-hour-share 0.15` — your traffic
   next to the measured ceiling.
3. Load test a **preview**, never production: [references/load-testing.md](references/load-testing.md).
4. On Pro, check the spending limit covers the expected overage.

## When the fault is Runlot's

If the evidence points at the platform — a 5xx the app did not produce, a deploy that succeeded
but serves the old version, behaviour that contradicts the docs, a CLI command failing with a
server error — file a report with the evidence attached instead of guessing:

```bash
runlot bug-report --last --message "deploy v42 succeeded but / still serves v41"
runlot bug-report --request 4bf92f3577b34da6a3ce929d0e0e4736 --message "checkout returns 502 since 10:00 UTC"
```

What to attach and how it works: [references/bug-report.md](references/bug-report.md).
Show the user what will be sent (`--dry-run`) and send only with their consent.

## Do

- Quote request IDs, versions and UTC times when you report findings.
- Prefer stored logs with a window (`--since`) over scrolling the live tail.
- Fix the cause (stream instead of buffering, batch SQL, queue long work) before raising a limit.
- Check `unknown` checks in `runlot health` as "not measured", never as "fine".

## Don't

- Don't load test production or use `--db shared` for a load test.
- Don't raise memory or CPU limits to hide a leak or a synchronous loop.
- Don't set the spending limit at or below this month's overage without the user's say-so —
  it blocks every request of the org at once.
- Don't send a bug report without the user's consent, and don't paste secrets into `--message`.
