Insights

How to measure cost per moderation decision

What counts as cost, a formula you can compute from logs you already have, how to instrument each stage, a worked example and the usual ways to bring it down.

Nemanja Jeremenkovic · · 5 min read · Last reviewed September 15, 2026

Most platforms can tell you what they spend on moderation vendors each month. Few can tell you what it costs to decide one item. That second number is the one that matters, because it is the one that grows with your users.

Cost per decision tells you whether moderation is getting cheaper as you scale or quietly getting more expensive. It shows which stage of your pipeline is burning money, and it gives you a way to compare a vendor, an open model and a human reviewer on the same scale.

What counts as cost

A decision is any time your system settles an item: allow, remove, restrict, or send to review. Count everything it took to get there:

  • Model and vendor calls. Classifier APIs, LLM tokens, image and video scanning, hash matching services.
  • Compute. The infrastructure your own pipeline runs on: queues, workers, self hosted models, storage for evidence.
  • Human review. Reviewer time for items that reach a person. This is usually the largest line, even when it is a small share of items.
  • Rework. Appeals and reversals. A wrong decision is paid for twice.

Leave out fixed costs that do not change with volume, such as your policy team's salaries. They matter, but they do not tell you how the system scales.

The formula

For a period, usually a month:

cost per decision = (model and vendor spend
                   + variable compute
                   + reviewer hours x loaded hourly cost
                   + appeal handling cost)
                  / decisions made

Then break it down by stage. The total is useful for a board slide. The per stage number is useful for engineering:

stage cost per decision = stage spend / items that stage settled

The denominator is items the stage settled, not items it saw. A classifier that sees everything and settles almost nothing is expensive even if each call is cheap, because it passes its work down.

Instrumenting each stage

You need three facts for every item, logged at every stage:

  1. Which stage settled it. Fast filter, classifier, policy judge or human.
  2. What that stage cost for this item. Token counts and price for LLM calls, per call price for vendors, handling time for reviewers.
  3. How long it took. Latency per stage, and total time to action.

For LLM calls, log input and output token counts from the API response and multiply by current prices kept in configuration, not hard coded, so a price change does not need a deploy. For vendors billed per call, log the call. For human review, log when an item was opened and closed in the review tool.

With those three fields in one table, cost per decision is a query:

select settled_by,
     count(*) as decisions,
     sum(cost_usd) as spend,
     sum(cost_usd) / count(*) as cost_per_decision,
     percentile_cont(0.95) within group (order by latency_ms) as p95_ms
from moderation_decisions
where decided_at >= date_trunc('month', now())
group by settled_by;

A worked example

The numbers below are made up to show the method, not taken from a client.

A community app makes 3,000,000 decisions a month.

| Stage | Settled | Spend | Cost per decision at this stage | |---|---|---|---| | Fast filters | 2,100,000 | $300 | $0.00014 | | Classifiers | 780,000 | $2,400 | $0.0031 | | Policy judge | 105,000 | $1,050 | $0.010 | | Human review | 15,000 | $9,000 | $0.60 | | Total | 3,000,000 | $12,750 | $0.00425 |

Two things stand out. Human review is 0.5 percent of decisions and 70 percent of spend. And in this setup the classifier runs in parallel with the fast filters, so it is called on all 3,000,000 items, including the 2,100,000 the filters settle anyway. Most of its $2,400 buys decisions that were already made.

That points to two changes: run fast filters first so the classifier only sees the 900,000 items left, and look at which items reach humans that the policy judge could have settled with a clearer policy.

How to bring it down

Put cheap layers first. Every item a hash match or rule settles is an item nothing expensive has to look at. See the moderation cascade.

Tune thresholds on your data. A wide "unsure" band sends too much to the judge and to people. Narrow it where your labeled data shows the classifier is reliable.

Rank the human queue by risk. Cost per human decision falls when reviewers see context already gathered, and when the lowest risk items are settled by automation or time out safely.

Cache repeat content. Spam and scams repeat. A normalized cache of recent decisions settles repeats at near zero cost.

Watch the rework rate. A cheaper decision that is reversed on appeal is not cheaper. Track appeals and reversals per stage next to cost.

Recheck prices. Model prices change often, usually downward. A monthly look at per token prices and vendor contracts is one of the cheapest wins available.

What good looks like

There is no universal target, because harm mix and risk tolerance vary so much. What matters is the trend. On a healthy system, cost per decision falls as volume grows, the share settled by fast filters and classifiers rises, and time to action falls with it.

Relevant for creator and live platforms, generative ai apps, communities and social apps.