Repository navigation
fix: gzip trace uploads at level 1 - #1129
Merged
Merged
Conversation
The upload thread spent ~70 ms of its ~78 ms per 2 MB episode in gzip at the default level 9, so it fell behind a fast producer and the upload queue dropped episodes. Level 1 is ~9x faster for ~13% more bytes on the wire. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mikasenghaas
requested review from
DamianB-BitFlipper,
JannikSt,
JohannesHa,
akirillo,
burnpiro,
cabrinha,
eexwhyzee,
kcoopermiller,
kennethnym,
mrmoxon and
willccbb
as code owners
October 29, 2026 22:16
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
hallerite
pushed a commit
to PrimeIntellect-ai/prime-rl
that referenced
this pull request
Nov 2, 2026
## Summary Part of the monitors stack: #4228 → #4316 → **#4317** → #4244. Stacked on #4316. - Adds `tests/unit/monitors/test_monitor_load.py`: one test, parametrized over monitor (file, prime, W&B) × episode count (10, 100, 1000). - Each episode is agentic and heavy: 100 turns, 100k tokens, numpy streams as the env-server wire delivers them (about 2 MB per upload). - Interleaved with 2000 metric rows of 200 keys. - The episodes share one trace object. Every monitor serializes each episode separately, so the load is the same at a fraction of the memory. - The test logs through `monitors.log` as the orchestrator does, under the orchestrator's `GarbageCollector` (no automatic full collections). An asyncio ticker measures how late the event loop wakes. - The test checks that everything logged arrives: - **File monitor:** every episode in the trace stream, and steps 1 to 2000 in `metrics.jsonl`. - **Prime monitor:** the real SDK run and uploader threads against fake Prime Traces and platform endpoints. The fake traces endpoint gzips like the real client. - **W&B monitor:** the real SDK in offline mode. W&B takes metrics only. - The test fails when a monitor stalls the loop: p99 lag of 50 ms or more, max lag of 250 ms or more, or one `log()` call of 250 ms or more. - `prime-1000` is an expected failure (strict). The SDK uploader gzips each episode at level 9, about 70 ms here, so 1000 episodes logged at once fill its queue. `log()` then waits for room for up to 5 s on the orchestrator's arrival path, and the SDK drops what stays queued. A TODO in the test tracks the fix; PrimeIntellect-ai/prime#1129 is the first part (gzip level 1). - The test is CPU-only, needs no network and is marked `slow`. CI's unit job runs it (it deselects only `gpu`). It takes about 110 s. ## Verification `pytest -s tests/unit/monitors/test_monitor_load.py` on the dev box, with main's `prime-traces` pin: 8 passed, 1 xfailed. | Monitor | Episodes | Loop lag p99 | Loop lag max | `log()` p99 | `log()` max | |---|---|---|---|---|---| | File | 10 / 100 / 1000 | 3.6 / 3.4 / 4.7 ms | 3.7 / 5.6 / 4.9 ms | 0.1 / 5.0 / 5.3 ms | 7.9 / 9.9 / 7.8 ms | | Prime | 10 / 100 | 5.2 / 7.9 ms | 6.0 / 10.5 ms | 0.4 / 0.4 ms | 10.1 / 15.4 ms | | Prime | 1000 | xfail: 7 of 1000 episodes dropped ("Upload queue full after 5.0s"), one `log()` call blocked 5 s | | | | | W&B (offline) | 10 / 100 / 1000 | 1.6 / 1.3 / 1.1 ms | 6.0 / 1.6 / 1.4 ms | 0.6 / 0.5 / 0.6 ms | 6.1 / 0.8 / 0.8 ms | Without the orchestrator's GC setup, a full collection pauses the loop for 220–260 ms in the 1000-episode cases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Test-only change with no production code paths modified; it exercises existing monitor integrations under load. > > **Overview** > Adds **`tests/unit/monitors/test_monitor_load.py`**, a slow unit test that drives **file**, **Prime**, and **W&B (offline)** monitors through **`monitors.log`** the way the orchestrator does—heavy agentic episodes (up to 1000 × 100 turns / ~100k tokens) interleaved with **2000** wide metric rows, under the orchestrator **`GarbageCollector`** fixture. > > For each monitor × episode count (**10 / 100 / 1000**), it asserts **complete delivery** (trace chunks / fake Prime endpoints / W&B metric steps) and **event-loop responsiveness** (p99 lag **< 50 ms**, max lag and single **`log()`** **< 250 ms**). **Prime @ 1000 episodes** is **`xfail` (strict)** documenting **`prime_runs`** upload-queue backpressure that can block **`log()`** for seconds and drop episodes. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit bb9dbad. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
kcoopermiller
approved these changes
Nov 2, 2026
kcoopermiller
left a comment
Member
There was a problem hiding this comment.
Approving. Correct on both clients, and the digest and limits stay over uncompressed bytes. On real long traces I measured about 5x faster gzip for about 20% more bytes, which is the right trade for hosted training.
Two follow-ups, not blockers:
- The prime-rl load test's fake hard-codes gzip level 9 and never calls the real client, so it can't see this change.
- Drops still need checking with a real 1000-episode burst against Prime Traces. The queue and the 5 s blocking put are unchanged.
This was referenced Nov 2, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GZIP_LEVELinprime_traces.core.client, used by the sync and async clients).prime_runsupload queue filled and dropped episodes after its 5 s put timeout.Verification
One agentic episode: 100 turns, 100k tokens, 2.17 MB upload body.
Uploader cost per episode (
TracesSink.writethrough a fake endpoint that gzips like the client): 78 ms before, 16 ms after.prime-rl monitor load test (PrimeIntellect-ai/prime-rl#4317), 1000 such episodes logged as fast as possible through
PrimeMonitor:uv run pytest tests/inpackages/prime-traces: 183 passed.🤖 Generated with Claude Code
Note
Low Risk
Transport-only gzip tuning with no change to content addressing or auth; slightly larger uploads in exchange for faster client-side compression.
Overview
Trace upload bodies are now gzipped at level 1 instead of Python’s default level 9, via a shared
GZIP_LEVELconstant inclient.pyused by both sync and asyncupload_batchpaths (still withmtime=0for reproducible retries).This targets upload throughput: compression was CPU-bound and could back up fast producers (e.g. upload queue timeouts and dropped episodes). Payload semantics are unchanged—idempotency and limits still apply to the uncompressed JSONL; only transport compression speed and wire size (~slightly larger) differ.
Reviewed by Cursor Bugbot for commit fce799d. Bugbot is set up for automated code reviews on this repo. Configure here.