One Trace Tells You What Happened. Langfuse Metrics Tell You What It Costs.
Metrics are not a second instrumentation project. They are sums and filters over the traces you already emit, and cost only exists on generations with a real model name.

Custom dashboards slice the names and tags you already set. Cost lives only on generations, and one empty chart usually means you renamed an observation.
You can open one ticket and see the tree. That does not tell you whether refund tickets got more expensive this week.
In this article: You will learn how Langfuse metrics turn the traces and scores you already emit into fleet answers: volume, cost, latency, and quality. We cover why cost only exists on
generationobservations with a real model name, how to build a Harbor Desk dashboard from the names and tags you already set, howapi.metrics.getpulls the same aggregations into your own job, and how alerts and spend alerts fire when a number crosses a line.
You can open Maya's soaked-life-jacket ticket and see the tree. Classify, retrieve, draft. Every span is there. That still does not tell you whether refund tickets got more expensive this week, or whether draft-reply slowed down after you shipped a less formal prompt.
Tracing answers one request. Langfuse metrics answer the fleet.
Harbor Desk is a support-ticket assistant. A ticket comes in. It classifies the intent as refund, shipping, or other, retrieves a short policy snippet, and drafts a reply. Langfuse derives metrics from the traces and scores you already have. You slice them in custom dashboards and through the Metrics API. Quality, cost and latency, and volume are the three measures. The dimensions are attributes you already attach: trace name, user, tags, release, version, prompt version, and model.
This is a dry topic. That is fine. A concrete cost surprise beats a metaphor.

Cost only exists on generations
Token usage and cost live on generation observations. Langfuse looks up pricing from the model name. If the name does not match the pricing table, automatic cost is missing. Usage details for input, output, and optional cached tokens power the token views. You can pass cost explicitly if you have a custom rate.
The OpenAI drop-in and most native integrations fill these fields. A manual span around an LLM call does not. The observation type is now a billing decision, not just a data-model nicety.
Harbor Desk's two model calls are the rows the cost dashboard will sum: classify-intent, draft-reply, or the Agent SDK turns that the instrumentor recorded. The retrieve-policy dict lookup should cost nothing. If it shows a model and tokens, you typed it as a generation.

Dashboards slice the names and tags you already set
Custom dashboards filter and aggregate by the observation names and tags you already treat as an API. Build one Harbor Desk board:
- Volume and cost by intent tag. Tag refund tickets
refund-flow. Tag shipping ticketsshipping-flowthe same way when you know the intent up front. - Latency of
draft-reply, the generation that writes the customer-facing draft. - Average
mentions-policyscore. Add a numerichelpfulnessjudge only if you want that chart.
If a chart is empty, you are filtering on a name that you renamed. The dashboard is another client of that API.

Score analytics trend the judges and the boolean checks you already attach. Put mentions-policy on the same board as cost. A cheaper draft that stopped quoting the policy is not a win.
You can also export metrics toward PostHog or Mixpanel if that is already where the company looks. That is an integration, not a replacement for the Langfuse board.
The Metrics API is the same aggregation, in your own job
The Metrics API is the same aggregations for your own board or billing job. From Python SDK v4 and JS SDK v5, api.metrics.get is the default.
The Metrics API query is a JSON string: pick the observations view, sum totalCost, and group by model name over a UTC window.
from langfuse import get_client
langfuse = get_client() # ①
query = """
{
"view": "observations",
"metrics": [{"measure": "totalCost", "aggregation": "sum"}],
"dimensions": [{"field": "providedModelName"}],
"filters": [],
"fromTimestamp": "2025-05-01T00:00:00Z",
"toTimestamp": "2025-05-13T00:00:00Z"
}
""" # ②
metrics = langfuse.api.metrics.get(query=query) # ③
① get_client() returns the process-wide client already configured from the environment.
② The query is a JSON string, not a Python dict: observations view, sum of totalCost, grouped by providedModelName, over a UTC window.
③ api.metrics.get runs that aggregation, the same call a custom board or billing job would use.
Note: The full extracted listing at code/langfuse/part-9-metrics-dashboards-cost/listings/01-metrics-api-query.py is the complete runnable program.

Alerts fire when a number crosses a line
Alerts fire when a metric crosses a line. On Cloud, the number of alerts depends on the plan: Hobby 2, Core 20, Pro 50, and Enterprise 100. Notifications can go to Slack, GitHub Actions, or a webhook. Spend alerts are the money-shaped cousin: a threshold on organization spend.
Harbor Desk's first useful tripwire is one daily spend alert. The dashboard tells you whether refund tickets got expensive. The alert tells you before you have to open the dashboard.

Do this today
Before you add another judge or another export, do four things.
- Confirm the two Harbor Desk model calls are
generationobservations with real model names.classify-intentanddraft-replyshould carry tokens and cost. If automatic cost is missing, the model name does not match the pricing table. Pass cost explicitly only if you have a custom rate. - Confirm
retrieve-policyis not ageneration. A dict lookup should cost nothing. If it shows a model and tokens, you typed it wrong. - Build one Harbor Desk dashboard. Volume and cost by
refund-flowandshipping-flow, latency ofdraft-reply, and averagementions-policy. If a chart is empty, you renamed the observation the filter still expects. - Create one spend alert on organization spend, and route it to Slack, GitHub Actions, or a webhook. Then, if you already have a billing board elsewhere, call
api.metrics.getwith atotalCostsum grouped byprovidedModelName.
Metrics are not a second instrumentation project
You do not need a new telemetry stack to know whether refund tickets got more expensive. You need sums and filters over the tree you already emit.
Cost needs generations with a real model name. Dashboards and alerts need stable names and tags. Score analytics need the judges you already attach, sitting on the same board as spend, so a cheaper draft that stopped quoting the policy does not look like a win.
Harbor Desk's first board is volume and cost by intent, latency of the draft, and the policy-mention score. Create that dashboard and one spend alert. The fleet will start answering questions one ticket never could.