Net NinjasBook a call
All talks and takeaways

Worksheet

What does one AI action cost?

A worksheet and a SQL query that turn tokens, model prices, and request logs into a cost per AI action and per customer.

The B2B SaaS pattern from the talk has two halves. The retrieval layer isolates tenants in code, and the gateway meters what each AI action costs. I'm starting to see a lot of teams price an AI feature before they know the second number. The model invoice shows a monthly total, and the request logs show usage. Few of the teams I talk to have joined the two.

This worksheet joins them for one action, such as one answer from an in-product assistant. The example column uses round numbers, not a real price list. The last column is for your own. Model prices change often, so I'd take them from the provider's current price list on the day.

From the talk: Your AI feature is an architecture problem

The worksheet

LineHow I measure itExampleOurs
A. Model calls per actionThe calls behind one user-visible answer, with retries and tool loops.3
B. Input tokens per callThe median over a week of real requests: system prompt, retrieved context, and history.6,000
C. Output tokens per callThe median over the same week.500
D. Price per million input tokensThe provider's price list for the model in use.EUR 3.00
E. Price per million output tokensThe same price list.EUR 15.00
F. Model cost per actionA × (B × D + C × E) ÷ 1,000,000EUR 0.0765
G. Retrieval and platform cost per actionThe monthly cost of the vector store, the gateway, and logging, divided by that month's actions.EUR 0.0035
H. Cost per actionF + GEUR 0.08

The margin test

The same EUR 0.08 against one customer's plan of EUR 99 a month. The third row is the one I'd plan for.

CaseActions a monthAI cost a monthShare of the plan price
A typical customer300EUR 2424%
A heavy customer1,000EUR 8081%
The largest customer, at ten times typical use3,000EUR 240242%

The query

PostgreSQL. It assumes the gateway writes one row per model call, and that a second table holds the price list. Line G comes from the cloud bill.

cost_per_action.sql
-- cost_per_action.sql (PostgreSQL)
-- From the talk "Your AI feature is an architecture problem" (netninjas.eu/events).
-- Model cost per customer and per AI action over the last 30 days.
--
-- ai_requests:  one row per model call (tenant_id, action_id, model,
--               input_tokens, cached_input_tokens, output_tokens, created_at).
--               input_tokens counts the tokens billed at the full input price.
-- model_prices: one row per model, in euros per million tokens, copied from
--               the provider's current price list.

WITH calls AS (
  SELECT
    r.tenant_id,
    r.action_id,
    ( r.input_tokens        * p.input_per_million
    + r.cached_input_tokens * p.cached_input_per_million
    + r.output_tokens       * p.output_per_million ) / 1000000.0 AS cost_eur
  FROM ai_requests r
  JOIN model_prices p ON p.model = r.model
  WHERE r.created_at >= now() - interval '30 days'
)
SELECT
  tenant_id,
  count(DISTINCT action_id)                                AS actions,
  count(*)                                                 AS model_calls,
  round(sum(cost_eur), 2)                                  AS model_cost_eur,
  round(sum(cost_eur) / count(DISTINCT action_id), 4)      AS cost_per_action_eur
FROM calls
GROUP BY tenant_id
ORDER BY model_cost_eur DESC;

Four levers, in the order I pull them

  1. I cache the context that repeats. A system prompt and shared documents sent on every call are the cheapest tokens to stop paying full price for. An answer cache for repeated questions helps too.
  2. I route simple tasks to a smaller model. Classification, extraction, and routing rarely need the largest model. The evaluation set shows whether quality held.
  3. I trim what retrieval sends. Fewer, better chunks lower line B. The evaluation set guards the quality here too.
  4. I set quotas per tenant. Rate limits and plan limits at the gateway protect the margin. They also stop one customer from slowing the rest.

Reading the number

I read cost per action next to the price of the plan, not by itself. A feature at 5% of plan revenue has room to grow. A feature at 50% needs a limit or a new price before the next big customer signs. A second measurement a month later shows whether a lever worked.

What I leave out on purpose

I leave out self-hosting a model to save money, a FinOps platform, and usage-based pricing on day one. Self-hosting trades a variable cost for a fixed one and an on-call rota. I'd measure for a month first, because the number often changes the plan.

Next step

I highly recommend bringing last month's model invoice and your request count to a thirty-minute call. We'll join the two and get a first cost per action. What happens to your gross margin if your largest customer uses the feature ten times more next month?

Book a call

These takeaways are an engineer's reading of the rules and the tools. I wrote them to help teams decide what to build. They aren't legal advice. I recommend checking the current text with your own counsel before planning around a date or a threshold.

Let's talk.

A 30-minute call, no pitch. We look at your current setup, your stage, and the thing that's bothering you about it. I give a straight opinion on what to change, what to leave alone, and whether the problem is the one it looks like. What's the one thing in your stack you'd fix tomorrow?