---
title: "An extension's own usage"
manual: "LLM Foundation"
version: "0.43"
permalink: "https://docs.typo3.org/permalink/netresearch/nr-llm:api-extension-usage@0.43"
source: "Api/ExtensionUsage.rst"
rendered: "2026-11-04T13:45:29+00:00"
---

# An extension's own usage {#api-extension-usage}

`ExtensionUsageReaderInterface` reads what one calling extension spent
and how often each of its operations ran and failed ([ADR-248](https://docs.typo3.org/permalink/netresearch/nr-llm:adr-248@0.43)).
The extension is the name it passes to `withCallerSource()`.

**Reading the usage of one extension**

```php
use Netresearch\NrLlm\Service\Usage\ExtensionUsageReaderInterface;

final readonly class MyUsageReader
{
    public function __construct(
        private ExtensionUsageReaderInterface $usage,
    ) {}

    public function lastThirtyDays(?int $onlyThisUser): array
    {
        $to   = new \DateTimeImmutable();
        // Midnight, so totals and operation counts cover the same days.
        $from = $to->modify('-29 days')->setTime(0, 0);

        return [
            'totals'     => $this->usage->totals('my_extension', $from, $to, $onlyThisUser),
            'operations' => $this->usage->operations('my_extension', $from, $to, $onlyThisUser),
            'coverage'   => $this->usage->coverage(),
        ];
    }
}
```

-   **`totals()`**

    `ExtensionUsageTotals` with `$estimatedCost` (US dollars, the
    recorded estimate), `$requests` and `$tokens`, from the daily
    usage aggregate. These are the figures the Analytics module shows per
    extension. The aggregate counts whole days, so the day `$from` falls
    on is included entirely. A request is what the usage tracker counts as
    one, so `$requests` need not equal the calls `operations()`
    counts.

-   **`operations()`**

    One `OperationUsage` per operation name, most calls first:
    `$operation`, `$calls`, `$failedCalls` and
    `$lastCallAt` (Unix time). Read from the per-call telemetry.

-   **`coverage()`**

    `TelemetryCoverage`: `$enabled` (the `telemetry.enabled`
    setting), `$retentionDays` (after which the purge command deletes
    rows) and `$oldestCallAt`, the oldest stored call or `null`.
    Operation counts for a period that starts before it are incomplete. It is a
    lower bound: a time while telemetry was switched off leaves a gap after it
    that the oldest call cannot show.

Pass a backend user uid to `totals()` and `operations()` to narrow
them to that user; `coverage()` always describes the whole installation.
Without a uid the figures cover the whole installation; show them only to
someone allowed to see them. Names are matched as stored: the first 64
characters of the extension and of the operation.
