@takk/tokenforecast - v1.0.0 - Apache-2.0

See your LLM bill before it arrives.

Your spend on OpenAI, Anthropic, or any provider creeps up, and you find out at the end of the month. By then the overrun already happened. Token Forecast learns your consumption pattern per provider, model, feature, and user, then projects the next days of spend with a prediction interval and a backtested error, so you see the overrun coming and act before the invoice.

53tests passing
95%line coverage
0runtime deps
SLSAprovenance
What it is

One library, two answers.

In a few words

You feed Token Forecast a stream of cost events, one per LLM call, each carrying the provider, model, feature, user, token counts, and the cost you computed. It buckets them into a clean daily or hourly series, learns the trend and the daily and weekly rhythm of your spend, then projects the next days forward with a low and high band around the expected number. Ask it to attribute a cost jump, flag a budget breach, or price a model swap, and it answers from the same data.

Technically

A classical time-series engine: UTC-aligned, zero-filled bucketing, additive trend and seasonal decomposition, and exponential smoothing (Holt-Winters, Holt, SES, seasonal-naive) auto-selected by an out-of-sample rolling-origin backtest. Prediction intervals come from an inverse-normal quantile clamped at zero; anomalies use a robust median-absolute-deviation z-score; drift uses a two-sided Page-Hinkley test. Cold-start blends a caller-supplied Bayesian prior with thin history. Zero runtime dependencies.

Before and after

The same overrun, two timelines.

Take a real production scene: a new prompt template ships and quietly doubles output tokens per call. Your monthly LLM budget is fixed, and the dashboard only shows month-to-date.

Without Token Forecast

Find out at month end, scramble after

  1. Day 1 The new template ships. Output tokens per call quietly double.
  2. Day 1 to 12 Daily spend drifts up. Nobody notices; the chart only shows a running total.
  3. Day 18 Finance flags the monthly budget is already 90% consumed.
  4. Day 18 An engineer greps logs by hand to find which feature and model drove it.
  5. Day 22 The cause is found, but the month is mostly spent.
  6. Day 30 The invoice lands 40% over budget.
  7. A postmortem is scheduled. The overrun already happened.
With Token Forecast

Caught on day six, fixed the same day

  1. Day 1 to 6 The same events flow into Token Forecast as you already record them.
  2. Day 6 drift() fires up with a Page-Hinkley change point at day 1.
  3. Day 6 budget() returns willExceed: true with exceedAt near day 22.
  4. Day 6 attribute(day1, 'feature') shows the new template accounts for 78% of the delta.
  5. Day 6 simulate() prices a swap to a cheaper model at 31% savings, enough to stay under budget.
  6. Day 6 You ship the fix with the month still ahead of you.
  7. The overrun was caught on day six, not day thirty.

The "With Token Forecast" timeline is the literal output of detectDrift, budgetForecast, attribute, and simulate over one event stream. Every forecast it shows ships with the backtested error (MAPE and sMAPE) that earned it.

Install

Five minutes from install to first forecast.

1. Add the package

pnpm add @takk/tokenforecast
npm install @takk/tokenforecast
yarn add @takk/tokenforecast
bun add @takk/tokenforecast

2. Optional: bridge a token meter

The core has zero runtime dependencies. Skip this unless you want to feed readings straight from an @takk/alkaline token meter, or pair it with another sibling package.

pnpm add @takk/alkaline # optional: bridge
                token-meter readings

3. Quickstart: forecast from cost events

import { createForecaster } from '@takk/tokenforecast';

const tf = createForecaster({ granularity: 'day' });

// Record one cost event per LLM call (you compute the cost).
tf.add({
  at: Date.now(),
  provider: 'openai',
  model: 'gpt-4o',
  feature: 'chat',
  user: 'acme',
  inputTokens: 1200,
  outputTokens: 800,
  cost: 0.018,
});

// Forecast the next 14 days with a 90% prediction interval.
const result = tf.forecast({ horizon: 14, level: 0.9 });
console.log(result.method, result.points[0]);

// Will a 500 USD monthly budget hold?
const budget = tf.budget(500, { horizon: 30 });
console.log(budget.willExceed, budget.utilization);

4. Quickstart: the CLI

# events.json is a JSON array of cost events you exported.
npx @takk/tokenforecast forecast events.json --horizon 14 --level 0.9 --budget 500

# Explain a cost change across a dimension.
npx @takk/tokenforecast attribute events.json --at 1750000000000 --by feature

# Detect a change in spend behavior.
npx @takk/tokenforecast drift events.json
Features

Nine capabilities, every one tied to a measurable outcome.

Spend forecasting

Exponential smoothing (Holt-Winters, Holt, SES, seasonal-naive) auto-selected by an out-of-sample rolling-origin backtest, with a symmetric prediction interval clamped at zero.

See the expected spend and a high and low band for the next days or hours before the invoice, not after.

Backtested accuracy

Every forecast ships the error that earned it: MAPE, sMAPE, and MAE from held-out history, plus the number of samples evaluated.

Know how far to trust a number, not just the number, so a wide interval is a signal, not a surprise.

Cost attribution

Decompose a cost change between two windows across provider, model, feature, or user, ranked by absolute delta with each driver's share of the total.

Answer "what drove the jump" in one call instead of grepping logs across a billing period.

Drift detection

A two-sided Page-Hinkley test flags a change point in cost behavior, with the index, the bucket time, and the direction of the shift.

Catch a regime change days after it starts, not at month end when the budget is already spent.

Price-shift detection

Derives each model's effective unit price (cost over tokens) across two windows and flags real billing changes straight from your recorded data, no external feed.

Know when a provider price change silently invalidated a forecast trained on the old price.

Budget forecasting

Projects whether a budget will be breached over a horizon, the expected and worst-case spend, and the bucket at which cumulative spend first crosses the ceiling.

Alert on a willExceed flag and an exceedAt date instead of a month-end shock.

What-if scenarios

Re-cost recorded usage under model swaps over a bring-your-own price book, returning baseline cost, scenario cost, the delta, and the savings fraction.

Price a model migration before you run it, with no provider price table to go stale.

Seasonality and anomalies

Learns a multiplicative daily and weekly profile and scores each bucket with a robust median-absolute-deviation z-score that falls back to standard deviation.

Separate a real spike from the normal weekday rhythm instead of paging on every Monday.

Cold-start prior

For a brand-new feature with too little history, blends a caller-supplied Bayesian prior with the thin data through a conjugate normal-mean update, widening the interval honestly.

Get a usable, wide-interval forecast from day one instead of an insufficient-data error.

Forecasting methods

Five methods, auto-selected by backtest.

You never pick by hand. forecast() runs an out-of-sample backtest and keeps the lowest-error method. Force one with options.method when you need byte-stable output.

Method How it models the series When it wins
holt-winters Level, trend, and a repeating seasonal component. Spend with a clear daily or weekly rhythm and at least two full seasons of history.
holt Level and trend, no seasonality. A steady climb or decline with no repeating cycle.
ses Level only (simple exponential smoothing). Flat, noisy spend with no meaningful trend or season.
seasonal-naive Repeats the last observed season forward. Strong seasonality but too little history to fit Holt-Winters.
cold-start Blends a caller-supplied Bayesian prior with the thin history. A brand-new feature or model with fewer than four buckets and a supplied prior.

Selection is by lowest out-of-sample error on a rolling-origin backtest; every forecast carries the MAPE and sMAPE it scored so the choice is auditable.

Entry points

Nine subpaths, import only what you need.

Entry point Subpath export What it gives you Use it when
Core @takk/tokenforecast createForecaster, every pure function, errors, types. The default. You want the whole engine behind one facade.
Ingest @takk/tokenforecast/ingest bucketEvents, filterEvents, seriesValues, totalCost. You only need to shape raw events into a uniform series.
Features @takk/tokenforecast/features decompose, seasonalProfile, anomalies. You want trend, seasonality, or anomaly scores.
Forecast @takk/tokenforecast/forecast forecast, budgetForecast. You only need projections and budget-breach checks.
Attribution @takk/tokenforecast/attribution attribute, splitAt. You only need cost-change drivers across a dimension.
Drift @takk/tokenforecast/drift detectDrift. You only need change-point detection.
Scenario @takk/tokenforecast/scenario simulate, repriceEvents, detectPriceShifts. You only need what-if pricing and price-shift detection.
Alkaline @takk/tokenforecast/alkaline createMeterIngestor. You bridge in-memory @takk/alkaline token-meter readings.
Edge @takk/tokenforecast/edge The full core under a worker condition. You target an edge or worker runtime.
Command line

The same engine, from your terminal.

Export your cost events to a JSON array and run forecasts, attributions, and drift checks without writing code. Add --json to any command for a machine-readable result. Exit codes follow the sysexits convention: 0 success, 64 usage, 65 bad data, 66 unreadable input.

Forecast spend

npx @takk/tokenforecast forecast events.json --horizon 7 --level 0.9 --budget 500

# method:   holt-winters
# interval: 90%
# backtest: sMAPE 8.2%, MAPE 7.9%, MAE 1.4210 (14 held out)
#
# date                      mean      lower      upper
# 2026-06-20T00:00:00.000Z   52.3100    44.1200    60.5000
# ...
# budget:   within budget (61% of 500)

Attribute a cost change

npx @takk/tokenforecast attribute events.json --at 1750000000000 --by feature

# cost change across feature: +128.4500
#   chat                     +94.2000  (73%)
#   embeddings               +21.1500  (16%)
#   summarize                +13.1000  (10%)

Detect drift

npx @takk/tokenforecast drift events.json

# drift up detected at 2026-06-06T00:00:00.000Z (statistic 12.84)
Typed results

Every result is a plain, typed object.

No event bus, no agent, no vendor. Each function returns a serializable object you can log, store, assert on, or branch on with full TypeScript narrowing. A Forecast carries its own backtested error.

const result = forecaster.forecast({ horizon: 3, level: 0.9 });
// {
//   granularity: 'day',
//   method: 'holt-winters',
//   level: 0.9,
//   points: [
//     { at: 1750377600000, mean: 52.31, lower: 44.12, upper: 60.50 },
//     { at: 1750464000000, mean: 53.07, lower: 43.88, upper: 62.26 },
//     { at: 1750550400000, mean: 53.83, lower: 43.41, upper: 64.25 }
//   ],
//   backtest: { mape: 0.079, smape: 0.082, mae: 1.421, samples: 14 }
// }

A cost attribution

const change = forecaster.attribute(splitAtMs, 'model');
// {
//   dimension: 'model',
//   totalBefore: 210.40,
//   totalAfter: 338.85,
//   totalDelta: 128.45,
//   rows: [
//     { key: 'gpt-4o',      before: 120.0, after: 214.2, delta: 94.20, share: 0.733 },
//     { key: 'gpt-4o-mini', before: 60.40, after: 81.55, delta: 21.15, share: 0.165 },
//     { key: 'text-embed-3', before: 30.0, after: 43.10, delta: 13.10, share: 0.102 }
//   ]
// }

Errors are just as structured: every refusal is a TokenForecastError carrying a stable code (ERR_INVALID_INPUT, ERR_INSUFFICIENT_DATA, ERR_UNKNOWN_MODEL, ERR_NOT_FOUND). Branch on the code, never the message.

Compare

Token Forecast vs the alternatives.

The other tools in this space are good at what they do. Most are hosted platforms or dashboards; the contrast clarifies where an embeddable library sits.

Capability Token Forecast CloudZero Helicone Langfuse Hand-rolled
Distribution npm library SaaS / hosted proxy + SaaS SaaS / self-host your repo
Runtime hop in-process external network hop async ingest in-process
Predictive forecast with intervals yes, backtested yes analytics no varies
Agent-readable in-process yes dashboard dashboard dashboard varies
Bring-your-own price book yes managed managed managed varies
Runtime dependencies 0 n/a (hosted) n/a (hosted) n/a (hosted) varies
SaaS lock-in none yes optional optional none
License Apache-2.0 commercial Apache-2.0 MIT your call

The honest summary: pick CloudZero if you want a managed FinOps platform with procurement behind it. Pick Helicone or Langfuse if you primarily want observability dashboards. Pick Token Forecast when you want the forecast itself, as a zero-dependency library your code, or an agent, can read and act on in-process.

Honest limits

What Token Forecast will not pretend to do.

Every forecasting tool has limits; most hide them. Here are Token Forecast's, stated plainly, so a wide interval or a flagged shift reads as a signal, not a promise.

Limit Where it shows up What Token Forecast does about it
Cold-start is only as good as your prior A brand-new feature with almost no history. Blends your prior, never invents one; labels the method cold-start and widens the interval.
Price-shift can be confounded by token mix A change in input-vs-output token ratio within one model. Reports the effective-price move and documents the confound; treat it as a signal to investigate.
Attribution is descriptive, not causal Asking "what caused" a cost change. Decomposes recorded data to locate the driver; the causal claim is yours to make.
Seasonality needs history Fewer than about two full seasons of buckets. Falls back to a simpler method by backtest and widens the interval honestly.
Cost accuracy is the caller's The cost on each event. Never embeds a price table that would go stale; garbage cost in, garbage forecast out.
Buckets align to UTC A business whose day boundary is a local time zone. Totals stay correct; pre-shift timestamps if you need local-day seasonality.
Quality and validation

The receipts behind v1.0.0.

Tests & coverage

53 tests passing across 12 suites under Vitest 4. Coverage: 95.87% lines, 95.92% statements, 99.05% functions, 82.59% branches. Run pnpm test on a fresh clone to reproduce.

Type safety

TypeScript 6 in maximum strict mode (exactOptionalPropertyTypes, useUnknownInCatchVariables, noUncheckedIndexedAccess, noImplicitOverride, noImplicitReturns). Zero errors under tsc --noEmit.

Lint & format

Biome 2 clean across src and tests. publint clean. Exports map is dual ESM + CJS with separate .d.ts and .d.cts per subpath.

Deterministic by design

Every function is pure. Tests use fixed UTC time anchors and fixtures, no network and no wall-clock, so a forecast, an attribution, and a drift verdict reproduce byte-for-byte across machines and Node versions.

Dist smoke

scripts/smoke-dist.mjs builds the package and exercises the published artefact end-to-end, asserting the CLI exit codes (sysexits convention) and the cold-start path before any release.

Supply chain

Committed pnpm lockfile, supply-chain policy with minimum release age, SLSA provenance attestation on every published version. Verify with npm view @takk/tokenforecast@1.0.0 --json | jq .dist.attestations.

Roadmap

What is shipped, what is next, what is later.

Now (1.0)

Shipped in v1.0.0

  • Five methods, backtest-selected
  • Prediction intervals + cold-start prior
  • Attribution, drift, price-shift detection
  • Budget forecasts and what-if scenarios
  • CLI: forecast, attribute, drift
  • Alkaline bridge and edge entry
  • Dual ESM + CJS, zero deps, SLSA provenance
Next (1.1)

Targeted for 1.1

  • Multiplicative Holt-Winters option
  • Incremental fitting for streaming series
  • Additional drift detectors (CUSUM, ADWIN)
  • Interval-calibration report
  • Per-dimension forecasting helpers
Later

On the horizon

  • Quantile (probabilistic) forecasts
  • Causal-attribution experiments
  • More sibling-package bridges
  • Browser-targeted bundle
FAQ

Common questions.

Is Token Forecast production-ready at 1.0.0?

Yes. 53 tests across 12 suites pass under Vitest 4 with 95% line coverage; TypeScript 6 maximum strict mode is clean; Biome 2 lint is clean; publint is clean. Every published release carries SLSA provenance produced by GitHub Actions, and the dist artefact is exercised end-to-end by a smoke script, including the CLI exit codes and the cold-start path.

Is this machine learning?

No, and that is deliberate. The engine is classical statistics: exponential smoothing (Holt-Winters, Holt, SES) with learned seasonality, robust anomaly scoring, and a Page-Hinkley drift test. It is explainable, and every forecast ships the backtested error (MAPE and sMAPE) that earned it, so you can audit the choice instead of trusting a black box.

How is this different from CloudZero, Helicone, or Langfuse?

Those are hosted dashboards or observability platforms. Token Forecast is an embeddable, zero-dependency library and CLI that runs in your process, so an agent or service can read its own forecast and act on it, not just a human reading a chart. They are complementary: stream the same events to both.

Does this work in Cloudflare Workers, Vercel Edge, Bun, or Deno?

Yes. The whole engine is Node-free, so the @takk/tokenforecast/edge entry exposes the full core under a worker condition. It runs on any modern JavaScript runtime, no built-in fetch or filesystem required, because Token Forecast makes no network or disk calls.

Does Token Forecast hardcode provider prices?

No. You supply the cost on each event, so a forecast never goes stale against a bundled price table. The scenario engine re-costs what-if model swaps over a price book you pass at call time, and price-shift detection derives effective prices from your own recorded data.

How much history do I need before forecasts are useful?

Holt-Winters wants roughly two full seasons (about 14 daily buckets for weekly seasonality). With less, the backtest selects a simpler method and the interval widens honestly. For a brand-new feature with almost no data, pass a cold-start prior and get a wide-interval forecast from day one.

What does the prediction interval mean?

Each forecast point carries a lower and upper bound at your confidence level (default 0.9, a 90% band), derived from an inverse-normal quantile of the residual scale and clamped so the lower bound never falls below zero. A wider band means the model is less certain, not that it failed.

Can I trust the forecast number?

Trust the number as far as its backtest says. Every Forecast includes a backtest with MAPE, sMAPE, MAE, and the number of held-out samples from a rolling-origin evaluation. Read the error alongside the mean; a tight interval with low sMAPE is a confident forecast, a wide one is a flag to gather more data.

Can I forecast tokens or call count instead of cost?

Yes. Every bucket carries cost, tokens, and count, and the forecaster takes a metric option of 'cost', 'tokens', or 'count'. Forecast whichever signal you budget against.

How does cold-start avoid making numbers up?

It never invents a prior. You supply the expected per-bucket cost and your uncertainty; Token Forecast blends that with whatever thin history exists through a conjugate normal-mean update and widens the interval. If your prior is wrong, the forecast is wrong, which is why the method is labelled cold-start in the result.

How do I verify a published version's provenance?

Every release is published with npm publish --provenance. Check the attestations with npm view @takk/tokenforecast@<version> --json | jq .dist.attestations. The attestation links the tarball you installed to the GitHub Actions workflow that built it from a specific source commit.

What is the policy on breaking changes?

Strict SemVer 2.0.0, starting from 1.0.0. The binding stability surface is documented in SPEC.md section 5. Which method the engine auto-selects is not part of that surface; pin it with options.method if you need byte-stable output. Major bumps require a deprecation cycle; security fixes follow the disclosure flow in SECURITY.md.

Author

Built and maintained by David C Cavalcante.

David C Cavalcante

Founder, Takk Innovate Studio

Product Engineer, AI Engineer, ML Engineer, LLM Engineer, LLM Architect, AI Researcher. Builder of the @takk family of NPM packages for AI-native infrastructure.

Token Forecast is one package in a planned portfolio of NPM libraries targeting AI-native infrastructure for 2026 to 2030. Adjacent research by the author covers systemic intelligence frameworks (MAIC, HIM, NHE) published independently of this codebase, with research notes on PhilPapers and PhilArchive linked from the repository README.

If Token Forecast caught an overrun before the invoice for you, the most useful thing you can do is open a GitHub issue when you find a case the test suite missed. The runbook for releases, the threat model, and the contributor agreement all live in the repository.