Docs
Billing

Usage Metering

Explains how MarkDocket records usage events through a transactional outbox, the retry and dead-letter behavior of the drain loop, and the distinction between product usage metering and direct COGS metering.

MarkDocket records every billable action through a metering outbox — a database table that acts as a durable queue between your activity and the billing system. This design means usage events are never lost due to a process restart or a temporary outage in the billing pipeline, and gives you a consistent, auditable record of everything that has been charged.

How the Outbox Works

Whenever you (or an automated workflow, agent turn, or API call) perform a billable action, MarkDocket writes a usage event to an internal outbox table in the same database transaction as the action itself. Nothing is sent to the billing system inline — the event is persisted first, then delivered asynchronously.

A periodic drain loop processes the outbox:

  1. Claim: Rows are claimed with a row-level lock so that multiple drain iterations never send the same event twice, even if the API server is running in multiple instances.
  2. Deliver: Each claimed event is sent to the billing system. On success the row is marked as delivered.
  3. Retry with backoff: If delivery fails, the event is retried with exponential backoff. Retries are capped at a maximum of 12 attempts, with the delay between attempts capped at 5 minutes.
  4. Dead-letter: Events that exhaust all retry attempts are marked permanently failed (dead-lettered) rather than silently dropped.
  5. Prune: Terminal rows — both successfully delivered and dead-lettered — are swept and pruned on a 6-hour cycle to keep the outbox table compact.

This approach provides exactly-once delivery semantics tied to your application's transaction boundaries. A process crash between a billable action and its delivery attempt does not lose the event; the outbox entry persists until the next drain cycle picks it up.

Operator visibility

The outbox is backed by a standard Postgres table, so it is queryable through normal database tooling. Delivered, pending, and dead-lettered events are distinguishable by their row state.

Two Types of Usage Events

MarkDocket emits two distinct categories of metering event. Keeping them separate prevents double-counting in a platform where multiple services can participate in a single user action.

Product Usage Events

Product usage events record what you did — the feature you used, the unit being counted, and the quantity consumed. They carry no provider-level cost information.

Examples of what product usage events track:

  • An agent turn being completed
  • A trademark search being run
  • A due-diligence report being generated
  • An automation step being executed

Product usage events are emitted for all completed actions, including those where MarkDocket delegated work to an internal worker service on your behalf. The platform records the product-level outcome once, regardless of how many internal services were involved.

Direct COGS Events

COGS events (Cost of Goods Sold) record direct AI provider costs incurred by MarkDocket on your behalf — specifically, the provider, the operation type, the model, and whether the call used a platform-managed key or your own key (BYOK).

COGS events are emitted only for LLM calls that the MarkDocket API server makes directly. Worker services that independently call AI providers emit their own COGS events. The API server is explicitly prohibited from emitting a COGS event for work it has delegated to a sibling worker — doing so would count the same provider cost twice.

This separation is enforced through two distinct function signatures in the metering layer, not through application-level conditional logic, so the boundary cannot be accidentally bypassed.

BYOK and COGS metering

When you supply your own AI provider key (BYOK) for automation agent nodes, MarkDocket routes those LLM calls through your key. In that case, the provider cost is yours directly and MarkDocket does not emit a COGS event for those calls — only product usage events are recorded for BYOK-executed actions.

Why This Matters for Your Bill

Because the two event types are separate, your usage summary reflects:

  • What you used (features, actions, units) — always tracked regardless of how work was fulfilled internally.
  • What MarkDocket spent on your behalf in direct AI provider costs — tracked only once, at the service that made the call, never double-counted.

This means your bill is accurate even for complex workflows where an agent turn triggers multiple internal services, or where an automation run mixes platform AI calls with BYOK calls.

Retry Behavior Reference

ParameterValue
Maximum delivery attempts12
Backoff strategyExponential
Maximum backoff interval5 minutes
Dead-letter afterAll retries exhausted
Prune cycle (terminal rows)Every 6 hours

Relation to Billing Blocks

The metering outbox records usage after an action completes. Before a billable action can start — particularly for agent turns — MarkDocket creates a billing reservation as part of the turn authorization step. If your account cannot support the action, a billing block is returned before any work begins and no outbox entry is created.

See the Billing Block Envelope page for details on how billing blocks surface in the UI, the API, the CLI, and automation workflows.

On this page