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 bysettings-store.ts) returns aUsageStatsobject containing bucketed token totals and cost totals for a specified time window. - User Interface – The
daily-review-coordinator.tsmerges buckets and feeds a Usage Summary panel displaying tokens consumed, total cost, model breakdowns, and tool call counts. - Session Recovery – On startup,
recoverInterruptedSessions()scans theusage_llm_callsledger 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
LlmCallRecordin 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_overridesenable 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →