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

# Usage and plan quotas

> What drain traffic is metered, what counts as billable, the per-tier daily allowances, and the usage route that reports them

Drain traffic is attributable: what was delivered, what was dropped, what your destination refused — per drain, per day, per organization.

<Info>
  **Metered and reported, not billed.** Every usage line comes back with `unpriced: true` today: the platform measures drain traffic and attributes it to your organization, and charges nothing for it. The line item exists so that the numbers behind any future price are visible before it exists, not after.
</Info>

Metering is switched on per deployment and is separate from delivery, so it can be armed or disarmed without interrupting your logs. Where it is off, the usage route answers with empty periods rather than an error.

## What is metered

One record per settled batch, and one per drop — never one per record.

| Event                                                                          | `deliveredRecords` | `rejectedRecords` | `droppedRecords` | Billable  |
| ------------------------------------------------------------------------------ | ------------------ | ----------------- | ---------------- | --------- |
| Batch accepted                                                                 | the batch          | 0                 | 0                | the batch |
| Batch accepted, N records refused                                              | the batch          | N                 | 0                | batch − N |
| Batch terminally refused                                                       | 0                  | the batch         | 0                | nothing   |
| Batch retried                                                                  | not metered        | —                 | —                | —         |
| Records dropped — quota, horizon, buffer, or unbuildable                       | 0                  | 0                 | the records      | nothing   |
| `heartbeat`, `verify`, `test`, and the in-band `dropped` / `truncated` reports | not metered        | —                 | —                | —         |

**Billable is `deliveredRecords − rejectedRecords`.** Nothing else. Drops and failures appear on the row so you can *see* the gap and reconcile it against your delivery rows, and they are excluded from every billable total.

A **retry is not metered**. Those records are not settled; they re-enter the pending pool and are metered when they eventually settle. Metering a retry would count the same records twice.

A heartbeat, a verification, and an in-band drop report are the platform talking about itself, so none of them is metered either.

<Note>
  **The billable figure is computed per batch and then summed — not as `Σdelivered − Σrejected`.** A terminally refused batch meters `delivered: 0, rejected: N`; on its own row that is zero, but subtracted from a total it would *credit* N against batches that were delivered successfully. One failed batch would quietly reduce what you are counted for on your successful ones.

  Bytes are pro-rated by each batch's own accepted fraction, for the same reason: there is no per-record byte count to subtract, so pro-rating per batch keeps the error inside that batch instead of spreading it across the month.
</Note>

## GET /admin/orgs/:orgId/usage/log-drains

Scope: `usage:read` — the same scope as the rest of the usage dashboard, and narrower than `logs:manage`. The response reports your own traffic and carries no drain configuration, no endpoint, and no credential.

<ParamField query="period" type="string">`YYYY-MM`. Defaults to the current UTC month.</ParamField>

**Response**

```json theme={null}
{
  "period": { "key": "2026-09", "startMs": 1788912000000, "endMs": 1791590400000 },
  "tier": "business",
  "totals": {
    "drainId": "all",
    "deliveredRecords": 12044918,
    "deliveredBytes": 8412009118,
    "droppedRecords": 4021,
    "rejectedRecords": 188,
    "billableRecords": 12044730,
    "billableBytes": 8411877902
  },
  "byDrain": [
    {
      "drainId": "drn_2b7f10d9ac4e83615702ffab",
      "deliveredRecords": 11902441,
      "deliveredBytes": 8301774110,
      "droppedRecords": 0,
      "rejectedRecords": 188,
      "billableRecords": 11902253,
      "billableBytes": 8301642894
    }
  ],
  "byDay": [
    {
      "ts": 1788912000000,
      "drainId": "drn_2b7f10d9ac4e83615702ffab",
      "deliveredRecords": 401288,
      "deliveredBytes": 280100418,
      "droppedRecords": 0,
      "rejectedRecords": 0,
      "billableRecords": 401288,
      "billableBytes": 280100418
    }
  ],
  "lineItem": {
    "lineItem": "log_drain_events",
    "tier": "business",
    "billableRecords": 12044730,
    "billableBytes": 8411877902,
    "includedEvents": 0,
    "includedBytes": 0,
    "overageEvents": 0,
    "overageBytes": 0,
    "eventsUsd": 0,
    "bytesUsd": 0,
    "usd": 0,
    "unpriced": true
  }
}
```

| Field      | Meaning                                                                                                         |
| ---------- | --------------------------------------------------------------------------------------------------------------- |
| `period`   | The UTC month, with its bounds in epoch milliseconds                                                            |
| `tier`     | The organization's drain tier for that period                                                                   |
| `totals`   | The organization's roll-up, with `drainId: "all"`                                                               |
| `byDrain`  | Per drain for the period, sorted by billable records, descending                                                |
| `byDay`    | The same numbers per UTC day per drain, for charting; ascending                                                 |
| `lineItem` | One `log_drain_events` line: the tier, the billable figures, the included allowance, the overage, and the money |

`usd` is `max(eventsUsd, bytesUsd)` — never the sum. The per-event and per-GiB readings are **alternative readings of the same traffic**, and adding them would count one delivery twice.

No monetary figure is ever written onto a usage record. The line is priced at **read** time from the current price card, which is why correcting a card fixes last month's report rather than only next month's.

`unpriced: true` means the price card is all zeroes — metered, not yet priced.

## Daily allowances

Each drain has a daily event and byte allowance from your tier:

| Tier       | Events per day | Bytes per day |
| ---------- | -------------- | ------------- |
| Team       | 1,000,000      | 1 GiB         |
| Business   | 10,000,000     | 10 GiB        |
| Enterprise | Unmetered      | Unmetered     |

Going over degrades the drain in steps rather than cutting it off:

| Usage | What happens                                          |
| ----- | ----------------------------------------------------- |
| 80%   | A [notice](/drains/notifications). Nothing is dropped |
| 100%  | `debug` records are dropped                           |
| 125%  | `info` records are dropped too                        |
| 150%  | The drain pauses, with reason `quota`                 |

`warn` and `error` records are the last to go: the ladder never drops them before it pauses the drain. Counters reset at 00:00 UTC.

<Note>
  **A read of a drain reports your plan's *live* limits, not the ones in force when the drain was created.** An organization that upgrades this morning is told its new ceiling straight away, on the same `quota` block, with its counters, `resetsAt` and `degradation` untouched. There is nothing to re-create and nothing to migrate.
</Note>

```bash theme={null}
lua drains status --json | jq '.drains[] | {name, quota}'
```

```json theme={null}
{
  "name": "Datadog prod",
  "quota": {
    "eventsPerDay": 10000000,
    "bytesPerDay": 10737418240,
    "usedEvents": 418223,
    "usedBytes": 289417216,
    "resetsAt": "2026-09-22T00:00:00.000Z",
    "degradation": "none"
  }
}
```

An organization on a negotiated allowance sees its own numbers here rather than its tier's defaults.

## Reconciling against your own destination

The usage numbers and the [delivery rows](/reference/rest/log-drains) for the same batch carry the **same** counts, so the comparison is an equality rather than a tolerance. Delivery rows are kept for 7 days, so only a recent window can be compared this way.

```bash theme={null}
# what the platform says it delivered, this month, per drain
curl -sS "https://api.heylua.ai/admin/orgs/<<YOUR_ORG_ID>>/usage/log-drains?period=2026-09" \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  | jq -r '.byDrain[] | [.drainId, .deliveredRecords, .rejectedRecords, .billableRecords] | @tsv'

# what the delivery rows say, for the last 7 days
lua drains deliveries drn_2b7f10d9ac4e83615702ffab --limit 100 --kind batch --json \
  | jq '[.deliveries[] | select(.ok) | .recordCount] | add'
```

A gap means metering was off for part of the window, or a process died between writing a delivery row and its usage record. It never means a record was delivered twice.

<Warning>
  **This is a read model, not a ledger.** It reports what the meter wrote. A window in which metering was off is a window with no records, and there is no backfill — delivery rows expire after 7 days, so only a recent gap can be reconstructed at all. Treat the numbers as reconciliation-grade rather than accounting-grade.
</Warning>

## See also

* [Delivery guarantees](/drains/delivery-guarantees#quota-degradation) — the ladder, and what a drop looks like
* [Drain notices](/drains/notifications) — who is told at 80%, and at 150%
* [Log drains REST](/reference/rest/log-drains) — the drain routes and the `quota` block on a read
* [`lua drains`](/reference/cli/drains) — `status --json` and its `quota` field
