> ## Documentation Index
> Fetch the complete documentation index at: https://docs.macropay.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Delta Time Strategy

> Meter wall-clock execution time and bill per millisecond of compute

When the thing your customer pays for *is time* — compute seconds, a rendering job, an agent's run duration — you need a clean way to measure how long an operation took and turn that number into a billable event. The Delta Time strategy does exactly that: start a timer, run your code, stop the timer, and the elapsed `deltaTime` is ingested to Macropay automatically.

Because Macropay is your Merchant of Record, those metered events flow straight into the meter → metered price pipeline. We invoice in the customer's currency, remit any applicable sales tax or VAT on your behalf, and stay the seller of record on the statement — you just emit the duration.

## What you'll need

* A meter that aggregates an event named `execution-time` (or whatever name you choose) into a metered price.
* A `MACROPAY_ACCESS_TOKEN` available to your server.
* The ingestion package installed.

```bash theme={null}
pnpm add @macropayments/ingestion
```

## Bring your own clock

Timing is only as good as the clock you read it from. Rather than lock you into one source, the strategy takes a **now-resolver** — a function returning the current time — so you can pick the precision your billing model requires:

| Resolver                        | Precision                  | Good for                           |
| ------------------------------- | -------------------------- | ---------------------------------- |
| `() => performance.now()`       | Sub-millisecond, monotonic | Per-request latency, short jobs    |
| `() => Number(hrtime.bigint())` | Nanosecond, monotonic      | High-resolution server-side timing |
| `() => Date.now()`              | Millisecond, wall-clock    | Long-running jobs, coarse metering |

<Tip>
  Prefer a **monotonic** source like `performance.now()` or `process.hrtime` for billing. Wall-clock time (`Date.now()`) can jump backward when the system clock is adjusted, producing a negative or inflated delta.
</Tip>

## Meter an operation end-to-end

The strategy wraps your now-resolver and hands back a `start()` function. Calling `start()` opens a timer and returns a `stop()` function; calling `stop()` closes it and ingests the measured `deltaTime`.

```typescript theme={null}
import { Ingestion } from "@macropayments/ingestion";
import { DeltaTimeStrategy } from "@macropayments/ingestion/strategies/DeltaTime";

// Pick the clock that matches your billing precision
const nowResolver = () => performance.now();
// const nowResolver = () => Number(hrtime.bigint());
// const nowResolver = () => Date.now();

// Wire up the Delta Time ingestion strategy once, at module scope
const deltaTimeIngestion = Ingestion({
  accessToken: process.env.MACROPAY_ACCESS_TOKEN,
})
  .strategy(new DeltaTimeStrategy(nowResolver))
  .ingest("execution-time");

export async function POST(request: Request) {
  try {
    // Attribute the timing to a customer so it lands on the right meter.
    // Returns the wrapped start-clock function.
    const start = deltaTimeIngestion.client({
      customerId: request.headers.get("X-Macropay-Customer-Id") ?? "",
    });

    // Open the timer
    const stop = start();

    // ...run the work you want to bill for, e.g. a video transcode
    await transcode(request);

    // Close the timer — { deltaTime } is ingested to Macropay automatically
    const delta = stop();

    return Response.json({ delta });
  } catch (error) {
    return Response.json({ error: error.message });
  }
}
```

<Note>
  Pass `customerId` when you build the client so each event is attributed to the right customer. The `X-Macropay-Customer-Id` header is just one convenient place to read it from — use whatever your app already has (a session, a JWT claim, a path param).
</Note>

## What gets ingested

When `stop()` fires, the strategy posts a single event. `deltaTime` is the elapsed value in whatever unit your now-resolver returns:

```json theme={null}
{
  "customerId": "123",
  "name": "execution-time",
  "metadata": {
    "deltaTime": 1000
  }
}
```

Your meter aggregates `deltaTime` across events and applies the metered price — so "$0.002 per second of transcoding" or "$0.05 per minute of agent runtime" is just a meter definition, not custom billing code.

## Billing agents by runtime

Delta Time pairs naturally with agent billing. If you charge for an autonomous agent by how long it works, wrap the agent's execution in `start()` / `stop()` and attribute the duration to the agent's customer. The elapsed time becomes an **activity signal** you can meter directly, while [value receipts](/features/usage-based-billing/introduction) certify the outcome — time saved or revenue generated — on top of raw runtime.

## Related strategies

* [Strategy introduction](/features/usage-based-billing/ingestion-strategies/ingestion-strategy) — when to reach for each one
* [LLM Strategy](/features/usage-based-billing/ingestion-strategies/llm-strategy) — meter prompt and completion tokens
* [Stream Strategy](/features/usage-based-billing/ingestion-strategies/stream-strategy) — meter bytes through a stream
* [S3 Strategy](/features/usage-based-billing/ingestion-strategies/s3-strategy) — meter file uploads
