Skip to content

[Fusion] Skip lookups for entities the request already fetched - #10606

Merged
michaelstaib merged 8 commits into
ChilliCream:mainfrom
michaelstaib:mst/per-request-entity-caching
Oct 19, 2026
Merged

michaelstaib merged 8 commits into
ChilliCream:mainfrom
michaelstaib:mst/per-request-entity-caching

Conversation

@michaelstaib

Copy link
Copy Markdown
Member

No description provided.

@CLAassistant

CLAassistant commented Oct 18, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

…hem up again

A lookup now takes an entity from the composite result when a node it depends on
already wrote the same entity (same lookup type and requirement values) with every
leaf field the lookup selects. The target rows point at the existing values, so no
value data is copied, and a lookup whose entities are all served completes without
a source schema request.

On the graphql-federation-benchmarks query this removes the products and accounts
lookups of the third wave, so the inventory lookup starts one wave earlier (4 -> 3
sequential source schema requests, 6 -> 4 requests per gateway request).

Reuse is limited to query plans without incremental delivery, lookups without
forwarded variables, simple requirements and leaf selections, and producers whose
fields are written only by transitive dependencies of the lookup. It can be turned
off with FusionOptions.EnableEntityReuse.
@michaelstaib
michaelstaib force-pushed the mst/per-request-entity-caching branch from 654d474 to 62776e3 Compare October 18, 2026 18:22
@michaelstaib michaelstaib changed the title [Fusion] Experiments [Fusion] Skip lookups for entities the request already fetched Oct 18, 2026
The entity reuse index is created once when the operation plan is constructed and
stored in the operation features, which are unique per plan. The plan exposes it
through an extension property, and lookups read their reuse by id from an array
instead of a reference-keyed dictionary behind a weak table.

The analysis now parses the plan's operation text with trusted parser options and
resolves dependencies through the plan's own nodes, so a plan it cannot analyze
gets no reuse instead of failing.
A producer entity is only reused when its key selection is the requirement field
itself, with the same field definition and arguments as at every lookup target. An
alias such as `id: username` no longer turns another field into the entity key.

Entities are no longer reused while the result holds errors, so a field that
returns a value together with an error keeps that error at every position the
lookup fills.

The reuse analysis no longer fails planning: a plan it cannot analyze executes
without entity reuse.
EntityReuse becomes EntityReuseCandidateList and EntityReuseIndex becomes
EntityReuseCandidateMap. The map returns a lookup's list through GetCandidates,
the plan exposes it as EntityReuseCandidateMap, and the context through
GetEntityReuseCandidates. No behavior changes.
A key whose components are all null does not identify an entity, so entities
whose key fields are all null no longer serve as reuse candidates. Composite
keys with some null components stay reusable.
Each lookup target scanned every candidate, which is quadratic when nothing
is reused. Above four candidates, targets now probe the dedup table that
already indexes the candidate variables. EntityReuseCandidateMatchingBenchmark
measures the crossover between the scan and the probe.
Lookups whose key has nested fields get no reuse candidates and always fetch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants