Skip to content

fix(scoring): bound score queue and batch payloads - #109

Merged
kxzk merged 5 commits into
feature/aai-388-flush-pending-spans-and-scores-at-process-exitfrom
feature/aai-390-fixscoring-bound-the-score-queue-and-cap-batch-payload-size
Aug 17, 2026
Merged

fix(scoring): bound score queue and batch payloads#109
kxzk merged 5 commits into
feature/aai-388-flush-pending-spans-and-scores-at-process-exitfrom
feature/aai-390-fixscoring-bound-the-score-queue-and-cap-batch-payload-size

Conversation

@kxzk

@kxzk kxzk commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

TL;DR

Asynchronous score batching now bounds memory use and limits multi-score request size.

Why

An ingestion outage could grow the score queue without a limit. Large flushes could also exceed the ingestion request limit.

Checklist

  • Has label
  • Has linked issue
  • Tests added for new behavior
  • Docs updated (if user-facing)

Closes #

Note

Kade's words:

Summary

Asynchronous score batching now keeps at most 100,000 pending scores by default. Applications can set score_queue_capacity. A full queue logs an error and drops the new asynchronous score without waiting for capacity. Synchronous score creation stays unchanged.

Flushes split before a multi-score JSON payload exceeds 2.5 MB. Delivered batches leave the queue. A failed batch and all later scores stay queued in their original order. This design keeps retry memory bounded.

Change diagram

flowchart TD
    accTitle: Bounded asynchronous score delivery
    accDescr: New scores enter a bounded queue. Flushes send size-limited batches and retain failed work in order.
    C["Create asynchronous score"] --> Q{"Queue has capacity"}
    Q -->|"No"| D["Log error and drop new score"]
    Q -->|"Yes"| A["Append score"]
    A --> B["Build payload below 2.5 MB"]
    B --> S{"Batch delivery succeeds"}
    S -->|"Yes"| R["Remove delivered prefix"]
    S -->|"No"| K["Keep failed batch in order"]
Loading

Verification

I ran the complete RSpec suite locally. All 1,578 examples passed. Line coverage was 97.33%.

I ran RuboCop against 98 files. RuboCop reported no offenses.

I ran a live Ruby SDK probe with a forced small payload limit. The SDK sent six accepted scores in six separate ingestion requests for trace b30020337050ed408b8f27469c4b4d2c. The Langfuse CLI read back the trace and all six score names.

I did not send a production-sized 2.5 MB payload to Langfuse. Unit tests validate exact JSON byte accounting at the split boundary. I did not preview the rendered Mermaid diagram in GitHub. I reviewed the Mermaid source and syntax locally.


Note

Medium Risk
Changes async score delivery, drop-on-full, and retry/discard semantics—scores can be lost under overload or permanent API rejection, though behavior is documented and heavily tested.

Overview
Asynchronous score batching is now memory-bounded and safer under API failures. Apps can set score_queue_capacity (default 100,000); when the queue is full the SDK logs and drops only the new async score—no blocking. Sync create_score! is unchanged.

Flush behavior replaces draining the whole unbounded queue with ordered prefix delivery: multi-score requests are split before ~2.5 MB JSON; successful prefixes are removed; retryable failures (429/5xx, network, auth) leave the failed batch at the front; non-retryable batch errors drop that batch and continue. Score bodies are JSON-snapshotted at enqueue so caller mutation cannot corrupt pending events.

Ingestion batch failures now raise BatchDeliveryError with a retryable? flag instead of generic ApiError where appropriate.

Reviewed by Cursor Bugbot for commit a767bbb. Bugbot is set up for automated code reviews on this repo. Configure here.

@kxzk kxzk added the bug Something isn't working label Aug 17, 2026
@linear-code

linear-code Bot commented Aug 17, 2026

Copy link
Copy Markdown

AAI-390

@kxzk
kxzk force-pushed the feature/aai-390-fixscoring-bound-the-score-queue-and-cap-batch-payload-size branch from 42795e9 to 238dc7e Compare August 17, 2026 17:53
@kxzk
kxzk changed the base branch from main to feature/aai-388-flush-pending-spans-and-scores-at-process-exit August 17, 2026 17:53
@kxzk kxzk closed this Aug 17, 2026
@kxzk kxzk reopened this Aug 17, 2026
Comment thread lib/langfuse/score_client.rb
@kxzk
kxzk force-pushed the feature/aai-390-fixscoring-bound-the-score-queue-and-cap-batch-payload-size branch from 238dc7e to 66c7d9c Compare August 17, 2026 18:29
@kxzk
kxzk changed the base branch from feature/aai-388-flush-pending-spans-and-scores-at-process-exit to main August 17, 2026 18:33
@kxzk kxzk closed this Aug 17, 2026
@kxzk kxzk reopened this Aug 17, 2026
@kxzk
kxzk changed the base branch from main to feature/aai-388-flush-pending-spans-and-scores-at-process-exit August 17, 2026 18:34
@kxzk kxzk closed this Aug 17, 2026
@kxzk kxzk reopened this Aug 17, 2026
@kxzk

kxzk commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

cursor review verbose=true

@cursor

cursor Bot commented Aug 17, 2026

Copy link
Copy Markdown

Bugbot request id: serverGenReqId_8f9c9ada-14fb-4aec-8105-c2224c85c660

@cursor

cursor Bot commented Aug 17, 2026

Copy link
Copy Markdown

Bugbot rules debug

No rules were used for this review.

https://cursor.com/docs/bugbot#team-rules

Bugbot request id: serverGenReqId_8f9c9ada-14fb-4aec-8105-c2224c85c660

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 66c7d9c. Configure here.

Comment thread lib/langfuse/score_client.rb
@kxzk
kxzk changed the base branch from feature/aai-388-flush-pending-spans-and-scores-at-process-exit to main August 17, 2026 19:05
@kxzk kxzk closed this Aug 17, 2026
@kxzk kxzk reopened this Aug 17, 2026
@kxzk
kxzk changed the base branch from main to feature/aai-388-flush-pending-spans-and-scores-at-process-exit August 17, 2026 19:06
@kxzk
kxzk merged commit 6b6992c into main Aug 17, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant