Agent Wranglers

USG-1Required

Give every usage event a key and count it once

Give each usage event a key made from the work it bills, such as the request ID. Store it under a unique constraint, so a retry never bills twice.

How to do it

Usage events are sent from retries, queues and crash recovery, so the same event arrives more than once. Build the key from facts that stay the same on a retry, such as the customer, the meter and the request ID. Never use a random value made at send time. Insert with "on conflict do nothing", so a repeat is a quiet no-op. Pass the same key to the billing provider. Providers often keep keys for a short window only, such as 24 hours, so your own table is the lasting guard. This is the same idea as Create each charge with an idempotency key and Make writes safe to repeat.

Examples

SQL example

CREATE TABLE usage_events (
  event_key   text PRIMARY KEY,
  customer_id text NOT NULL,
  meter       text NOT NULL,
  quantity    bigint NOT NULL CHECK (quantity >= 0),
  occurred_at timestamptz NOT NULL,
  received_at timestamptz NOT NULL DEFAULT now()
);

JavaScript example

export async function recordUsage(db, { customerId, meter, requestId, quantity, occurredAt }) {
  const eventKey = `${customerId}:${meter}:${requestId}`
  await db.query(
    `INSERT INTO usage_events (event_key, customer_id, meter, quantity, occurred_at)
     VALUES ($1, $2, $3, $4, $5) ON CONFLICT (event_key) DO NOTHING`,
    [eventKey, customerId, meter, quantity, occurredAt],
  )
}

Python example

def record_usage(db, customer_id: str, meter: str, request_id: str, quantity: int, occurred_at) -> None:
    event_key = f"{customer_id}:{meter}:{request_id}"
    db.execute(
        """INSERT INTO usage_events (event_key, customer_id, meter, quantity, occurred_at)
           VALUES (%s, %s, %s, %s, %s) ON CONFLICT (event_key) DO NOTHING""",
        (event_key, customer_id, meter, quantity, occurred_at),
    )

How to check

A test sends the same usage event three times, including once after a simulated crash. The usage table holds one row, and the period total counts it once.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/usage-billing/metering/idempotent-usage-events">Agent Wranglers usage-based billing playbook</a>. In code you write, add a comment next to it with the same link.