Skip to content

feat: add bytecode compilation and execution for GraphQL responses#1494

Open
TheApeMachine wants to merge 2 commits into
wundergraph:masterfrom
TheApeMachine:feat/planbytecode
Open

feat: add bytecode compilation and execution for GraphQL responses#1494
TheApeMachine wants to merge 2 commits into
wundergraph:masterfrom
TheApeMachine:feat/planbytecode

Conversation

@TheApeMachine

Copy link
Copy Markdown

@coderabbitai summary

Checklist

  • I have discussed my proposed changes in an issue and have received approval to proceed.
  • I have followed the coding standards of the project.
  • Tests or benchmarks have been added or updated.

This commit introduces a new bytecode compilation and execution mechanism for GraphQL responses, enhancing performance and flexibility. It includes the implementation of various benchmarks and tests to ensure correctness and efficiency in processing GraphQL queries. New structures and functions for handling bytecode operations, including direct responses and nested object handling, have been added to improve the overall architecture of the engine.

I just made this because of my answer on your form about what I would do about the code. I realized my answer was making a lot of assumptions, so I wanted to know if they were correct. Please ignore if this is not a direction you are interested in at this time :)

Using the final -count=3 benchmark run on Apple M4 Max:

Scenario Original Final Bytecode Speedup B/op allocs/op
Loader only 3845 ns/op 3691 ns/op 1.04x 3096 -> 2736 60 -> 51
Flat query resolve 4661 ns/op 4205 ns/op 1.11x 4368 -> 4584 77 -> 44
Nested static query 2945 ns/op 1970 ns/op 1.50x 4968 -> 4160 99 -> 33
Batch entity query 3383 ns/op 2885 ns/op 1.17x 5811 -> 6228 98 -> 79
Object entity query 2021 ns/op 1799 ns/op 1.12x 3388 -> 4069 69 -> 56
Nested batch entity query 5946 ns/op 4732 ns/op 1.26x 7947 -> 8044 143 -> 121

Command used:

go test ./pkg/engine/resolve -run '^$' -bench 'BenchmarkResolveGraphQLResponse|BenchmarkLoaderLoadGraphQLResponseData' -benchmem -count=3

Interpretation: the best case is the static-shape nested query, where the bytecode direct renderer gets almost exactly the 1.5x target and cuts allocs by two thirds. Entity cases are more modest because they still pay ASTJSON merge/fetch-input costs, but they consistently reduce alloc count and still land around 1.12x-1.26x faster.

This commit introduces a new bytecode compilation and execution mechanism for GraphQL responses, enhancing performance and flexibility. It includes the implementation of various benchmarks and tests to ensure correctness and efficiency in processing GraphQL queries. New structures and functions for handling bytecode operations, including direct responses and nested object handling, have been added to improve the overall architecture of the engine.

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This pull request implements a complete bytecode compilation and execution system for GraphQL federation response resolution. The changes introduce an optimized instruction-based execution model that bypasses traditional fetch-tree traversal and enables direct-response rendering via byte-range extraction from subgraph JSON.

Changes

Bytecode Compilation and Execution Pipeline

Layer / File(s) Summary
Bytecode IR definition
v2/pkg/engine/planbytecode/bytecode.go, bytecode_test.go
Opcode enum (OpNop, OpEnterSequence, OpFetchSubgraph, OpProjectField, OpEmitLiteral, etc.) and fixed-width Op struct form the instruction set. Program container holds opcode stream, string/path side tables, fetches, optional DirectResponse tree, and execution stats. DirectField structures encode field metadata via flags and children. Tests verify Op is exactly 16 bytes.
JSON byte-range utilities
v2/pkg/engine/planbytecode/jsonpaste.go, jsonpaste_test.go
FindValueRange/FindValueRangeStatus locate byte spans for JSON values without unmarshalling. ScanObjectFieldRanges extracts ordered object fields; ScanArrayValueRanges enumerates array element ranges; AppendObjectFromRanges reconstructs objects from byte slices. Internal helpers (skipJSONValue, skipJSONString, skipJSONComposite) parse JSON structure at byte level. Tests verify field ordering, allocation-free repeated scans, nested paths, escaped keys, null detection, and array element extraction.
Bytecode compiler
v2/pkg/engine/planbytecode/compiler/compile.go, compile_test.go, bench_test.go, fixtures_test.go
Compile() translates plan.Plan to planbytecode.Program. Evaluates direct-response eligibility, compiles synchronous response fetch trees and response data into bytecode ops. compileDirectField builds direct-field trees; compileFetchTree emits sequence/parallel/fetch ops; compileNode emits object/array/literal/projection ops. Interns strings/paths, analyzes GraphQL selection sets for dead-code elimination, and records unsupported features. Tests cover opcode sequences, direct-response variants (flat/nested/entity/batch), dead-code elimination, variable normalization, and feature gating. Benchmarks measure tree walking, opcode iteration, and compilation throughput.
Bytecode execution and rendering
v2/pkg/engine/resolve/bytecode.go, bytecode_test.go
ResolveGraphQLResponseBytecode and ArenaResolveGraphQLResponseBytecode entry points manage concurrency, optionally load and render direct bytecode response, otherwise render and resolve. Loader.LoadGraphQLResponseDataBytecode executes bytecode span, collects raw fetch results, and orchestrates merging. renderDirectResponseBytecode selects direct value sources from subgraph JSON via byte ranges, renders objects/arrays/literals directly to output. Direct-field rendering validates field refs, emits JSON keys/values, handles nullability and object/array overlay. bytecodeResponseRenderer implements op-walking renderer for response-ops fallback. executeBytecodeSpan recursively executes ops, resolves fetches (single/batch entity/entity), and merges nested results. Runtime readiness gates (bytecodeDirectResponseRuntimeReady, bytecodeResponseRuntimeReady) disable fast paths when unsupported features, errors, or additional extensions present. Tests validate output matches fetch-tree resolution, fallback on errors, nested/merge/entity fetch scenarios, list-size tracking, and parallel fetch execution. Benchmarks compare fetch-tree vs bytecode resolution across all fixture patterns.

Sequence Diagrams

sequenceDiagram
  participant GraphQL Plan
  participant Compiler
  participant FetchOps as Fetch Ops
  participant ResponseOps as Response Ops
  participant StringRefs as String/Path Refs
  participant Program
  
  GraphQL Plan->>Compiler: plan input
  Compiler->>FetchOps: compileFetchTree
  Compiler->>ResponseOps: compileNode
  FetchOps->>StringRefs: registerFetch, pathRef
  ResponseOps->>StringRefs: stringRef, pathRef
  StringRefs->>Program: deduplicate entries
  FetchOps->>Program: append fetch records
  ResponseOps->>Program: append ops
  Compiler->>Program: add DirectResponse if eligible
Loading
sequenceDiagram
  participant Request as GraphQL Request
  participant Resolver as ResolveGraphQLResponseBytecode
  participant Loader as LoadGraphQLResponseDataBytecode
  participant FetchExec as executeBytecodeSpan
  participant DirectRender as renderDirectResponseBytecode
  participant Merge as mergeRawFetchResults
  participant Output as JSON Writer
  
  Request->>Resolver: invoke with program
  Resolver->>Loader: load bytecode data
  Loader->>FetchExec: walk ops, resolve fetches
  FetchExec->>FetchExec: recursively execute sequences/parallels
  Loader->>DirectRender: attempt direct response
  DirectRender->>DirectRender: selectDirectValueSources from byte ranges
  DirectRender->>Output: emit JSON directly
  alt Direct render succeeds
    Output->>Resolver: fast path done
  else Direct render unavailable
    Loader->>Merge: merge raw fetch results
    Merge->>Output: emit JSON from merged data
  end
  Resolver->>Output: finalize response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description is directly related to the changeset, explaining the bytecode mechanism, providing benchmark results, and detailing performance improvements across various scenarios.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately describes the main change: a new bytecode compilation and execution system for GraphQL responses, which is the primary focus across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@endigma

endigma commented May 15, 2026

Copy link
Copy Markdown
Member

Hi @TheApeMachine, wow, this is a pretty big change! Could you consider adding some more background to how your change works, your motivation, how you implemented it?

Being completely honest my main concern with PRs like this is that it's 5000 new lines of code that our team has to become comfortable enough with what you've written to adopt it into our codebase and offer long term support for it.

It's difficult to justify this based on purely the implementation and microbenchmarks (ns scale), so sharing some background would be great.

@TheApeMachine

Copy link
Copy Markdown
Author

@endigma Fully understand, and I will add some more background. However, just to make it clear, this was more in response to the question about what you would change, which was presented in the recruitment form. So please don't spend your time on this if this is not something you truly want/need to pursue. On the other hand, if performance is something on your roadmap, I believe there is a viable path for gains here. I will add the background in any case for completeness tomorrow.

@endigma

endigma commented May 16, 2026

Copy link
Copy Markdown
Member

Hi @TheApeMachine, thanks for letting me know, I think this could be a good idea, but I don't think we'll be merging something like this at this time unless you've motivated your change with a real issue.

Of course good luck with our hiring process!

@ysmolski ysmolski changed the title 💥feat!: add bytecode compilation and execution for GraphQL responses feat!: add bytecode compilation and execution for GraphQL responses May 18, 2026
@ysmolski ysmolski changed the title feat!: add bytecode compilation and execution for GraphQL responses feat: add bytecode compilation and execution for GraphQL responses May 18, 2026
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.

2 participants