How Apache Maka Tracks Model Usage, Maintains a Usage Ledger, and Calculates Pricing

Apache Maka records every LLM interaction in an append-only JSONL ledger stored in SQLite, buckets the data for efficient aggregation, applies configurable pricing rules to compute per-turn costs, and exposes the data through a telemetry API for billing and session recovery.

Apache Maka implements a comprehensive model usage tracking system that captures every prompt, token count, and tool call in an immutable ledger. This architecture serves as the source-of-truth for billing and enables exact session recovery after crashes. Understanding how Maka handles model usage tracking, ledger maintenance, and pricing calculation is essential for developers integrating custom models and cost controls.

Recording Model Calls

When the runtime-host executes a model call, it creates a LlmCallRecord containing metadata required for billing and reconstruction. This record includes the model_key (e.g., gpt-4-turbo), session_id, unique request_id, detailed token_usage (prompt, completion, and cached tokens), usageBasis (raw token counts), and costBasis (monetary value computed later).

The record is ingested via admitLlmCall() and persisted to the usage_llm_calls table by packages/storage/src/sqlite-usage-store.ts. The storage layer uses an append-only strategy, inserting the JSON-serialized record into SQLite with a unique storage key:

// Simplified flow from sqlite-usage-store.ts
const admitted = await admitLlmCall(record);
this.#lease.database
  .prepare(`INSERT INTO usage_llm_calls(storage_key, id, ts, record_json, session_id)
            VALUES(?, ?, ?, ?, ?)`)
  .run(usageIdentityKey(admitted.id), admitted.id, admitted.ts,
       JSON.stringify(admitted), admitted.session_id);

This insertion guarantees exact-once semantics; once written, the row is read-only and immutable, forming the foundation of the usage ledger.

The Immutable Usage Ledger

Maka maintains the ledger as an append-only log of JSONL entries within the usage SQLite schema. To support efficient querying and UI rendering, raw records are periodically bucketed by model, time interval, and session using usageBucketKey from packages/storage/src/usage-stats-store.ts.

A bucket aggregates data into a compact structure:

{
  "model_key": "gpt-4-turbo",
  "time_bucket": "2024-08-27T00:00:00Z",
  "tokens_used": 12345,
  "cost_usd": 3.21
}

The mergeUsageBuckets utility (from @maka/core/usage-ledger-merge and utilized in packages/runtime-host/src/server/daily-review-coordinator.ts) combines per-session buckets into global summaries. This merging produces the compact usage statistics displayed in the UI, such as "12 k / 100 k tokens" progress indicators.

Configuring Pricing Rules

Pricing configuration in Maka is dynamic and model-specific. The system stores overrides in the usage_pricing_overrides table, which contains PricingConfig entries with model_key, price_per_token_usd, and optional price_per_output_token_usd.

The coordinator loads the active pricing authority via packages/storage/src/sqlite-usage-store.ts (querying SELECT * FROM usage_pricing_authority). If no override exists for a specific model, Maka falls back to a default pricing map defined in @maka/core/usage-stats/types, such as OpenAI’s standard rates (e.g., $0.03 per 1,000 prompt tokens for gpt-4-turbo).

This hierarchy allows operators to inject custom rates for private or fine-tuned models without modifying core code.

Calculating Token Costs

Cost calculation occurs when persisting the LlmCallRecord. The system projects usageBasis into costBasis by applying the active PricingConfig to token counts. The logic distinguishes between input (prompt) and output (completion) tokens to support divergent pricing tiers:

function computeCost(record: PersistedLlmCallRecord, pricing: PricingConfig) {
  const promptCost = (record.promptTokens / 1000) * pricing.price_per_token_usd;
  const completionCost = (record.completionTokens / 1000) *
                        (pricing.price_per_output_token_usd ?? pricing.price_per_token_usd);
  return promptCost + completionCost;
}

The resulting costUsd is stored alongside the record, enabling exact per-turn billing and accurate aggregate session cost tracking.

Consuming the Usage Ledger

Maka exposes ledger data through multiple interfaces:

  • Telemetry API – The readUsageStats(range) function (exposed by settings-store.ts) returns a UsageStats object containing bucketed token totals and cost totals for a specified time window.
  • User Interface – The daily-review-coordinator.ts merges buckets and feeds a Usage Summary panel displaying tokens consumed, total cost, model breakdowns, and tool call counts.
  • Session Recovery – On startup, recoverInterruptedSessions() scans the usage_llm_calls ledger to rebuild session state without re-executing model calls, preserving the exact-once execution guarantee.

Implementation Examples

Recording a Model Call

The following pattern demonstrates how runtime components record usage within a write transaction:

import { admitLlmCall } from '@maka/core/usage-stats';
import { openWriter, closeWriter } from '@maka/core/async';

async function handleModelCall(sessionId: string, requestId: string, usage) {
  const record = {
    model_key: usage.modelKey,
    session_id: sessionId,
    request_id: requestId,
    promptTokens: usage.promptTokens,
    completionTokens: usage.completionTokens,
    usageBasis: usage.promptTokens + usage.completionTokens,
  };
  const admitted = await admitLlmCall(record);   // validates & adds timestamps
  await openWriter(() => openInteractiveUsageStoresForWrite(), async (stores) => {
    await stores.usage.appendLlmCall(admitted); // writes to SQLite ledger
  });
}

Querying Aggregated Usage

Retrieve bucketed statistics for the last 24 hours using the telemetry API:

import { readUsageStats } from '@maka/core/settings-store';

async function getUsageSummary() {
  const stats = await readUsageStats('24h'); // returns UsageStats
  console.log('Tokens used:', stats.total.tokens);
  console.log('Cost (USD):', stats.total.costUsd);
}

Overriding Pricing for Custom Models

Operators can inject custom pricing at runtime, which immediately affects subsequent cost calculations:

import { setPricingOverride } from '@maka/core/pricing-store';

await setPricingOverride({
  model_key: 'my-custom-model',
  price_per_token_usd: 0.0015,
  price_per_output_token_usd: 0.0020,
});

This override persists in usage_pricing_overrides and takes precedence over default rates.

Key Source Files

Component Source Path Responsibility
Usage Persistence packages/storage/src/sqlite-usage-store.ts Appends immutable LlmCallRecord entries to the SQLite ledger.
Bucket Aggregation packages/storage/src/usage-stats-store.ts Groups raw records into time-bucketed summaries using usageBucketKey.
Pricing Authority packages/runtime-host/src/protocol/usage-pricing.ts Loads pricing overrides and provides the active PricingConfig.
Ledger Merging @maka/core/usage-ledger-merge Utility for merging per-session buckets into compact global summaries.
Daily Review packages/runtime-host/src/server/daily-review-coordinator.ts Consumes usage data to render UI summaries and reports.
Architecture Docs docs/session-task-ledger-lifecycle.md Defines ledger invariants, lifecycle, and recovery procedures.

Summary

  • Maka captures every LLM interaction as an immutable LlmCallRecord in an append-only SQLite ledger.
  • The usage ledger uses time-based bucketing and merging utilities to aggregate raw data for efficient querying.
  • PricingConfig objects stored in usage_pricing_overrides enable per-model rate customization with fallback defaults.
  • Costs are calculated per-turn using distinct input and output token rates, ensuring transparent billing.
  • The ledger supports session recovery, telemetry APIs, and UI dashboards while guaranteeing exact-once execution semantics.

Frequently Asked Questions

How does Maka prevent duplicate billing after a crash?

Maka implements exact-once semantics by writing LlmCallRecord entries to the immutable ledger before acknowledging a model response to the user. During recovery, recoverInterruptedSessions() scans the usage_llm_calls table to reconstruct session state without re-executing calls, ensuring no duplicate tokens are recorded or billed.

Can I set different prices for input and output tokens?

Yes. The PricingConfig interface supports price_per_token_usd for input (prompt) tokens and an optional price_per_output_token_usd for completion tokens. If the output-specific field is omitted, the system defaults to the input price. Set these via setPricingOverride() to apply custom rates for specific models.

Where is the usage ledger physically stored?

The ledger resides in a SQLite database under the "usage" schema, managed by packages/storage/src/sqlite-usage-store.ts. Records are stored as JSONL in the usage_llm_calls table, while pricing overrides live in usage_pricing_overrides. This file-backed storage ensures durability and ACID compliance for billing data.

How does Maka handle pricing for unknown models?

If a model lacks an entry in usage_pricing_overrides, Maka falls back to the default pricing map defined in @maka/core/usage-stats/types. This map contains hardcoded rates for popular providers like OpenAI. For truly unknown models without defaults, the cost calculation yields zero until an operator injects a pricing override.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →