PHPackages                             ykachala/meter - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. ykachala/meter

ActiveLibrary[Payment Processing](/categories/payments)

ykachala/meter
==============

Token accounting, multi-provider cost calculation, and budget guardrails for PHP AI apps. Know what every LLM call costs and stop runaway spend before it happens.

00PHP

Since Jun 2Pushed 1mo agoCompare

[ Source](https://github.com/ykachala/meter)[ Packagist](https://packagist.org/packages/ykachala/meter)[ RSS](/packages/ykachala-meter/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

Ykachala Meter
==============

[](#ykachala-meter)

> Token accounting, multi-provider cost calculation, and **budget guardrails** for PHP AI apps. Measure what every LLM call costs, attribute it to a user/team/feature, and enforce spend caps *before* the request goes out.

[![PHP Version](https://camo.githubusercontent.com/5a2eb3f6217f798b7ca58d59764e8fd3d779752c0cef2b8634034d9e7e4ba92d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e332d373737626234)](https://www.php.net/)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](LICENSE)

---

Why this exists (the 2026 gap)
------------------------------

[](#why-this-exists-the-2026-gap)

AI features in production have one universal failure mode: **a surprise invoice**. A single buggy loop, a jailbroken agent, or a viral launch can burn thousands of dollars in tokens overnight.

The Python ecosystem solved this with **LiteLLM** (virtual keys, per-key budgets, cost tracking) and SaaS like **Langfuse**. PHP teams in 2026 have *observability* (Langfuse has a PHP-friendly tracing path) but **no native, in-process metering layer** that can also **refuse a call** when a budget is blown. Observability tells you what you spent *yesterday*; Ykachala Meter stops you spending it *today*.

What it does
------------

[](#what-it-does)

- **Token estimation** — pre-flight token counts per provider so you can budget before sending.
- **Cost calculation** — a versioned, dated `PriceBook` for OpenAI, Anthropic, Google, Mistral, and custom models (input/output/cached-input/reasoning tiers).
- **Usage recording** — every call recorded with model, tokens, cost, latency, and arbitrary tags (`user_id`, `team`, `feature`).
- **Budgets** — hard and soft caps scoped to any tag (per user, per team, per day/month). Soft caps fire an event; hard caps throw before the request leaves.
- **Exporters** — roll usage up to Prometheus, OpenTelemetry, or a plain SQL table.

Install
-------

[](#install)

```
composer require ykachala/meter
```

Quick start
-----------

[](#quick-start)

```
use Ykachala\Meter\Meter;
use Ykachala\Meter\PriceBook;
use Ykachala\Meter\Budget\Budget;

$meter = new Meter(
    prices: PriceBook::default(),            // dated, versioned price tables
    store:  new Psr16UsageStore($cache),
);

// 1. Enforce a budget BEFORE the call
$meter->budget(Budget::monthly('team:acme', usd: 500.00));

$estimate = $meter->estimate('claude-opus-4-8', $messages);
$meter->assertWithinBudget('team:acme', $estimate);   // throws BudgetExceeded if over

// 2. Record actual usage AFTER the call
$usage = $meter->record(
    model: 'claude-opus-4-8',
    inputTokens: $response->usage->input,
    outputTokens: $response->usage->output,
    tags: ['team' => 'acme', 'user' => $userId, 'feature' => 'support-bot'],
);

echo $usage->cost->format();      // "$0.0241"
echo $meter->spent('team:acme')->format();  // running total this period
```

Budgets
-------

[](#budgets)

```
$meter->budget(Budget::daily('user:'.$userId, usd: 2.00, soft: 1.50));

$meter->on(BudgetSoftLimitReached::class, function ($e) {
    Notification::send($e->scope, new ApproachingLimit($e->spent, $e->limit));
});
// Hard limit throws BudgetExceeded — catch it and degrade gracefully (smaller model, queue, deny).
```

Wrap any client
---------------

[](#wrap-any-client)

Meter is a measurement layer, not a client. Wrap whatever you already use:

```
$response = $meter->wrap(
    fn () => $prism->text()->using('anthropic', 'claude-opus-4-8')->generate(),
    tags: ['feature' => 'summarizer'],
);
// usage auto-recorded from the response; budgets enforced around the closure
```

Architecture
------------

[](#architecture)

```
src/
├── Meter.php             # facade: estimate / record / wrap / budget / spent
├── PriceBook.php         # dated price tables, per-model, per-tier
├── Money.php             # integer-cents money value object
├── Usage.php             # one recorded call (tokens, cost, latency, tags)
├── Budget/               # Budget definitions + enforcement + events
├── Store/                # PSR-16, SQL, in-memory usage stores
└── Export/               # Prometheus / OpenTelemetry / SQL exporters

```

Roadmap
-------

[](#roadmap)

- Money + Usage value objects, integer-cents arithmetic
- PriceBook with dated tables (input/output/cached/reasoning tiers)
- Token estimators per provider family
- Usage stores (in-memory, PSR-16, SQL)
- Budget definitions + soft/hard enforcement + events
- Prometheus &amp; OpenTelemetry exporters

See [`CLAUDE.md`](CLAUDE.md) for the full phase plan and conventions.

License
-------

[](#license)

MIT

###  Health Score

19

—

LowBetter than 9% of packages

Maintenance59

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/5c5892a06b5cc3a1f6adaa3fa3d0cb5e9f77c6fc613425df614e2c4778b2e0a7?d=identicon)[joel767443](/maintainers/joel767443)

---

Top Contributors

[![ykachala](https://avatars.githubusercontent.com/u/985991?v=4)](https://github.com/ykachala "ykachala (8 commits)")

---

Tags

aianthropicbillingbudgetcostgeminillmobservabilityopenaitokensusage

### Embed Badge

![Health badge](/badges/ykachala-meter/health.svg)

```
[![Health](https://phpackages.com/badges/ykachala-meter/health.svg)](https://phpackages.com/packages/ykachala-meter)
```

###  Alternatives

[pagseguro/php

Biblioteca de integração com o PagSeguro

23260.3k6](/packages/pagseguro-php)[dinkbit/conekta-cashier

Dinkbit Cashier nos da una interface para cobrar subscripciones con Conketa en Laravel.

365.4k](/packages/dinkbit-conekta-cashier)[msilabs/bkash

bKash Payment Gateway API for Laravel Framework.

181.4k](/packages/msilabs-bkash)[binkode/laravel-paystack

A description for laravel-paystack.

112.1k](/packages/binkode-laravel-paystack)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
