LLM Usage Metering and Billing: Token-Based Revenue Infrastructure

TL;DR — LLM usage metering and billing is the revenue infrastructure for AI SaaS. Stripe introduced AI-focused billing in 2026: "Bill for LLM tokens without building a pricing engine. Stripe handles model price updates and usage metering for you." Four pricing models: pure usage-based (per token), subscription + overage (included allowance + per-token overage), credit-based (abstract tokens into credits), hybrid (subscription + usage). Flexprice: "tokens are no longer just a technical unit; they are the currency of AI operations." Zenskar covers 4 token pricing models and RevRec framework. Lago: "AI-based products often require hybrid pricing models that combine flat-rate subscriptions with usage-based billing." Metering architecture: event ingestion → pipeline → real-time accumulation (Redis) → persistent storage → pricing engine → invoice generation → reconciliation. Funnel all calls through single metering chokepoint. Integrate with per-tenant cost tracking, multi-tenant architecture, white-label, and BYOK.

Stripe's 2026 AI billing launch introduced "AI-focused metering and billing capabilities inside Stripe Billing, giving software companies infrastructure to charge for AI consumption the way cloud providers charge for compute: by the unit, in real time."

Flexprice states: "In 2026, businesses need to keep track of their Large Language Model (LLM) tokens because tokens are no longer just a technical unit; they are the currency of AI operations."

Metering and Billing Architecture

flowchart TD subgraph LLMCalls["LLM Calls"] Call1["Agent Call"] Call2["RAG Query"] Call3["Chat Message"] end subgraph Metering["Metering Chokepoint"] Extract["Extract Usage Block
(input/output/cache tokens)"] Attribute["Attribute to
tenant + user + model + feature"] end subgraph Pipeline["Event Pipeline"] Queue["Event Queue
(Redis Streams / Kafka)"] Accumulate["Real-Time Accumulation
(Redis atomic counters)"] end subgraph Storage["Persistent Storage"] Records["Usage Records
(PostgreSQL)"] Pricing["Pricing Engine
(model prices + markup)"] end subgraph Billing["Billing System"] Invoice["Invoice Generation
(Stripe / Lago)"] Credits["Credit System
(optional)"] Portal["Customer Portal
(usage + projected charges)"] end subgraph Reconciliation["Reconciliation"] Provider["Provider Invoice
(OpenAI / Anthropic)"] Compare["Compare Totals"] Alert["Alert on Gaps > 1%"] end Call1 --> Extract Call2 --> Extract Call3 --> Extract Extract --> Attribute Attribute --> Queue Queue --> Accumulate Accumulate --> Records Records --> Pricing Pricing --> Invoice Pricing --> Credits Invoice --> Portal Credits --> Portal Records --> Compare Provider --> Compare Compare --> Alert

Pricing Models Comparison

Model How It Works Best For Example Complexity
Pure usage-based Charge per token Variable usage $0.01/1K tokens Low
Subscription + overage Flat fee + per-token overage Predictable with caps $99/mo + 200K tokens, $0.02/1K over Medium
Credit-based Buy credits, consume per call Abstracting tokens 10K credits for $50 Medium
Hybrid Subscription + usage variable Most AI SaaS $49/mo + $0.005/1K tokens High
Tiered Price per token decreases with volume High-volume tenants $0.02/1K (0-1M), $0.015/1K (1M-10M) High
Enterprise contract Custom negotiated Large enterprises Custom pricing + committed spend Custom

Token Pricing by Model (2026)

Model Input ($/1M) Output ($/1M) Cache Read ($/1M) Cache Write ($/1M)
GPT-4o $2.50 $10.00 $1.25 $2.50
GPT-4o-mini $0.15 $0.60 $0.075 $0.15
Claude Sonnet 4 $3.00 $15.00 $0.30 $3.75
Claude Haiku 3.5 $0.80 $4.00 $0.08 $1.00
Gemini 2.0 Flash $0.10 $0.40
Llama 3.3 70B (self-hosted) $0.20* $0.20*

*Self-hosted cost = GPU cost / tokens served

Implementation

from datetime import datetime, timezone
from dataclasses import dataclass

@dataclass
class UsageEvent:
    tenant_id: str
    user_id: str
    model: str
    feature: str  # "rag", "chat", "agent", "embedding"
    input_tokens: int
    output_tokens: int
    cache_read_tokens: int = 0
    cache_write_tokens: int = 0
    timestamp: datetime = None

    def __post_init__(self):
        if self.timestamp is None:
            self.timestamp = datetime.now(timezone.utc)

    @property
    def total_tokens(self) -> int:
        return self.input_tokens + self.output_tokens


class LLMMeteringService:
    """Metering chokepoint for all LLM calls."""

    # Pricing per 1M tokens (updated from provider APIs)
    PRICING = {
        "gpt-4o": {"input": 2.50, "output": 10.00, "cache_read": 1.25, "cache_write": 2.50},
        "gpt-4o-mini": {"input": 0.15, "output": 0.60, "cache_read": 0.075, "cache_write": 0.15},
        "claude-sonnet-4": {"input": 3.00, "output": 15.00, "cache_read": 0.30, "cache_write": 3.75},
        "claude-haiku-3.5": {"input": 0.80, "output": 4.00, "cache_read": 0.08, "cache_write": 1.00},
    }

    # Credit conversion rates (credits per 1K tokens)
    CREDIT_RATES = {
        "gpt-4o": {"input": 3, "output": 12},
        "gpt-4o-mini": {"input": 0.2, "output": 0.8},
        "claude-sonnet-4": {"input": 4, "output": 18},
        "claude-haiku-3.5": {"input": 1, "output": 5},
    }

    def __init__(self, redis_client, db, stripe_client=None):
        self.redis = redis_client
        self.db = db
        self.stripe = stripe_client

    async def record_usage(self, event: UsageEvent) -> dict:
        """Record a usage event — the single metering chokepoint."""
        # Calculate cost
        cost = self._calculate_cost(event)

        # Calculate credits consumed
        credits = self._calculate_credits(event)

        # Store in database
        record = await self.db.insert("usage_records", {
            "tenant_id": event.tenant_id,
            "user_id": event.user_id,
            "model": event.model,
            "feature": event.feature,
            "input_tokens": event.input_tokens,
            "output_tokens": event.output_tokens,
            "cache_read_tokens": event.cache_read_tokens,
            "cache_write_tokens": event.cache_write_tokens,
            "total_tokens": event.total_tokens,
            "cost_usd": cost,
            "credits_consumed": credits,
            "timestamp": event.timestamp,
        })

        # Real-time accumulation in Redis
        pipe = self.redis.pipeline()
        month_key = event.timestamp.strftime("%Y-%m")
        day_key = event.timestamp.strftime("%Y-%m-%d")

        # Per-tenant accumulation
        pipe.hincrby(f"usage:{event.tenant_id}:{month_key}", "total_tokens", event.total_tokens)
        pipe.hincrby(f"usage:{event.tenant_id}:{month_key}", "cost_usd_cents", int(cost * 100))
        pipe.hincrby(f"usage:{event.tenant_id}:{month_key}", "credits", credits)
        pipe.hincrby(f"usage:{event.tenant_id}:{day_key}", "total_tokens", event.total_tokens)

        # Per-model accumulation
        pipe.hincrby(f"usage:{event.tenant_id}:{month_key}:models", event.model, event.total_tokens)

        # Per-feature accumulation
        pipe.hincrby(f"usage:{event.tenant_id}:{month_key}:features", event.feature, event.total_tokens)

        await pipe.execute()

        # Report to Stripe if configured
        if self.stripe:
            await self.stripe.report_usage(
                customer_id=await self._get_stripe_customer(event.tenant_id),
                usage=event.total_tokens,
                timestamp=event.timestamp,
            )

        return {
            "record_id": record.id,
            "cost_usd": cost,
            "credits_consumed": credits,
            "total_tokens": event.total_tokens,
        }

    def _calculate_cost(self, event: UsageEvent) -> float:
        """Calculate cost based on model pricing."""
        pricing = self.PRICING.get(event.model, {})
        return (
            (event.input_tokens / 1_000_000) * pricing.get("input", 0) +
            (event.output_tokens / 1_000_000) * pricing.get("output", 0) +
            (event.cache_read_tokens / 1_000_000) * pricing.get("cache_read", 0) +
            (event.cache_write_tokens / 1_000_000) * pricing.get("cache_write", 0)
        )

    def _calculate_credits(self, event: UsageEvent) -> int:
        """Calculate credits consumed based on credit rates."""
        rates = self.CREDIT_RATES.get(event.model, {})
        input_credits = (event.input_tokens / 1000) * rates.get("input", 1)
        output_credits = (event.output_tokens / 1000) * rates.get("output", 1)
        return int(input_credits + output_credits)

    async def generate_invoice(self, tenant_id: str, period: str) -> dict:
        """Generate invoice for a billing period."""
        usage = await self.db.aggregate("usage_records", [
            {"$match": {
                "tenant_id": tenant_id,
                "timestamp": {"$gte": self._period_start(period),
                              "$lt": self._period_end(period)},
            }},
            {"$group": {
                "_id": "$model",
                "total_tokens": {"$sum": "$total_tokens"},
                "input_tokens": {"$sum": "$input_tokens"},
                "output_tokens": {"$sum": "$output_tokens"},
                "cost_usd": {"$sum": "$cost_usd"},
                "credits_consumed": {"$sum": "$credits_consumed"},
                "request_count": {"$sum": 1},
            }},
        ])

        # Get tenant's pricing plan
        plan = await self._get_tenant_plan(tenant_id)

        # Calculate invoice based on pricing model
        if plan["model"] == "subscription_overage":
            total_tokens = sum(u["total_tokens"] for u in usage)
            included = plan["included_tokens"]
            overage = max(0, total_tokens - included)
            overage_cost = (overage / 1_000_000) * plan["overage_price"]
            total = plan["base_price"] + overage_cost

        elif plan["model"] == "credit_based":
            total_credits = sum(u["credits_consumed"] for u in usage)
            included_credits = plan["included_credits"]
            overage_credits = max(0, total_credits - included_credits)
            total = plan["base_price"] + (overage_credits * plan["credit_price"])

        elif plan["model"] == "pure_usage":
            total = sum(u["cost_usd"] for u in usage) * (1 + plan["markup_pct"] / 100)

        else:  # hybrid
            usage_cost = sum(u["cost_usd"] for u in usage)
            total = plan["base_price"] + usage_cost

        return {
            "tenant_id": tenant_id,
            "period": period,
            "usage_by_model": usage,
            "total_usd": total,
            "pricing_model": plan["model"],
        }

Credit System Examples

Platform Credit Unit Conversion Included in Plan
Salesforce Agent Work Units (AWU) 1 AWU = ~$2 execution cost Varies by edition
GitHub Premium requests Model-dependent multiplier 300/mo (Pro), 1000/mo (Team)
Workday Flex Credits Feature-dependent Enterprise contract
HubSpot Monthly credits Model + feature dependent Tier-dependent
Custom platform Platform credits Configurable per model Plan-dependent

LLM Usage Metering and Billing Checklist

  • [ ] Implement single metering chokepoint — all LLM calls flow through one path
  • [ ] Verify no LLM calls bypass the metering layer (grep for direct provider calls)
  • [ ] Extract usage block from every LLM response (input, output, cache tokens)
  • [ ] Attribute usage to: tenant_id, user_id, model, feature, agent_id
  • [ ] Implement real-time accumulation with Redis atomic counters
  • [ ] Store usage records in database for historical queries and billing
  • [ ] Build pricing engine with current model prices
  • [ ] Track cache tokens separately (cache read costs less than full input)
  • [ ] Update model prices automatically when providers change pricing
  • [ ] Choose pricing model: pure usage, subscription+overage, credit-based, hybrid
  • [ ] Configure markup percentage for usage-based pricing
  • [ ] Set up Stripe Billing integration
  • [ ] Configure Stripe model price syncing and markup
  • [ ] Report usage events to Stripe in real time
  • [ ] Set up automatic invoice generation at billing cycle end
  • [ ] Implement credit system (optional) — abstract tokens from customers
  • [ ] Configure credit-to-token conversion rates per model
  • [ ] Set up credit expiration policy (if applicable)
  • [ ] Build customer portal with real-time usage and projected charges
  • [ ] Show usage by model, feature, and time period
  • [ ] Display current period spend vs budget
  • [ ] Implement monthly reconciliation against provider invoices
  • [ ] Alert on reconciliation gaps > 1%
  • [ ] Track per-tenant usage: tokens, cost, credits, request count
  • [ ] Track per-model usage for cost optimization insights
  • [ ] Track per-feature usage for product analytics
  • [ ] Integrate with per-tenant cost tracking for budget enforcement
  • [ ] Integrate with multi-tenant architecture for tenant isolation
  • [ ] Support BYOK billing (platform fee only, no token markup)
  • [ ] Integrate with white-label reseller billing hierarchy
  • [ ] Implement tiered pricing (volume discounts for high-usage tenants)
  • [ ] Set up platform monitoring for billing system health
  • [ ] Apply zero-trust architecture to billing data
  • [ ] Implement dunning: handle failed payments gracefully
  • [ ] Set up revenue recognition (RevRec) for usage-based revenue
  • [ ] Consider semantic answer caching to reduce metered usage
  • [ ] Test billing accuracy: verify invoice matches usage records
  • [ ] Test reconciliation: verify platform totals match provider invoices
  • [ ] Document pricing model and billing cycle for customers
  • [ ] Quarterly review: audit billing accuracy, update model prices, review margins
  • [ ] Consider AI incident response for billing system failures

FAQ

What is LLM usage metering?

LLM usage metering is the system that tracks, records, and reports token consumption across all LLM calls in real time. Every LLM response contains a usage block (input tokens, output tokens, cache read tokens, cache write tokens). The metering system captures this data, attributes it to the correct tenant and user, calculates cost based on model pricing, and feeds it to the billing system for invoicing. Unlike traditional SaaS metering (API calls, storage), LLM metering must handle: (1) Real-time event ingestion — tokens must be counted as they're consumed. (2) Multi-dimensional attribution — tenant, user, model, feature, agent. (3) Dynamic pricing — model prices change frequently. (4) Cache token tracking — cache reads cost less than full input. (5) Reconciliation — per-tenant totals must match provider invoices.

What are the LLM pricing models?

Four main LLM pricing models: (1) Pure usage-based — charge per token (e.g., $0.01 per 1K tokens). Customer pays exactly for what they use. Best for variable usage patterns. (2) Subscription with included usage — flat monthly fee includes a token allowance, overage charged per token (e.g., $99/month includes 200K tokens, $0.02 per 1K overage). Best for predictable usage with caps. (3) Credit-based — customers buy credits, each LLM call consumes credits based on model and token count. Best for abstracting token complexity from customers. (4) Hybrid — subscription base fee + usage-based variable component. Most common in 2026. Stripe supports all four models with automatic model price syncing and markup configuration.

How does Stripe handle LLM token billing?

Stripe introduced AI-focused metering and billing capabilities in 2026. Features: (1) Automatic model price syncing — Stripe syncs model prices across providers (OpenAI, Anthropic, Google) so you don't track price changes manually. (2) Markup configuration — set your markup percentage in the Dashboard and Stripe configures all underlying model prices with your margin. (3) Usage metering — Stripe records token usage events in real time. (4) Invoice generation — automatic invoicing at end of billing cycle based on metered usage. (5) Hybrid pricing — combine subscription invoicing with real-time event metering on a single plan. (6) Customer portal — customers can view usage and projected charges. Implementation: report usage events to Stripe via API, Stripe handles pricing, invoicing, and collection.

What is a credit-based billing system for AI?

A credit-based billing system abstracts token complexity from customers. Customers buy or receive credits (e.g., 1,000 credits for $50). Each LLM call consumes credits based on the model and token count. Credit conversion: GPT-4o might cost 3 credits per 1K tokens, while GPT-4o-mini costs 1 credit per 1K tokens. Benefits: (1) Customers don't need to understand token economics. (2) Platform controls the credit-to-token conversion rate. (3) Credits can be included in subscription plans (Pro = 10,000 credits/month). (4) Credits can expire (use them or lose them). (5) Credits can be purchased in bulk at discount. Examples: Salesforce AWU (Agent Work Units), GitHub premium requests, Workday Flex Credits, HubSpot monthly credit pools. The billing unit must correspond to a concept customers can reason about.

How do you build a metering architecture for AI billing?

Build a metering architecture with: (1) Event ingestion — every LLM call produces a usage event (tenant_id, user_id, model, input_tokens, output_tokens, cache_tokens, timestamp). (2) Event pipeline — events flow through a queue (Kafka, Redis Streams) to the metering service. (3) Real-time accumulation — Redis atomic counters for per-tenant, per-user, per-model running totals. (4) Persistent storage — database for historical usage records and billing. (5) Pricing engine — apply current model prices to calculate cost. (6) Invoice generation — at billing cycle end, aggregate usage, apply pricing, generate invoice. (7) Reconciliation — compare platform totals against provider invoices. (8) Customer portal — real-time usage dashboard with projected charges. Use Stripe Billing or Lago for invoice generation. Funnel all LLM calls through a single metering chokepoint — even one call outside the meter creates month-end gaps.


Want a self-hosted AI company brain that does all of this out of the box?
Book a demo →