Skip to content

Commit a02a4c9

Browse files
committed
docs: use real quota tags; a billing limit is a 402
Capture never sends billing_limit_exceeded or billing as a per-event tag. Product quotas drop single events in a 2xx with tags such as llm_events_over_quota; a request over the billing limit gets a 402 with no per-event results.
1 parent 6537741 commit a02a4c9

3 files changed

Lines changed: 20 additions & 15 deletions

File tree

‎docs/migration-7.x-to-8.0.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,16 @@ Posthog("<api_key>", host="https://us.i.posthog.com", debug=True)
5757
## Errors and `on_error`
5858

5959
Capture v1 returns a result for every event, even when the request succeeds.
60-
An event can be dropped, for example by billing limits or quotas, inside a 2xx response.
60+
An event can be dropped inside a 2xx response, for example when it is over a product quota.
6161
8.0 reports those events as failures.
62+
When the whole request is over the billing limit, capture returns a `402` with no per-event results instead.
6263

6364
- Every capture failure is a `CaptureError`. It has these fields:
6465
- `status`: the HTTP status, or `0` when the request never got a response
6566
- `endpoint`, `request_id` and `attempts`
6667
- `drops` and `retry_exhausted`: the uuids that were dropped or ran out of retries
6768
- `event_results`: a `CaptureEventResult(result, details)` for each uuid, from `posthog.capture_send`
68-
- `verdict_summary()`: counts such as `drop/billing=1, retry/not_persisted=1`
69+
- `verdict_summary()`: counts such as `drop/llm_events_over_quota=1, retry/not_persisted=1`
6970
- `on_error(error, batch)` receives every failure, including in `sync_mode` and from `AsyncPosthog.capture_immediate`.
7071
- Without `on_error`, the SDK logs one line per failed batch, for example `2 event(s) not persisted by /i/v1/analytics/events: ...`. The line never contains event content or the server's response text.
7172
- In `sync_mode`, a failed `capture()` calls `on_error` and returns `None`. With `debug=True` it calls `on_error` and then re-raises the error.

‎posthog/capture_send.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class CaptureEventResult:
9191
9292
``result`` is ``ok``, ``warning``, ``drop`` or ``retry``, or a value newer
9393
than this SDK, which counts as success. ``details`` is the server's reason
94-
tag, such as ``billing_limit_exceeded``.
94+
tag, such as ``llm_events_over_quota``.
9595
"""
9696

9797
result: Optional[str]
@@ -156,7 +156,7 @@ def __init__(
156156

157157
def verdict_summary(self) -> str:
158158
"""Count the undelivered events by verdict and reason, for example
159-
``drop/billing_limit_exceeded=2, retry/not_persisted=1``.
159+
``drop/llm_events_over_quota=2, retry/not_persisted=1``.
160160
161161
Counts the events in ``drops`` and ``retry_exhausted``: events the
162162
server dropped, and events still pending retry after the last 2xx

‎posthog/test/test_capture_send.py‎

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,15 @@ def test_drop_accumulated_across_attempts_surfaces_on_later_success(self) -> Non
366366
stub, exc = self._run_expecting_error(
367367
batch,
368368
[
369-
_results_response({"u-drop": ("drop", "billing"), "u-retry": "retry"}),
369+
_results_response(
370+
{"u-drop": ("drop", "llm_events_over_quota"), "u-retry": "retry"}
371+
),
370372
_results_response({"u-retry": "ok"}),
371373
],
372374
)
373375
self.assertEqual(len(stub.calls), 2)
374376
self.assertEqual(stub.calls[1]["uuids"], ["u-retry"]) # only retry resent
375-
self.assertEqual(exc.drops, [("u-drop", "billing")])
377+
self.assertEqual(exc.drops, [("u-drop", "llm_events_over_quota")])
376378
self.assertEqual(exc.retry_exhausted, [])
377379

378380
def test_retry_exhausted_raises_with_uuids(self) -> None:
@@ -394,7 +396,7 @@ def test_retry_exhausted_carries_earlier_drops(self) -> None:
394396
_results_response(
395397
{
396398
"u-ok": "ok",
397-
"u-drop": ("drop", "billing"),
399+
"u-drop": ("drop", "llm_events_over_quota"),
398400
"u-retry": "retry",
399401
}
400402
),
@@ -405,16 +407,18 @@ def test_retry_exhausted_carries_earlier_drops(self) -> None:
405407
self.assertEqual(len(stub.calls), 2)
406408
self.assertEqual(exc.endpoint, _CAPTURE_V1_PATH)
407409
self.assertEqual(exc.retry_exhausted, ["u-retry"])
408-
self.assertEqual(exc.drops, [("u-drop", "billing")])
410+
self.assertEqual(exc.drops, [("u-drop", "llm_events_over_quota")])
409411
self.assertEqual(
410412
exc.event_results,
411413
{
412414
"u-ok": CaptureEventResult("ok"),
413-
"u-drop": CaptureEventResult("drop", "billing"),
415+
"u-drop": CaptureEventResult("drop", "llm_events_over_quota"),
414416
"u-retry": CaptureEventResult("retry", "not_persisted"),
415417
},
416418
)
417-
self.assertEqual(exc.verdict_summary(), "drop/billing=1, retry/not_persisted=1")
419+
self.assertEqual(
420+
exc.verdict_summary(), "drop/llm_events_over_quota=1, retry/not_persisted=1"
421+
)
418422

419423
@parameterized.expand(
420424
[
@@ -432,11 +436,11 @@ def test_results_match_non_canonical_uuid(self, _name, sent_uuid) -> None:
432436
[_msg(sent_uuid)],
433437
[
434438
_results_response({canonical: "retry"}),
435-
_results_response({canonical: ("drop", "billing")}),
439+
_results_response({canonical: ("drop", "llm_events_over_quota")}),
436440
],
437441
)
438442
self.assertEqual(len(stub.calls), 2)
439-
self.assertEqual(exc.drops, [(canonical, "billing")])
443+
self.assertEqual(exc.drops, [(canonical, "llm_events_over_quota")])
440444

441445
def test_malformed_2xx_is_terminal(self) -> None:
442446
stub, exc = self._run_expecting_error(
@@ -536,17 +540,17 @@ class TestCaptureLossMessage(unittest.TestCase):
536540
200,
537541
"2 event(s) not delivered",
538542
endpoint=_CAPTURE_V1_PATH,
539-
drops=[("u-drop", "billing")],
543+
drops=[("u-drop", "llm_events_over_quota")],
540544
retry_exhausted=["u-retry"],
541545
event_results={
542546
"u-ok": CaptureEventResult("ok"),
543-
"u-drop": CaptureEventResult("drop", "billing"),
547+
"u-drop": CaptureEventResult("drop", "llm_events_over_quota"),
544548
"u-retry": CaptureEventResult("retry", "not_persisted"),
545549
},
546550
),
547551
3,
548552
"2 event(s) not persisted by /i/v1/analytics/events: 1 dropped, "
549-
"1 out of retries (drop/billing=1, retry/not_persisted=1)",
553+
"1 out of retries (drop/llm_events_over_quota=1, retry/not_persisted=1)",
550554
),
551555
(
552556
"request_failure_after_partial_success",

0 commit comments

Comments
 (0)