Metric · Support

What is cost per ticket, and how do you measure it in Metabase?

Cost per ticket is your fully-loaded support cost divided by tickets handled in the same period. It's the metric that connects the support queue to the profit-and-loss statement — and the one finance will ask about first. Measure it in Metabase by joining a costs table from finance to ticket counts synced from Zendesk, Intercom, Freshdesk, or Kustomer.

TL;DRfully-loaded support cost ÷ tickets handledper month. Fix the numerator's definition once (salaries + tooling + overhead), segment by channel and tier, and never optimize it without CSAT on the same dashboard.

What cost per ticket measures

It measures the unit economics of support: what one resolved customer problem actually costs the business. The numerator is fully-loaded support cost — agent salaries and benefits, team leads and QA, help desk and tooling licenses, plus an overhead allocation. The denominator is tickets handled (or resolved, if you prefer the stricter cost per resolution) in the same period. Trended monthly it shows whether hiring, tooling, and self-service investments are paying off; segmented by channel it shows that a phone ticket can cost five times a chat ticket, which is what makes deflection and channel-steering decisions concrete.

What data does it need?

  • A costs table — one row per month per cost line, exported from finance or the budgeting tool. It rarely lives in the help desk, and that's fine: a small manually-loaded table works.
  • The tickets table from your help desk sync, with solved_at (or closed_at), channel, and a tier or group field.
  • For channel-level allocation, handle_minutes per ticket — without it you can only split by ticket count, which undercharges the slow channels.

SQL patterns

Monthly cost per ticketPostgreSQL

Joins a finance costs table to monthly ticket counts.

-- Fully-loaded monthly cost per ticket: support costs ÷ tickets handled.
-- support_costs holds one row per month per cost line (salaries, tooling,
-- overhead allocations) from finance's export.
WITH monthly_costs AS (
  SELECT
    date_trunc('month', c.cost_month)  AS month,
    SUM(c.amount)                      AS support_cost
  FROM support_costs c
  GROUP BY 1
),
monthly_tickets AS (
  SELECT
    date_trunc('month', t.solved_at)   AS month,
    COUNT(*)                           AS tickets_handled
  FROM tickets t
  WHERE t.solved_at IS NOT NULL
  GROUP BY 1
)
SELECT
  c.month,
  c.support_cost,
  t.tickets_handled,
  ROUND(c.support_cost / NULLIF(t.tickets_handled, 0), 2) AS cost_per_ticket
FROM monthly_costs c
JOIN monthly_tickets t USING (month)
ORDER BY c.month;
Cost per ticket by channelPostgreSQL

Allocates each month's cost by handle-time share, then divides by that channel's tickets.

-- Cost per ticket by channel, allocating each month's cost by the share
-- of agent handle time that channel consumed.
WITH monthly_costs AS (
  SELECT
    date_trunc('month', c.cost_month) AS month,
    SUM(c.amount)                     AS support_cost
  FROM support_costs c
  GROUP BY 1
),
channel_effort AS (
  SELECT
    date_trunc('month', t.solved_at) AS month,
    t.channel,
    COUNT(*)                         AS tickets,
    SUM(t.handle_minutes)            AS handle_minutes
  FROM tickets t
  WHERE t.solved_at IS NOT NULL
  GROUP BY 1, 2
)
SELECT
  e.month,
  e.channel,
  e.tickets,
  ROUND(
    c.support_cost
    * e.handle_minutes
    / NULLIF(SUM(e.handle_minutes) OVER (PARTITION BY e.month), 0)
    / NULLIF(e.tickets, 0), 2
  ) AS cost_per_ticket
FROM channel_effort e
JOIN monthly_costs c ON c.month = e.month
ORDER BY e.month, cost_per_ticket DESC;

Pitfalls

Counting only salaries in the numerator.→ Tooling, management, and overhead are real support costs. A salaries-only number understates cost per ticket and makes outsourcing quotes look worse than they are. Define "fully loaded" once and keep it.
Driving it down without a quality guardrail.→ Shorter handle times and aggressive closing lower cost per ticket and quietly raise reopens and churn. Pair it with CSAT and reopen rate, and judge the pair.
Comparing across channels by ticket count alone.→ A phone ticket consumes far more agent time than a chat. Allocate cost by handle time before comparing channels, or chat looks artificially expensive.
Ignoring ticket mix when the trend moves.→ Deflecting easy tickets raises average difficulty, so cost per ticket can rise even as total cost falls. Report total support cost next to the unit number so mix shift doesn't read as inefficiency.

Where this metric applies

Metrics

Analytics & dashboards

FAQ

What costs go into cost per ticket?
The fully-loaded version: agent salaries and benefits, the loaded cost of team leads and QA, help desk and tooling licenses, and an overhead allocation (facilities, IT, management). A salaries-only number looks flattering but understates the real cost by 30-50%. Whatever you include, write the definition down and hold it constant — the trend matters more than the absolute figure, and it only trends if the numerator is stable alongside ticket volume in the denominator.
What's the difference between cost per ticket and cost per resolution?
Cost per ticket divides by every ticket handled; cost per resolution divides by tickets actually resolved. If your resolution rate is high the two are close, but a queue full of stale-closed or abandoned tickets makes cost per ticket look better than the work justifies. Cost per resolution is the honest efficiency number; cost per ticket is easier to compute and fine for trending as long as you watch resolution rate next to it.
What is a good cost per ticket?
Published benchmarks run from a few dollars for chat-heavy consumer support to well over $100 for enterprise phone support, so cross-company comparisons are mostly noise. Compare against your own history and across your own segments instead: by channel, by tier, by topic. A rising cost per ticket with flat volume usually means mix shift toward harder tickets — segment before concluding the team got slower.
Why shouldn't you just minimize cost per ticket?
Because the cheapest ticket is one you close fast and badly. Aggressive cost-cutting shows up as falling CSAT, rising reopens, and eventually churn — costs that never land in the support budget. Track cost per ticket on the same dashboard as CSAT and reopen rate, and treat "cost down, satisfaction flat" as the goal rather than cost down at any price. Deflecting simple tickets with self-service (see deflection rate) cuts cost without cutting quality.
How do you track cost per ticket in Metabase?
Sync your help desk into a SQL database with a pipeline like Airbyte or Fivetran — Zendesk, Intercom, Freshdesk, and Kustomer all have connectors — then load a small monthly costs table from finance alongside it. One join gives you the trend; add channel and tier splits and pin them next to the agent performance dashboard.