Gross margin by customer
@agentcosts/gross-margin-by-customer
Gross margin per customer for an AI product: revenue minus LLM cost minus allocated hosting and other cost of revenue. Flags negative and below-target customers, names the task driving their cost, and gives the price each one would need to hit your target margin.
- Activity
- New: be the first to try it
- Installs
- 0 installs
- Likes
- 0 likes
- Clones
- 0 clones
- 1---
- 2name: gross-margin-by-customer
- 3description: Calculate gross margin per customer for an AI or agentic product from LLM usage, revenue by customer, and other cost of revenue such as hosting, vector databases, and support tools. Flags customers with negative or below-target margins, shows which task drives their cost, and the price that would hit the target. Use when the user asks "which customers lose us money", "gross margin by customer", "unit economics per account", "are we profitable on this customer", or is preparing pricing or a board finance review for an AI product.
- 4license: MIT
- 5---
- 7# Gross margin by customer
- 9AI products have a cost of goods that moves with usage, so two customers on the same plan can have very different margins. This kit puts revenue, model costs, and the rest of cost of revenue side by side per customer and month, so pricing conversations start from facts.
- 11## Inputs
- 131. **Usage** in the shared schema (`timestamp, customer, task, model, tokens..., cost_usd`). From app logs, or from provider exports via the `llm-usage-normalizer` kit. Blank `cost_usd` is priced with `--prices` (check those prices against each provider's current pricing first).
- 142. **Revenue** `data/revenue.csv`: `customer,month,revenue`. Use recognized monthly revenue (an annual contract is 1/12 per month), net of discounts. Customer names must match the usage file exactly.
- 153. **Other cost of revenue** (optional) `data/cogs.csv`: `item,month,amount,allocation`. Allocation is `usage` (by LLM cost share, good for hosting and vector databases), `revenue` (payment fees), `even` (per-customer tools), or `customer:<name>` (dedicated infrastructure). Only cost of revenue belongs here, not sales or R&D.
- 164. **Target margin** (default 70%, `--target 0.7`). Ask the user; 60 to 80% is common for software with AI features.
- 18## Steps
- 201. Check that customer names match between usage and revenue. List names that appear in only one file and fix them with the user (usually a naming mismatch or an unmapped API key).
- 212. Run:
- 23 ```bash
- 24 node scripts/margin.mjs data/usage.csv --revenue data/revenue.csv --cogs data/cogs.csv --prices data/llm-prices.csv --target 0.7 --out out/margin
- 25 ```
- 273. Read `out/margin.md` and report per month: overall gross margin, each negative customer, each below-target customer, and the task that drives their cost.
- 284. Explain the levers for each problem customer, in this order:
- 29 - **Cost:** cheaper model for that task's simpler steps, better prompt caching, fewer retries (a low success rate burns money).
- 30 - **Packaging:** usage caps or overage on the heavy task (see `consumption-guardrails`).
- 31 - **Price:** `price_for_target` is what they would need to pay to hit the target. Use `usage-pricing-simulator` to test a new model on everyone before changing one deal.
- 325. Mention unattributed LLM cost (internal use, evals, trials). It is real cost even though it is not in any customer's margin.
- 34## Output template
- 36```markdown
- 37**October gross margin: 57% (target 70%).**
- 38- cobalt-labs: -116% ($60 revenue, $130 cost). 96% of cost is research_agent. Needs $433/mo for 70%.
- 39- northwind-co: 40%. research_agent again. Needs $477/mo.
- 40- Everyone else is above 80%.
- 41Biggest lever: research_agent cost per run. Next: model choice for its steps, then usage-based pricing for it.
- 42```
- 44## Guardrails
- 46- Margins use the price table you give it. Say "based on the example prices" if the user has not checked them.
- 47- Revenue and margins per customer are sensitive. Keep them in `out/` and do not paste the full table into shared channels.
- 48- This kit does not change prices or contracts. It informs a decision people make.
