{% extends 'base.html' %}
{% block title %}Usage & cost - Memorizz{% endblock %}
{% block head %}{% endblock %}
{% block content %}
{% from '_ui.html' import page_header, observability_tabs, empty_state %}
{% from '_fmt.html' import count, usd, usd_exact, percent %}
{% from '_run_health.html' import range_picker with context %}
{% from '_analytics_charts.html' import donut, bars %}
{% set window_labels = {'24h': 'Last 24 hours', '7d': 'Last 7 days', '30d': 'Last 30 days', '90d': 'Last 90 days', 'all': 'All recorded usage'} %}
{% set window_label = window_labels.get(window) or fmt_range(span) %}
{% set series = view.series %}
{% set totals = usage.totals %}
{% macro delta(entry) -%}
{%- if entry.delta is not none -%}
{{ '▲' if entry.delta > 0 else ('▼' if entry.delta < 0 else '') }} {{ '%.0f'|format(entry.delta|abs) }}%
{%- elif view.compared and entry.kind != 'percent' -%}
new
{%- endif -%}
{%- endmacro %}
{% macro figure(entry) -%}
{%- if entry.kind == 'usd' -%}{{ usd(entry.value, '—') }}
{%- elif entry.kind == 'duration' -%}{{ fmt_duration(entry.value) }}
{%- elif entry.kind == 'percent' -%}{{ percent(entry.value, 'Not reported') if entry.value is not none else '—' }}
{%- else -%}{{ fmt_compact(entry.value) }}
{%- endif -%}
{%- endmacro %}
{% call page_header('Usage & cost', 'Spend, tokens and model calls by agent, model and run, compared with the period before.', 'Operations', nav=observability_tabs('usage', {'traces': trace_url})) %}
{{ range_picker('/traces/usage', window, windows, span, query, {'all': 'All'}) }}
Export
{{ window_label }} {% if view.compared %}Compared with the {{ 'same length of time' if window == 'custom' else window_label|lower|replace('last ', '') }} before{% elif view.previous_empty %}Nothing recorded in the {{ 'same length of time' if window == 'custom' else window_label|lower|replace('last ', '') }} before, so no change is shown{% endif %} Updated {{ generated_at.strftime('%H:%M') }} UTC {% if not view.coverage.complete %}Partial read · {{ count(view.coverage.events) }} events{% else %}{{ count(view.coverage.events) }} events read{% endif %} {% if preserved_filters %}Trace selection kept · Clear{% endif %}
The newest {{ series.bars|length }} days are drawn; {{ series.clipped }} earlier ones are in the CSV by day.
{% endif %} {% if metric == 'spend' and totals.unpriced_calls %}{{ count(totals.unpriced_calls) }} call{{ '' if totals.unpriced_calls == 1 else 's' }} without a price {{ 'is' if totals.unpriced_calls == 1 else 'are' }} left out of spend. Set prices
{% endif %} {% else %} {{ empty_state('No model calls in this window', 'Choose a longer range, or clear the agent and model filters.') }} {% endif %}| Agent | Tokens | Calls | Spend | p95 |
|---|---|---|---|---|
| {% if row.filter_url %}{{ row.name }}{% else %}{{ row.name }}{% endif %} {% if not row.saved and row.agent_id %}Not saved in this store{% endif %} | {% if row.unknown_usage_calls == row.calls %}Not reported{% else %}{{ fmt_compact(row.total_tokens) }}{% if row.unknown_usage_calls %}{{ row.unknown_usage_calls }} not reported{% endif %}{% endif %} | {{ count(row.calls) }} | {% if row.cost is not none %}{{ usd(row.cost) }}{% if row.unpriced_calls %}+{{ row.unpriced_calls }} unpriced{% endif %}{% else %}No price{% endif %} | {{ fmt_duration(row.p95_latency_ms) }} |
No agent made a model call in this window.
{% endif %}| Model | Tokens | Calls | Spend | p95 |
|---|---|---|---|---|
| {{ row.model or row.label }}{{ row.provider }} | {% if row.unknown_usage_calls == row.calls %}Not reported{% else %}{{ fmt_compact(row.total_tokens) }}{% if row.unknown_usage_calls %}{{ row.unknown_usage_calls }} not reported{% endif %}{% endif %} | {{ count(row.calls) }} | {% if row.cost is not none %}{{ usd(row.cost) }}{% endif %}{% if row.price_url %}{% if row.cost is not none %}+{{ row.unpriced_calls }} unpriced{% endif %} Set price{% endif %} | {{ fmt_duration(row.p95_latency_ms) }} |
No model calls in this window.
{% endif %}| Started | Agent | Calls | Tokens | Spend | p95 | Trace |
|---|---|---|---|---|---|---|
| {{ relative_time(row.started, generated_at) if row.started else '—' }} | {{ row.agent_name }} | {{ count(row.calls) }} | {% if row.unknown_usage_calls == row.calls %}Not reported{% else %}{{ fmt_compact(row.total_tokens) }}{% endif %} | {% if row.cost is not none %}{{ usd(row.cost) }}{% else %}No price{% endif %} | {{ fmt_duration(row.p95_latency_ms) }} | {% if row.trace_url %}Trace{% endif %} |
No runs in this window.
{% endif %}| Agent | Model | Sessions | Turns | Tokens in | Cached | Tokens out | Spend |
|---|---|---|---|---|---|---|---|
| {{ row.label }} | {{ row.model or '—' }} | {{ count(row.sessions) }} | {{ count(row.turns) }} | {{ fmt_compact(row.input_tokens) }} | {{ fmt_compact(row.cached_tokens) }} | {{ fmt_compact(row.output_tokens) }} | {% if row.priced %}{{ usd(row.cost_usd) }}{% if row.priced < row.sessions %} + {{ row.sessions - row.priced }} unpriced{% endif %}{% else %}No price{% endif %} |
Codex and Claude Code sessions the MemoRizz plugin recorded, read from each agent's own session log and counted apart from the usage above. Cost is Claude Code's own total, or OpenAI list rates for Codex when its model has one; a ChatGPT plan isn't billed per token.
| Memory type | Approx. tokens | Times supplied | Reads | Read errors | Mean read | p95 read |
|---|---|---|---|---|---|---|
| {{ memory_label(row.label) }} | {{ count(row.memory_tokens_estimate) if row.supply_samples else '—' }} | {{ count(row.supply_samples) }} | {{ count(row.retrieval_samples) }} | {{ count(row.retrieval_errors) }} | {{ fmt_duration(row.retrieval_mean_ms) }} | {{ fmt_duration(row.retrieval_p95_ms) }} |
No memory measurements in this window. Agents record them when they read memory for a prompt.
{% endif %}