Revenue and cost, closing on one basis

What each user earns you — and what they cost.

DuckLedger is the revenue-metrics layer that also knows the other half of the equation. Normalized MRR, a movement waterfall, cohorts, churn and retention; cloud, AI APIs, expenses and suppliers. And the answer that only exists once both sides close: margin by product, by customer, by user.

Multi-product · RBAC · Encrypted secrets · No spreadsheet archaeology

Sample · current month

MRR

R$ 248.4k

Gross margin

63.3%

Cost / user

R$ 3.12

LTV:CAC

4.1×

Full revenue metrics

MRR, ARR, waterfall, NRR, GRR, cohorts and conversion funnel.

Every cost has an owner

Cloud, AI and expenses allocated to the product that caused them.

Margin per user

Revenue minus direct cost, down to the person and the session.

What it answers

The questions neither half of the equation can answer alone

A revenue tool knows what came in. A FinOps tool knows what went out. Neither closes the account for one specific customer. These are DuckLedger’s questions.

Revenue

Why did MRR move this month?
A typed waterfall: new, expansion, reactivation, contraction and churn — each movement written once and never revised.
Is the base retaining, or just growing over the leak?
NRR, GRR and quick ratio anchored to the snapshot the month opened on.
How many trials actually convert?
Trial and free→paid funnel with the outcome recorded when it happens, measured over resolved rather than started.
How much comes from cards, Pix and the app stores?
Asaas, App Store, Google Play and RevenueCat in one ledger, with fees and refunds separated from gross.

Cost

Which product spent the R$ 8k of AWS?
Cost Explorer imported and allocated by workspace, not one undifferentiated “infra” line.
What did the AI model cost, per feature?
Cost by provider, project and key, attributed to the product that made the call.
Does this cost serve a customer, buy one, or neither?
Explicit classification — cost of revenue, acquisition or overhead. Until it is classified, margin is not invented.
What is the real fixed cost per product?
Manual, recurring and CSV-imported expenses, with supplier and category.

Per user

What does serving this user cost?
Usage events and traces carrying measured or estimated cost, summed per person and per session.
Does this customer pay for what they consume?
Net revenue attributed to the customer, minus their direct cost — the contribution result.
What did that AI conversation cost?
A trace per conversation, checkout or job, with every step, provider and currency visible.
Does LTV cover CAC — in profit, not in revenue?
LTV computed on gross profit, payback by cohort, and churn weighted by margin.
The joint

Checkout to profit is six stages. Almost nobody crosses the fourth.

Revenue tools stop at stage 3. Cloud-cost tools start at 4 and never learn what came in. “Is this customer profitable?” lives exactly at the joint — and needs revenue and cost for the same product, in the same period, in the same currency.

  1. 1

    Charge

  2. 2

    Subscription

  3. 3

    Analytics

  4. 4

    Cost

  5. 5

    Allocation

  6. 6

    Profit

  • Revenue tools23

    MRR, churn, cohorts

  • Cloud FinOps tools45

    cloud cost by tag

  • DuckLedger26

    crosses the joint

The gateway moves the money at stage 1. DuckLedger explains the five that follow.

Revenue side

Subscription metrics that reconcile with the statement

Not a pretty MRR chart on top of a CSV. A ledger of movements, daily snapshots and outcomes written when they happen — because a canceled subscription no longer remembers what it was worth.

Normalized MRR and ARR

Weekly, monthly, quarterly, semiannual and annual compared after normalization. Moving 99 a month to 1,800 a year is 51 of expansion, not 1,701.

Movement waterfall

New, expansion, reactivation, contraction and churn — with voluntary churn separated from involuntary by the status the subscription lapsed from.

Cohorts and retention

Cohort retention, ARPU, average lifetime, and NRR/GRR anchored to the snapshot the month opened on.

Trial and free→paid funnel

Outcomes written once and never recomputed. Rate over resolved, with the still-open population always shown beside it.

Stores and in-app purchase

RevenueCat covers Apple, Google and web at once; App Store and Play also connect directly. Store commission and refunds kept apart from gross.

Brazilian payments, natively

Asaas built in: Pix, boleto, cards and subscriptions, with idempotent webhooks and per-gateway-account reconciliation.

Segmentation and forecast

Customer attributes, saved segments, and a revenue forecast built from observed movements.

Revenue attribution

Every payment resolved to the product that earned it — never “somewhere in the gateway.”

Cost side

Every cost with an owner and a classification

A cost with no product never becomes margin. DuckLedger imports spend where it originates, attributes it to a workspace, and forces a question accounting never asks: does this serve a customer, buy one, or neither?

AWS Cost Explorer

Automatic sync of spend by service, written as an expense on its competence date and allocated by product.

AI APIs by provider

OpenAI, Anthropic, OpenRouter, Gemini and more, with a daily sync and attribution by project, key and workspace.

Real expenses

Manual, recurring and CSV-imported, with supplier, category and competence date.

Cost classification

Cost of revenue, acquisition or overhead. Every category starts as overhead, so an unclassified one never silently inflates margin or CAC.

Allocation by product

Shared cost stays at the organization; each workspace’s P&L stays clean and comparable.

Unit cost

An auditable formula engine: total cost over active users, operations or requests — whichever metric you define.

Where it closes

LTV in gross profit, not in accumulated revenue

A revenue LTV tells you what a customer will pay. Only LTV on margin tells you what you keep — the one version comparable to what acquiring them cost. Four figures no revenue-only tool can produce.

gross margin  = (revenue − cost of revenue) / revenue
CAC           = acquisition spend / new customers
LTV (margin)  = ARPU × average lifetime × gross margin
LTV:CAC       = LTV (margin) / CAC
payback       = CAC / (ARPU × gross margin)

A month that acquired nobody does not have a CAC of zero — it has no CAC. A negative margin has no payback period. The figure comes back null instead of lying.

Illustration of operational metrics flowing into a unit-cost prism

Profit cohorts

Everyone charts revenue retention by cohort. Here the cohort accumulates gross profit until it covers what acquiring it cost — and the month that happens has a name.

Margin-weighted churn

Losing a high-margin customer and a negative-margin one are not the same event. One of them improves the company.

Cash and competence never sum

The margin rate comes from the P&L; recurring revenue lives on its own basis. Carrying the rate into MRR is standard practice — adding cash revenue to MRR is the error this separation exists to prevent.

Per user and per session

The cost of serving one person, event by event

Average cost per active user is a division, not a measurement. Instrument what the product actually does, and every model call, job and conversation gets an owner, a session, a currency and an amount.

Node SDK

One ingest key and one package. Batching, retries and idempotency on the event ID.

Supabase / PostgreSQL

Usage already lives in your tables: one read-only view and a scheduled query.

PostHog

Already-standardized events import directly with host, project and a personal key.

await usage.withTrace(
  {
    kind: 'conversation',
    name: 'Support chat',
    subject: user.id,
  },
  async (trace) => {
    trace.step('retrieveContext');

    usage.track({
      type: 'ai.tokens_spent',
      data: {
        model: 'gpt-4o',
        prompt_tokens: 1200,
        completion_tokens: 400,
      },
    });
  },
);

Tokens with no cost attached are priced from public list rates and marked estimated. Pass a measured cost and it replaces the estimate.

Illustration of product nodes converging into a central financial ledger
  • Traces that correlate the whole unit of work

    Conversation, checkout or job: every step, provider and service hop on one row, with duration and cost.

  • Measured and estimated never blur

    What the provider charged and what the price catalog computed carry different labels on the same screen.

  • Currencies sit side by side

    A trace that burned USD on a model and BRL on a gateway fee cost two things. Picking an exchange rate to merge them is your decision, not the cell’s.

  • Usage subject linked to the paying account

    Your app’s internal ID becomes the identity, and one account can pay for many users without multiplying the revenue.

How the numbers behave

A number that cannot be justified is not shown

This is not modesty — it is what separates a decision dashboard from a decorative one. When the basis is missing, DuckLedger says it is missing.

Null instead of zero

Spending R$ 3,000 and acquiring nobody is not free acquisition. With no basis the answer is null, and the screen says what still needs connecting.

Estimated is labeled estimated

A cost derived from list prices never dresses up as a measured one. The same holds for trace names inferred from the route.

Environments never mix

Sandbox and production are filed under the environment the event carries, not the one the connection was set to.

Nothing is counted twice

Idempotent webhooks, store aliases resolved to a single customer, and instrumented cost reconciled against the invoice rather than added to it.

Where it fits

Half the equation already has tooling. The whole one does not.

Compared by category of tool rather than by brand — the difference is not quality, it is scope.

  • MRR, churn, cohorts

    Revenue tools
    Does it well
    Cloud FinOps
    Does not
    Spreadsheet + accountant
    Does it partially
    DuckLedger
    Does it well
  • Apple and Google subscriptions

    Revenue tools
    Does it partially
    Cloud FinOps
    Does not
    Spreadsheet + accountant
    Does it partially
    DuckLedger
    Does it well
  • Pix, boleto and BR billing

    Revenue tools
    Does not
    Cloud FinOps
    Does not
    Spreadsheet + accountant
    Does it well
    DuckLedger
    Does it well
  • Cloud cost by product

    Revenue tools
    Does not
    Cloud FinOps
    Does it well
    Spreadsheet + accountant
    Does it partially
    DuckLedger
    Does it well
  • AI API cost

    Revenue tools
    Does not
    Cloud FinOps
    Does it partially
    Spreadsheet + accountant
    Does it partially
    DuckLedger
    Does it well
  • Margin and profit by product

    Revenue tools
    Does not
    Cloud FinOps
    Does not
    Spreadsheet + accountant
    Does it partially
    DuckLedger
    Does it well
  • LTV on gross profit

    Revenue tools
    Does not
    Cloud FinOps
    Does not
    Spreadsheet + accountant
    Does not
    DuckLedger
    Does it well
  • Cost and revenue per user

    Revenue tools
    Does not
    Cloud FinOps
    Does it partially
    Spreadsheet + accountant
    Does not
    DuckLedger
    Does it well
  • Answer the same day

    Revenue tools
    Does it well
    Cloud FinOps
    Does it well
    Spreadsheet + accountant
    Does not
    DuckLedger
    Does it well
How it works

From connection to margin in four steps

No six-week implementation. Wire the structure once, and the numbers compound on their own.

  1. 01

    Map the products

    One organization, one workspace per product. Shared cost stays at the org; each product’s P&L is comparable from day one.

  2. 02

    Connect revenue

    Asaas for Pix, boleto and cards; RevenueCat or the stores for in-app purchase. Backfill once, webhooks for the rest.

  3. 03

    Connect cost

    AWS Cost Explorer, AI providers and expenses. Classify each category as cost of revenue, acquisition or overhead.

  4. 04

    Instrument usage

    SDK, database or PostHog. From there, “what does this user cost and earn” has an answer with a name and a session.

Illustration of a shield and lock representing secure financial data
Security

Financial data treated as the production system it is

An ingest key lives on your server and its scope is deliberately narrow: send events, read the meter catalog, register a missing type. Nothing else.

  • HttpOnly cookies and rotating refresh tokens
  • Gateway and provider secrets encrypted at rest
  • Organizations, workspaces and permission-scoped RBAC from day one
  • Audit trail, including for machine actors
  • Read-only external database connections with TLS certificate verification
  • Signed webhooks with an auditable delivery log

Stop answering “are we profitable?” with an export.

If you run digital products and the revenue answer lives in one tool, the cost in another, and the margin in none — that joint is what DuckLedger closes.

Already on the team? Sign in and pick up where you left off.