WIP: feat(performance): chunked trace buffer parser for large recordings - #2721
Draft
jackfranklin wants to merge 3 commits into
Draft
WIP: feat(performance): chunked trace buffer parser for large recordings#2721jackfranklin wants to merge 3 commits into
jackfranklin wants to merge 3 commits into
Conversation
When performance traces exceed ~512 MB, decoding the full recording buffer into a single string throws a V8 RangeError due to the maximum string length limit (2^29 - 24 characters). This introduces a byte-level scanner that identifies JSON event boundaries directly on the Uint8Array using brace-depth and string-escape tracking. Events are sliced and parsed in bounded batches with native JSON.parse, ensuring intermediate strings remain well under V8 string allocation limits.
When performance traces exceed ~512 MB, decoding the full recording buffer into a single string throws a V8 RangeError due to the maximum string length limit (2^29 - 24 characters). This integrates the chunked trace buffer scanner into parseRawTraceBuffer, parsing events in bounded batches directly from the raw byte buffer so traces of any size supported by the buffer limit can be parsed by the trace engine without string allocation limits.
…tation Avoids V8 call stack size exhaustion on large batches by pushing events iteratively rather than spreading them as function arguments. Enforces strict EOF and structural token validation to prevent silent truncation on malformed buffers. Extracts a reusable string scanner to prevent delimiter drift across keys and values. Integrates embedded trace file metadata with caller throttling options, and documents state machine UTF-8 safety invariants and public API contracts.
Contributor
Author
|
The buffer limit in Chrome Tracing does not align with the final JSON output, because it limits the size of the binary protobuf that is captured. So I also think separately we might want to consider reducing the limit from 1.2gb. |
Contributor
Author
|
Please note also this PR is a WIP and is not fully ready for code review, sharing to get early thoughts on if we want to pursue it. |
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.
Note
This PR is marked as WIP (Work in Progress) / Draft to gather feedback and extra opinions on the streaming / chunked parsing strategy for large performance traces.
Problem Statement
When recording performance traces on busy sites or over long recording durations, the resulting trace buffer often exceeds 512 MB (and can reach 1 GB+).
Currently,$2^{29} - 24$ characters (~512 MB). Any trace exceeding ~512 MB throws a fatal error:
parseRawTraceBufferdecodes the entire raw buffer into a single string vianew TextDecoder().decode(buffer)and parses it withJSON.parse(asString). In V8 (64-bit), strings are strictly limited toThis prevents the MCP server from parsing and analyzing large traces even when sufficient heap memory is available.
Proposed Solution: Chunked Trace Buffer Scanner
This change introduces
ChunkedTraceParser.tsto extract trace events directly from the raw binary buffer in bounded batches without materializing the full trace JSON into a single string:Byte-Level Delimiter & Escape Scanning:
Uint8Arraydirectly using ASCII byte codes (0x7B{,0x7D},0x22",0x5C\).[ {...}, ... ]) and top-level object envelopes ({ "traceEvents": [ ... ], "metadata": { ... } }).Batched Native
JSON.parse:[and].JSON.parse, keeping intermediate string allocations small (< 5 MB) and short-lived.Metadata Preservation:
cpuThrottlingandnetworkThrottling) and merges it with caller options.Strict Structural Validation:
Testing
tests/trace-processing/ChunkedTraceParser.test.tscovering:basic-trace.json.gz,web-dev-with-commit.json.gz).