Thanks to visit codestin.com
Credit goes to github.com

Skip to content

WIP: feat(performance): chunked trace buffer parser for large recordings - #2721

Draft
jackfranklin wants to merge 3 commits into
mainfrom
chunked-trace-parsing
Draft

WIP: feat(performance): chunked trace buffer parser for large recordings#2721
jackfranklin wants to merge 3 commits into
mainfrom
chunked-trace-parsing

Conversation

@jackfranklin

Copy link
Copy Markdown
Contributor

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, parseRawTraceBuffer decodes the entire raw buffer into a single string via new TextDecoder().decode(buffer) and parses it with JSON.parse(asString). In V8 (64-bit), strings are strictly limited to $2^{29} - 24$ characters (~512 MB). Any trace exceeding ~512 MB throws a fatal error:

RangeError: Cannot create a string longer than 0x1fffffe8 characters

This 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.ts to extract trace events directly from the raw binary buffer in bounded batches without materializing the full trace JSON into a single string:

  1. Byte-Level Delimiter & Escape Scanning:

    • Scans the Uint8Array directly using ASCII byte codes (0x7B {, 0x7D }, 0x22 ", 0x5C \).
    • Tracks brace nesting depth while properly handling escaped quotes within strings.
    • Supports both bare JSON arrays ([ {...}, ... ]) and top-level object envelopes ({ "traceEvents": [ ... ], "metadata": { ... } }).
  2. Batched Native JSON.parse:

    • Accumulates slices of events into bounded batches (default: 5,000 events) wrapped in [ and ].
    • Parses each batch using native V8 JSON.parse, keeping intermediate string allocations small (< 5 MB) and short-lived.
    • Pushes parsed events iteratively to avoid V8 function call argument stack limits.
  3. Metadata Preservation:

    • Extracts top-level metadata from object envelopes (such as cpuThrottling and networkThrottling) and merges it with caller options.
  4. Strict Structural Validation:

    • Enforces valid structural tokens (closing brackets, braces, colons, commas) and prevents silent truncation on incomplete buffers or unexpected EOF.

Testing

  • Unit tests in tests/trace-processing/ChunkedTraceParser.test.ts covering:
    • Both top-level array and object formats.
    • Custom batch sizes and large batches exceeding function call argument limits (70,000+ events).
    • Malformed inputs: truncated arrays, unterminated strings, unquoted keys, trailing characters.
    • Multibyte UTF-8 characters split across byte boundaries.
  • Full regression tests against existing trace fixtures (basic-trace.json.gz, web-dev-with-commit.json.gz).

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.
@jackfranklin

Copy link
Copy Markdown
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.

@jackfranklin

Copy link
Copy Markdown
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant