Metrics & Logs

Every app has three views of what it’s doing right now: Metrics (resource and traffic charts), Logs (the running container’s output), and the per-deployment build logs on each deployment.

Metrics

The Metrics tab shows six live tiles, each with a sparkline:

Tile Source
CPU % docker stats on the app’s container
Memory docker stats (with the container’s memory limit)
Requests/s Traefik’s Prometheus counters for the app’s router
Error rate Traefik 5xx responses as a share of requests
Latency p50 / p95 Traefik request-duration histogram, over the last 15-second interval

A collector job samples every running app every 15 seconds, writes the sample to Postgres, and publishes it to subscribers. The tab loads the last 24 hours of history, then follows the live stream over SSE — the connection state is shown next to the page title (streaming / disconnected).

Traffic figures come from Traefik’s Prometheus endpoint on an internal-only listener (:8082), so they reflect what actually reached the proxy, not what the app thinks it served. Traefik keeps a separate histogram per status code, method, and protocol; Cargo sums them per app, and computes percentiles from the change since the previous sample — a latency spike shows up in the interval it happened, rather than being averaged into everything since Traefik started. If Traefik restarts, the first sample after it uses the fresh totals.

Retention

Samples are kept for 48 hours and purged by the daily housekeeping job. The history endpoint accepts a window of 6h, 24h (default), or 48h.

Instance-wide monitoring

App metrics answer “is this app healthy”. The Admin page answers “is the server healthy”, with two views instance admins see across every organization.

Server shows four live tiles on the same 15-second tick and 48-hour retention as app metrics:

Tile Source
Host CPU % /proc/stat, as a delta between ticks
Host memory /proc/meminfo — used is derived from MemAvailable, so reclaimable page cache doesn’t read as “full”
Disk used statfs on the data directory
Containers docker ps — every container on the host, not just apps

All applications lists the newest sample for every app on the instance — CPU, memory, requests/s, error rate, and p95 — with a link through to each app. An error rate above 5% is badged so it stands out. This is the one view that deliberately crosses organization boundaries, so it is instance-admin only.

These really are host figures

The controlplane runs in a container, but Docker does not namespace /proc/stat or /proc/meminfo — so the CPU and memory readings describe the whole machine, not the controlplane's own container. The container count includes the platform's own three containers and any managed databases, which is why it is usually higher than the number of running apps.

Each source degrades independently: if the Docker socket is unavailable the container count reports zero, but the CPU, memory, and disk series keep recording. Losing the whole sample exactly when something is wrong with the host would be the worst possible time for the charts to go blank.

Metrics appear roughly 15 seconds after an app starts running. A stopped app has no container to sample, so its charts flatten out.

Runtime logs

The Logs tab streams the running container’s stdout/stderr over SSE, starting from the last 200 lines. If the stream drops — a redeploy restarts the container, or the session needs refreshing — the tab reconnects on its own and starts over from the latest 200 lines, without duplicating what was already shown. For apps on a worker host, logs are read from that host. This is your application’s own output — distinct from the build output of a deployment. Any org member (viewer and up) can read it.

If the app has never deployed successfully, or is stopped, there’s no container to attach to and the tab reports that no running container exists yet.

Deployment logs

Build and deploy logs are captured per deployment and streamed live while the deploy runs (see Deployments). The stream ends on its own once the deployment finishes. Logs are kept with their deployment rows: the newest five per app always, plus the live deployment and any still in progress — older finished deployments’ logs and images are reclaimed by the prune job (see Image retention).

Platform-level metrics

Separately from per-app metrics, the control plane exposes its own Prometheus endpoint (deploy counts and durations, job-queue depth, DB-pool gauges) on an internal listener. See Operations & Hardening.