Skip to main content

System Diagnostics & Usage Analytics

Libre WebUI gives administrators two live views of the instance: a System page with host and runtime diagnostics, and a Usage page with model and provider usage analytics. Both are administrator-only in the backend and the interface. Reading either page stays inside the deployment; optional external telemetry is a separate, operator-configured Observability path.

Reach them from the sidebar admin entries, the tab menu's admin shortcuts, or directly at /system and /usage. Non-administrators cannot open either page, and the admin tabs are closed if a signed-in account loses the admin role.

System Diagnostics

The System page (/system) reports:

  • Host: hostname, platform, kernel release, architecture, uptime, logical CPU count, CPU model, load average, and whether the process looks containerized. There is no CPU utilization percentage; CPU load is the load average only.
  • Runtime: application version, Node.js version, process id, process uptime, and working directory.
  • Memory: total, free, and used host memory, plus the process RSS and heap figures.
  • Filesystems: capacity and usage for the runtime filesystem (/) and the data directory (DATA_DIR).
  • Network: interface names and addresses, with received/transmitted byte counters on Linux.
  • Docker: engine version, host OS, kernel, CPU and memory as the engine reports them, and container counts plus a reduced container list, when the Docker socket is available.

The page refreshes every 30 seconds while its tab is focused and has a manual refresh button. The backend endpoint is GET /api/system, guarded by authentication, an active administrator role, and a per-user rate limit of 120 requests per 15 minutes. Responses are never cached (Cache-Control: no-store), and every request collects fresh values.

Docker socket dependency

The Docker section resolves its endpoint the same way the Work runtime and interactive terminal do: WORK_DOCKER_SOCKET when set (always a local Unix socket path), otherwise DOCKER_HOST — a unix:// URL or a plain-HTTP tcp:// endpoint such as a filtered Docker API proxy — otherwise /var/run/docker.sock. ssh:// and npipe:// endpoints, and tcp:// with TLS verification enabled, are deliberately not queried. The requests are strictly read-only engine GETs (version, info, container list) with a 4-second timeout and a bounded response size, and the container list is capped at 100 entries.

Without a usable socket the rest of the page still works: the Docker panel reports why it is unavailable — socket not mounted, mounted but unreadable, daemon unreachable, or remote endpoint — instead of failing the whole request.

What the page reveals, and to whom

The container list is reduced on purpose: short id, name, image, state, and created time. Environment variables, labels, mounts, container commands, and inspect payloads are never included, and no credentials appear anywhere in the response.

The page still shows real infrastructure detail — hostname, working directory, internal IP addresses, and the names and images of every container on the Docker host, not only Libre WebUI's own. That is consistent with the trust model: in a Docker deployment every Libre WebUI administrator is already effectively a host administrator (see Docker). Grant the admin role accordingly.

Usage Analytics

The Usage page (/usage) charts user-attributed model and provider work. Metering happens at each supported execution boundary and currently covers:

  • local Ollama chat calls, including native Chat and Ollama-backed Work calls;
  • installed agent CLI chat calls;
  • native DSH provider calls in Chat, Work, titles, and thinking summaries;
  • plugin-backed chat, streaming and non-streaming;
  • plugin embeddings, image generation, speech to text, text to speech, sound, and video; and
  • plugin-backed Work calls.

Background operations without an owning user are deliberately not assigned to a synthetic account and therefore are not metered. A call is still recorded when it fails or is cancelled.

Each event records:

  • provider/plugin id and a snapshot of its display name (ollama, agent-cli:*, and dsh-native:* use the same ledger as plugin providers)
  • capability (chat, embedding, image, stt, tts, audio, video)
  • model
  • status: success, error, or cancelled (an aborted stream counts as cancelled)
  • token counts, only when the provider returned usage metadata
  • unit counters appropriate to the capability (characters for TTS, images, embedding inputs, jobs for video, bytes for audio)
  • end-to-end duration and a timestamp
  • the requesting user id

Native DSH entries are labeled DeepSeek Harness · provider, retain the exact native model, and count each inference once, including separate tool rounds. Input totals include the native adapter's disjoint cache-read/cache-write counters once. Catalog queries and rejected preflight checks are not inference events. DSH calls through an LWUI-configured provider keep that provider's existing record. Usage is not reconstructed for calls made before metering was installed. See Native provider usage.

Nothing else is stored. Prompts, responses, provider endpoints, credentials, and provider error bodies are never written to the usage table — a failed call is recorded only as status = 'error'. The events live in the selected application database (SQLite in solo mode, PostgreSQL in team mode) and are kept for 400 days; older rows are pruned opportunistically on write, at most once per day. Metering is best-effort by design and can never make a model or provider request fail.

The page offers 7, 30, and 90-day ranges over a single admin-only endpoint, GET /api/plugins/usage?days=<1..365> (default 30). It shows total calls, reported tokens, success rate, average latency, and the share of calls that reported token usage. Reading the page is read-only and uses the deployment's existing usage ledger.

Agent usage

The Agents section near the top shows Claude Code, Codex, OpenCode, Pi, and DeepSeek Harness separately. It includes each agent's calls, reported tokens, failed or cancelled calls, average duration, and up to 20 most-used models. Agent totals cover all matching calls in the selected period, independently of the larger provider and model tables' display limits. These are subsets of the page totals, not additional billable events.

An agent with no records says No recorded calls in this period. This does not indicate whether its CLI is installed or signed in. Calls without reported token metadata say Tokens not reported; missing counters are not estimated. The page refreshes every 20 seconds while visible and provides a manual refresh.

CLI usage records one invocation and the token counters reported by that CLI. Cumulative snapshots replace older snapshots, and repeated per-step reports are deduplicated. Cache and reasoning counters are combined according to each CLI's protocol, without counting subsets twice. Cancelled invocations and partial responses that exit unsuccessfully retain their actual outcome.

DSH here includes native provider requests, including tool rounds and auxiliary text requests. DSH using LWUI providers remains under those providers because the historical ledger does not identify the engine on those records. Calls made outside LWUI are not imported. Older records without token counters remain unmetered.

The endpoint exposes this bounded breakdown in agents, including all five supported names even when their counters are zero. Reading it does not discover CLI models, launch agents, or contact providers. Older servers without this field can show recorded agent entries from their provider breakdown; missing agent entries on those servers are not presented as confirmed zero usage.

Explore models and providers

Model colors connect the daily chart, yearly activity calendar, model table, and provider bars. Model names, values, and selection indicators accompany the colors. The activity calendar always covers the last 365 days, independently of the selected range; each day's color identifies its most-used model.

The daily chart switches between Calls and Tokens. Hover over a model in its legend or move keyboard focus to it to trace that model's line. Select the model to keep it highlighted, select it again to release it, or choose Show all models to reset. The model table also provides a highlight action. Highlighting changes emphasis while preserving the daily totals, table values, and provider totals.

Move the pointer across the chart or use Explore daily usage to inspect a day's total and model breakdown. The daily slider supports keyboard navigation: arrow keys move between days, and Home/End reach the first/last day. Daily buckets and their labels use UTC.

By default, the chart shows the top 12 model names by call count in the selected period, including when viewing tokens. Every model remains individually inspectable: focus or select a model in the table or provider details to load its exact daily line, even when it is outside those 12. A loading message names the requested model while its history is fetched.

An additional model's line is separated from Other models, and the remaining group excludes its calls, reported tokens, and failures. The chart contains at most 13 named model lines plus the remaining group, and their daily values still reconcile to the same totals. Choose Show all models to return to the default view.

Daily lines combine calls with the same recorded model name across providers. The model table retains separate provider/model entries, so the same model can appear under more than one provider. Named models retain individual colors in the table and provider bars, including models outside the default chart.

Provider details show each provider's share of requests, a bar divided by model, reported tokens, failed or cancelled calls, and average response time. The capability mix remains available below the model and provider breakdowns.

Token totals include only calls where the provider reported usage metadata. The coverage percentage makes partial reporting visible; missing token counts are never estimated from requests or from another model. A period with no reported tokens shows an explanation in the Tokens view, and its request history remains available in Calls.

The endpoint includes daily model points in modelSeries. An optional model query parameter requests one exact recorded model name alongside the default top 12, for example GET /api/plugins/usage?days=30&model=<encoded-model-name>. This is the same administrator-only, read-only endpoint: it queries the local usage ledger and never calls a model provider to retrieve history.

An optional to parameter fixes the request's end boundary to a Unix timestamp in milliseconds. It requires model and accepts only a non-negative safe integer no later than the server's current time. The browser sends the overview's range.to when loading an individual model, preserving its UTC day and year boundaries and excluding calls after that timestamp. Without to, the endpoint uses the current time.

Loading a model keeps the overview's cards, table, provider totals, and colors in place. Its daily line is added only when the response's time bounds and daily totals match that overview. The time boundary does not freeze the database: if historical backfills or deletions change those totals, the browser refreshes the overview before showing the model line.

If an older server omits modelSeries, the chart shows the aggregate All models series with an explanation that the model breakdown is unavailable. The model table remains available; the browser does not infer daily model history from period totals or the yearly calendar.

There is no switch to disable metering. Because the data is aggregated across accounts, inspecting it is restricted to administrators.

The Usage page reports calls, units, tokens, latency, and outcomes. Add Cost Governance when those events need effective-dated tariffs, spend breakdowns, budgets, alerts, or accounting export. Events without a matching tariff or provider-reported usage remain visibly unpriced rather than being treated as free.

OpenRouter attribution

Since 0.18.0, requests to OpenRouter identify the application through OpenRouter's app-attribution headers (HTTP-Referer: https://librewebui.org, an application title, and category hints). These headers are sent only when the request goes to https://openrouter.ai itself — never to a custom or self-hosted route — and they add nothing to what is stored locally.