Skip to content

BE-599: Compute entity summary aggregations in SQL#8864

Open
TimDiekmann wants to merge 2 commits into
t/be-596-materialize-the-aggregate-views-in-the-entity-subgraph-queryfrom
t/be-599-compute-the-entity-summary-aggregations-in-sql-instead-of
Open

BE-599: Compute entity summary aggregations in SQL#8864
TimDiekmann wants to merge 2 commits into
t/be-596-materialize-the-aggregate-views-in-the-entity-subgraph-queryfrom
t/be-599-compute-the-entity-summary-aggregations-in-sql-instead-of

Conversation

@TimDiekmann

@TimDiekmann TimDiekmann commented Jun 12, 2026

Copy link
Copy Markdown
Member

🌟 What is the purpose of this PR?

When any of the include* summary flags is set, queryEntities re-ran the full filtered query unbounded (no DISTINCT, no LIMIT) and streamed every matching row to the client to fold counts there.

This PR computes the summaries (total count, per-web, per-creator, per-edition-creator, per-type counts) in SQL instead: the compiled filter query is wrapped into a deduplicated hits CTE feeding one UNION ALL aggregate branch per requested dimension, so only the aggregate rows cross the wire.

🔗 Related links

🚫 Blocked by

🔍 What does this change?

  • New module postgres/knowledge/entity/summary.rs: EntitySummaryQuery::new(compiler, params) adds the required selections (or returns None when no summary is requested), statement() wraps the compiled query into the aggregate statement, decode() routes the result rows into EntitySummaries via a Dimension discriminant enum.
  • The per-type counts unnest the direct-type prefix of the entity_edition_cache arrays (from BE-596: Materialize entity aggregates into entity_edition_cache #8854) instead of joining the type tables.
  • Deduplication is per entity identity: plain (hashable) DISTINCT when only entity-scoped columns are selected, DISTINCT ON (web_id, entity_uuid, draft_id) when edition-scoped columns (edition provenance, type arrays) are present — interval temporal axes can match multiple editions per entity, and a plain DISTINCT over edition-scoped columns would inflate the counts.
  • Behaviour fix: includeTypeTitles: true without any other summary flag now returns type titles; previously the summary pass silently never ran for it.
  • decode returns Result instead of panicking on unexpected row shapes (e.g. a NULL actor ID from malformed provenance JSON).
  • query/mod.rs: test_helper is pub(crate) so the new module's unit tests can reuse trim_whitespace.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

⚠️ Known issues

  • The summary query inherits the type-chain joins from the compiled filter; BE-597 (next PR in the stack) replaces those with array predicates and multiplies the win.
  • DISTINCT ON picks an arbitrary edition per entity for the edition-scoped dimensions under interval temporal axes — same nondeterminism as the previous client-side HashMap fold.

🐾 Next steps

  • BE-597: array-based type filtering in the SelectCompiler (stacked on this PR).
  • Integration tests covering the include* flags (incl. multi-edition entities under interval axes).

🛡 What tests cover this?

  • New unit tests in summary.rs pinning the generated aggregate SQL (all dimensions incl. DISTINCT ON, count-only) and the dimension discriminant round-trip.
  • Existing integration tests covering queryEntities/queryEntitySubgraph responses in CI.

❓ How to test this?

  1. Checkout the branch, start the graph with a seeded database.
  2. Run a queryEntitySubgraph request with includeCount/includeWebIds/includeCreatedByIds/includeEditionCreatedByIds/includeTypeIds/includeTypeTitles set.
  3. Confirm the summary fields match the values on the base branch and the query no longer streams all matching rows.

Copilot AI review requested due to automatic review settings June 12, 2026 14:40
@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
hash Ignored Ignored Preview Jun 12, 2026 3:08pm
hashdotdesign-tokens Ignored Ignored Preview Jun 12, 2026 3:08pm
petrinaut Skipped Skipped Jun 12, 2026 3:08pm

@cursor

cursor Bot commented Jun 12, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes core read-path SQL and deduplication semantics for edition-scoped summaries under interval temporal axes; large-query behavior shifts but outputs are intended to match prior aggregation.

Overview
Moves queryEntities / queryEntitySubgraph summary fields (count, per-web, per-creator, per-edition-creator, per-type) from client-side folding over every matching row to PostgreSQL aggregation via new EntitySummaryQuery in summary.rs.

The compiled filter query is wrapped in a deduplicated hits CTE (DISTINCT or DISTINCT ON entity identity when edition-scoped columns are needed), then UNION ALL branches aggregate each requested dimension; per-type counts use unnest(versioned_urls[1:direct_types]) from the edition cache instead of type-table joins.

query_entities_impl now runs this aggregate query before the limited entity fetch. includeTypeTitles alone now triggers the summary pass (titles-only no longer skipped). Summary decoding errors on bad rows instead of panicking. Adds unit tests for generated SQL and an integration test for all include_* flags.

Reviewed by Cursor Bugbot for commit 22de6ab. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions github-actions Bot added area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team labels Jun 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR moves entity-query summary aggregation (the various include_* summary flags) from client-side folding over an unbounded result stream to server-side SQL aggregation, reducing the amount of data streamed back and improving performance on large datasets.

Changes:

  • Add knowledge/entity/summary.rs to build a deduplicated hits CTE and compute requested summary dimensions via UNION ALL aggregate branches, plus decode the resulting rows into EntitySummaries.
  • Update knowledge/entity/mod.rs to use the SQL-side summary query and to ensure includeTypeTitles alone triggers the summary pass (so titles are returned).
  • Expose query::test_helper as pub(crate) (still #[cfg(test)]) so the new module’s unit tests can reuse trim_whitespace.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
libs/@local/graph/postgres-store/src/store/postgres/query/mod.rs Makes test_helper accessible within the crate during tests for reuse by new summary unit tests.
libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/summary.rs New SQL-side summary aggregation/query builder + decoder + unit tests for statement generation and dimension discriminant round-trip.
libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs Replaces client-side summary folding with SQL aggregate query execution + decoding; fixes includeTypeTitles-only behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 67.98246% with 73 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.21%. Comparing base (db769d6) to head (df62a4e).

Files with missing lines Patch % Lines
...ore/src/store/postgres/knowledge/entity/summary.rs 67.98% 71 Missing and 2 partials ⚠️
Additional details and impacted files
@@                                            Coverage Diff                                            @@
##           t/be-596-materialize-the-aggregate-views-in-the-entity-subgraph-query    #8864      +/-   ##
=========================================================================================================
+ Coverage                                                                  59.17%   59.21%   +0.03%     
=========================================================================================================
  Files                                                                       1346     1347       +1     
  Lines                                                                     130111   130290     +179     
  Branches                                                                    5885     5894       +9     
=========================================================================================================
+ Hits                                                                       76995    77150     +155     
- Misses                                                                     52210    52232      +22     
- Partials                                                                     906      908       +2     
Flag Coverage Δ
apps.hash-ai-worker-ts 1.39% <ø> (ø)
apps.hash-api 0.00% <ø> (ø)
local.hash-backend-utils 2.81% <ø> (ø)
local.hash-graph-sdk 9.63% <ø> (ø)
local.hash-isomorphic-utils 0.00% <ø> (ø)
rust.hash-graph-api 2.51% <ø> (ø)
rust.hash-graph-postgres-store 27.65% <67.98%> (+0.60%) ⬆️
rust.hashql-compiletest 28.26% <ø> (ø)
rust.hashql-eval 75.72% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@vercel vercel Bot temporarily deployed to Preview – petrinaut June 12, 2026 15:07 Inactive
@github-actions github-actions Bot added the area/tests New or updated tests label Jun 12, 2026
@TimDiekmann TimDiekmann requested a review from a team June 12, 2026 15:28
@github-actions

Copy link
Copy Markdown
Contributor

Benchmark results

@rust/hash-graph-benches – Integrations

policy_resolution_large

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2002 $$25.7 \mathrm{ms} \pm 159 \mathrm{μs}\left({\color{gray}-1.224 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.44 \mathrm{ms} \pm 19.0 \mathrm{μs}\left({\color{gray}-1.092 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1001 $$12.7 \mathrm{ms} \pm 105 \mathrm{μs}\left({\color{gray}1.50 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$43.2 \mathrm{ms} \pm 363 \mathrm{μs}\left({\color{gray}1.26 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$14.5 \mathrm{ms} \pm 111 \mathrm{μs}\left({\color{lightgreen}-6.563 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1526 $$24.4 \mathrm{ms} \pm 164 \mathrm{μs}\left({\color{gray}0.090 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$27.5 \mathrm{ms} \pm 220 \mathrm{μs}\left({\color{gray}2.12 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.89 \mathrm{ms} \pm 30.5 \mathrm{μs}\left({\color{gray}0.415 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$14.2 \mathrm{ms} \pm 111 \mathrm{μs}\left({\color{gray}2.95 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_medium

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 102 $$3.84 \mathrm{ms} \pm 26.4 \mathrm{μs}\left({\color{gray}2.08 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.04 \mathrm{ms} \pm 19.9 \mathrm{μs}\left({\color{gray}0.423 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 51 $$3.44 \mathrm{ms} \pm 20.5 \mathrm{μs}\left({\color{gray}1.42 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.18 \mathrm{ms} \pm 39.1 \mathrm{μs}\left({\color{gray}1.43 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.57 \mathrm{ms} \pm 22.2 \mathrm{μs}\left({\color{gray}1.55 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 107 $$4.28 \mathrm{ms} \pm 47.7 \mathrm{μs}\left({\color{gray}3.31 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.37 \mathrm{ms} \pm 26.3 \mathrm{μs}\left({\color{gray}-4.171 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.63 \mathrm{ms} \pm 28.0 \mathrm{μs}\left({\color{gray}3.74 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.15 \mathrm{ms} \pm 41.3 \mathrm{μs}\left({\color{gray}-2.845 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.64 \mathrm{ms} \pm 14.4 \mathrm{μs}\left({\color{lightgreen}-11.170 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.56 \mathrm{ms} \pm 15.9 \mathrm{μs}\left({\color{gray}-3.850 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1 $$2.65 \mathrm{ms} \pm 21.6 \mathrm{μs}\left({\color{lightgreen}-5.820 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$2.91 \mathrm{ms} \pm 14.9 \mathrm{μs}\left({\color{gray}-4.607 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.22 \mathrm{ms} \pm 23.7 \mathrm{μs}\left({\color{red}9.70 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$3.14 \mathrm{ms} \pm 38.7 \mathrm{μs}\left({\color{lightgreen}-5.265 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$3.05 \mathrm{ms} \pm 19.2 \mathrm{μs}\left({\color{gray}1.24 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.76 \mathrm{ms} \pm 15.7 \mathrm{μs}\left({\color{gray}-0.366 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 25 $$2.99 \mathrm{ms} \pm 20.3 \mathrm{μs}\left({\color{gray}0.112 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.37 \mathrm{ms} \pm 20.1 \mathrm{μs}\left({\color{gray}0.594 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$2.98 \mathrm{ms} \pm 16.2 \mathrm{μs}\left({\color{gray}-0.118 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 26 $$3.28 \mathrm{ms} \pm 19.7 \mathrm{μs}\left({\color{gray}0.062 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.31 \mathrm{ms} \pm 19.6 \mathrm{μs}\left({\color{gray}-0.005 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.98 \mathrm{ms} \pm 16.7 \mathrm{μs}\left({\color{gray}1.12 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.32 \mathrm{ms} \pm 20.5 \mathrm{μs}\left({\color{gray}1.65 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$57.5 \mathrm{ms} \pm 329 \mathrm{μs}\left({\color{gray}0.118 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$49.5 \mathrm{ms} \pm 300 \mathrm{μs}\left({\color{gray}-0.142 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$52.9 \mathrm{ms} \pm 425 \mathrm{μs}\left({\color{gray}0.041 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$48.3 \mathrm{ms} \pm 301 \mathrm{μs}\left({\color{gray}-0.412 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$64.4 \mathrm{ms} \pm 705 \mathrm{μs}\left({\color{gray}-0.248 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$65.2 \mathrm{ms} \pm 370 \mathrm{μs}\left({\color{gray}-3.164 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$58.2 \mathrm{ms} \pm 373 \mathrm{μs}\left({\color{gray}-1.457 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$111 \mathrm{ms} \pm 615 \mathrm{μs}\left({\color{gray}-1.890 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$50.3 \mathrm{ms} \pm 286 \mathrm{μs}\left({\color{lightgreen}-9.787 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$285 \mathrm{ms} \pm 1.29 \mathrm{ms}\left({\color{lightgreen}-7.816 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$22.8 \mathrm{ms} \pm 135 \mathrm{μs}\left({\color{gray}-4.266 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$24.2 \mathrm{ms} \pm 165 \mathrm{μs}\left({\color{lightgreen}-5.751 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$22.9 \mathrm{ms} \pm 149 \mathrm{μs}\left({\color{gray}-2.335 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$22.8 \mathrm{ms} \pm 188 \mathrm{μs}\left({\color{lightgreen}-6.588 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$27.4 \mathrm{ms} \pm 160 \mathrm{μs}\left({\color{gray}0.029 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$22.2 \mathrm{ms} \pm 130 \mathrm{μs}\left({\color{gray}-2.985 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$22.3 \mathrm{ms} \pm 138 \mathrm{μs}\left({\color{gray}-1.389 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$22.2 \mathrm{ms} \pm 104 \mathrm{μs}\left({\color{gray}-0.087 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$22.0 \mathrm{ms} \pm 162 \mathrm{μs}\left({\color{gray}0.781 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$22.8 \mathrm{ms} \pm 134 \mathrm{μs}\left({\color{gray}-0.534 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity

Function Value Mean Flame graphs
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1 $$24.7 \mathrm{ms} \pm 137 \mathrm{μs}\left({\color{gray}3.07 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$24.8 \mathrm{ms} \pm 149 \mathrm{μs}\left({\color{gray}3.46 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$24.9 \mathrm{ms} \pm 121 \mathrm{μs}\left({\color{red}6.00 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$24.8 \mathrm{ms} \pm 142 \mathrm{μs}\left({\color{red}5.16 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$25.2 \mathrm{ms} \pm 162 \mathrm{μs}\left({\color{gray}-1.054 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$24.8 \mathrm{ms} \pm 135 \mathrm{μs}\left({\color{gray}4.55 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$25.1 \mathrm{ms} \pm 221 \mathrm{μs}\left({\color{red}6.62 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$24.8 \mathrm{ms} \pm 139 \mathrm{μs}\left({\color{red}5.33 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$25.3 \mathrm{ms} \pm 162 \mathrm{μs}\left({\color{gray}-2.307 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity_type

Function Value Mean Flame graphs
get_entity_type_by_id Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba $$8.59 \mathrm{ms} \pm 55.2 \mathrm{μs}\left({\color{gray}1.46 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$62.7 \mathrm{ms} \pm 464 \mathrm{μs}\left({\color{gray}0.110 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$112 \mathrm{ms} \pm 826 \mathrm{μs}\left({\color{gray}-1.230 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$70.0 \mathrm{ms} \pm 473 \mathrm{μs}\left({\color{gray}0.497 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$77.4 \mathrm{ms} \pm 481 \mathrm{μs}\left({\color{gray}-4.557 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$87.5 \mathrm{ms} \pm 790 \mathrm{μs}\left({\color{gray}-1.914 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$92.1 \mathrm{ms} \pm 791 \mathrm{μs}\left({\color{gray}-0.131 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$81.5 \mathrm{ms} \pm 445 \mathrm{μs}\left({\color{gray}-0.707 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$113 \mathrm{ms} \pm 689 \mathrm{μs}\left({\color{gray}1.26 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$88.6 \mathrm{ms} \pm 601 \mathrm{μs}\left({\color{gray}-0.411 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$97.3 \mathrm{ms} \pm 514 \mathrm{μs}\left({\color{gray}-0.499 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$101 \mathrm{ms} \pm 751 \mathrm{μs}\left({\color{gray}0.734 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$100 \mathrm{ms} \pm 589 \mathrm{μs}\left({\color{gray}-0.078 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$143 \mathrm{ms} \pm 594 \mathrm{μs}\left({\color{gray}0.893 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$153 \mathrm{ms} \pm 699 \mathrm{μs}\left({\color{gray}-0.887 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$57.5 \mathrm{ms} \pm 310 \mathrm{μs}\left({\color{red}27.8 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$584 \mathrm{ms} \pm 1.08 \mathrm{ms}\left({\color{gray}-0.239 \mathrm{\%}}\right) $$ Flame Graph

@TimDiekmann TimDiekmann requested review from a team and removed request for a team June 12, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/libs Relates to first-party libraries/crates/packages (area) area/tests New or updated tests type/eng > backend Owned by the @backend team

Development

Successfully merging this pull request may close these issues.

2 participants