Skip to content

BE-580: Inline type filters onto the edition cache; rework summarizeEntities aggregation#8903

Open
TimDiekmann wants to merge 7 commits into
mainfrom
t/be-580-investigate-slow-entity-queries-on-large-graphs
Open

BE-580: Inline type filters onto the edition cache; rework summarizeEntities aggregation#8903
TimDiekmann wants to merge 7 commits into
mainfrom
t/be-580-investigate-slow-entity-queries-on-large-graphs

Conversation

@TimDiekmann

@TimDiekmann TimDiekmann commented Jun 25, 2026

Copy link
Copy Markdown
Member

🌟 What is the purpose of this PR?

Two changes to how entity queries are compiled in the Postgres store:

  • The summarizeEntities type aggregation no longer expands the cached type arrays with a per-row CROSS JOIN LATERAL unnest, and skips the DISTINCT ON deduplication when the compiled query cannot emit duplicate rows.
  • Type-matching filters across apps/ and libs/ are inlined so they resolve against the materialized entity_edition_cache columns instead of the entity_is_of_type join.

🔗 Related links

🔍 What does this change?

summarizeEntities aggregation (hash-graph-postgres-store):

  • The type-ids branch expands the cache arrays via set-returning unnest in the SELECT list (ProjectSet) instead of CROSS JOIN LATERAL unnest(...).
  • Adds Relation::is_to_many and SelectCompiler::has_to_many_join. The hits CTE omits DISTINCT ON when no to-many (fan-out) join was added and the variable temporal axis is a collapsed point; otherwise it deduplicates as before. Selection is via a Deduplication enum (no boolean parameter).

Type-filter inlining (apps/ + libs/):

  • Removes generateVersionedUrlMatchingFilter. Every call site is inlined as a direct { equal: [{ path: ["type", "baseUrl"] }, { parameter: …entityTypeBaseUrl }] }["type", "versionedUrl"] for raw VersionedUrl inputs and version-sensitive sites, …linkEntityTypeBaseUrl for link types.
  • Drops the inheritanceDepth = 0 path qualifier: a bare type path resolves to the GIN-indexed entity_edition_cache base_urls/versioned_urls columns rather than the entity_is_of_type join. The remaining hand-written inheritanceDepth = 0 filters (machine-actors, org) and a rustdoc example are migrated to the same form.

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

🛡 What tests cover this?

  • hash-graph-postgres-store unit tests: statement_all_dimensions, statement_count_only, statement_skips_dedup, has_to_many_join_flag.
  • The inlined filters are covered by type-checking (lint:tsc).

❓ How to test this?

  1. cargo nextest run -p hash-graph-postgres-store
  2. turbo run lint:tsc for the affected TypeScript packages.

Replace the per-row `CROSS JOIN LATERAL unnest` in the type-ids branch with a
set-returning `unnest` in the SELECT list (ProjectSet), avoiding the
single-threaded nested-loop function scan that dominated runtime (~23s -> ~8s
warm on the production dataset).

Skip the `DISTINCT ON` edition dedup in the `hits` CTE when the compiled query
cannot emit duplicate rows per edition: no fan-out (to-many) filter join was
added and the variable temporal axis is a collapsed point. Dropping the sort
barrier lets the planner run a fully parallel partial aggregate (~8s -> ~4s
warm). `Relation::is_to_many` + `SelectCompiler::has_to_many_join` expose the
join-cardinality signal; the wrapper falls back to dedup whenever duplicates
are possible, so the default stays correct for arbitrary filters.
Remove `generateVersionedUrlMatchingFilter` and inline every call site as a
direct filter: `["type", "baseUrl"]` against `*.entityTypeBaseUrl` (or
`*.linkEntityTypeBaseUrl` for link types), `["type", "versionedUrl"]` where a
raw `VersionedUrl` is supplied or the exact version matters (e.g. migrations,
integration dedup).

Drop the `inheritanceDepth = 0` qualifier: a bare `type` path resolves to the
materialized `entity_edition_cache` `base_urls`/`versioned_urls` columns
(GIN-indexed over the full inheritance closure) instead of the slow
`entity_is_of_type` join. This moves these filters onto the cache fast path —
the same motivation as the summarizeEntities work — and obsoletes the
`pageEntityTypeFilter` "inheritance is slow" workaround.

Matching now includes subtypes (via the closure). For the affected system and
integration types this is flat today, and identity-critical lookups (Linear
sync dedup, `getOrgByShortname`) discriminate on a unique property, so the type
filter is only a coarse prefilter. Also migrates the remaining hand-written
`inheritanceDepth = 0` filters (`machine-actors`, `org`) and the `store.rs`
doc example to the same convention.
Copilot AI review requested due to automatic review settings June 25, 2026 11:08
@vercel

vercel Bot commented Jun 25, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview, Comment Jun 25, 2026 9:28pm
petrinaut Ready Ready Preview Jun 25, 2026 9:28pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hashdotdesign-tokens Ignored Ignored Preview Jun 25, 2026 9:28pm

@cursor

cursor Bot commented Jun 25, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Wide query-filter changes could alter which entities match (baseUrl vs versionedUrl, inheritance behavior); incorrect dedup skipping in summarize would miscount aggregates.

Overview
Entity type matching across apps and libs no longer uses generateVersionedUrlMatchingFilter. Call sites now use explicit equal filters on ["type", "baseUrl"] (with entityTypeBaseUrl / linkEntityTypeBaseUrl) or ["type", "versionedUrl"] when a specific version matters. That steers the Postgres compiler toward the materialized entity_edition_cache instead of the slower entity_is_of_type join. Shared helpers like pageEntityTypeFilter are removed in favor of the same inlined shape.

In hash-graph-postgres-store, summarizeEntities is reworked: type-id aggregation uses set-returning unnest in a subquery instead of CROSS JOIN LATERAL unnest, and the hits CTE can omit DISTINCT ON when SelectCompiler::has_to_many_join() is false and the variable temporal axis is a point interval—allowing parallel partial aggregates when duplicate editions cannot occur. Relation::is_to_many drives that decision via a Deduplication enum.

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

@github-actions github-actions Bot added area/apps > hash* Affects HASH (a `hash-*` app) area/apps > hash-api Affects the HASH API (app) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team type/eng > backend Owned by the @backend team area/apps labels Jun 25, 2026
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.90722% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.79%. Comparing base (882e794) to head (d024f51).

Files with missing lines Patch % Lines
...r-ts/src/activities/shared/find-existing-entity.ts 0.00% 1 Missing ⚠️
...phql/resolvers/knowledge/org/invite-user-to-org.ts 0.00% 1 Missing ⚠️
.../hash-isomorphic-utils/src/page-entity-type-ids.ts 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8903      +/-   ##
==========================================
+ Coverage   59.76%   59.79%   +0.03%     
==========================================
  Files        1348     1348              
  Lines      131817   131885      +68     
  Branches     5944     5940       -4     
==========================================
+ Hits        78784    78867      +83     
+ Misses      52125    52111      -14     
+ Partials      908      907       -1     
Flag Coverage Δ
apps.hash-ai-worker-ts 1.39% <0.00%> (ø)
apps.hash-api 3.26% <0.00%> (ø)
local.hash-backend-utils 2.81% <ø> (ø)
local.hash-graph-sdk 9.63% <ø> (ø)
local.hash-isomorphic-utils 0.18% <0.00%> (+<0.01%) ⬆️
rust.hash-graph-api 2.53% <ø> (ø)
rust.hash-graph-postgres-store 29.44% <100.00%> (+0.32%) ⬆️
rust.hash-graph-store 37.99% <ø> (ø)
rust.hash-graph-validation 83.43% <ø> (ø)
rust.hashql-compiletest 28.24% <ø> (ø)
rust.hashql-eval 75.23% <ø> (ø)

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.

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 optimizes how entity queries are compiled/executed in the Postgres store by (1) reducing work in summarizeEntities (skipping unnecessary deduplication and avoiding lateral unnest expansion) and (2) inlining type-matching filters across the TypeScript codebase so they target the materialized entity_edition_cache type columns (base URLs / versioned URLs) rather than the entity_is_of_type join.

Changes:

  • Reworked summarizeEntities aggregation SQL generation to avoid CROSS JOIN LATERAL unnest(...) and to conditionally skip DISTINCT ON based on a new deduplication decision.
  • Introduced Relation::is_to_many and SelectCompiler::has_to_many_join() to detect fan-out joins and drive the deduplication decision.
  • Removed generateVersionedUrlMatchingFilter and replaced call sites with direct { equal: [{ path: ["type", ...] }, { parameter: ... }] } filters (plus nested path equivalents for link traversals).

Reviewed changes

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

Show a summary per file
File Description
libs/@local/hash-isomorphic-utils/src/page-entity-type-ids.ts Replaces helper-based type filters with direct type.versionedUrl equality filters.
libs/@local/hash-isomorphic-utils/src/graph-queries.ts Removes generateVersionedUrlMatchingFilter and trims unused imports/types.
libs/@local/hash-backend-utils/src/user-secret.ts Inlines link-type filter to type.baseUrl against the edition cache.
libs/@local/hash-backend-utils/src/service-usage.ts Inlines usage/service feature type filters to type.baseUrl.
libs/@local/hash-backend-utils/src/machine-actors.ts Migrates type(inheritanceDepth = 0).baseUrl to type.baseUrl.
libs/@local/hash-backend-utils/src/google.ts Inlines Google account type filter to type.baseUrl.
libs/@local/hash-backend-utils/src/flows/shared/get-flow-run-entity-by-id.ts Inlines flow-run type filter to type.baseUrl.
libs/@local/hash-backend-utils/src/flows/process-flow-workflow/common-activities/persist-flow-activity.ts Inlines flow-run type filter to type.baseUrl.
libs/@local/hash-backend-utils/src/flows/get-flow-context.ts Inlines flow-run type filter to type.baseUrl.
libs/@local/hash-backend-utils/src/flows.ts Inlines flow-run type filter to type.baseUrl.
libs/@local/graph/store/src/entity/store.rs Updates rustdoc JSON example to use type.versionedUrl equality filter.
libs/@local/graph/postgres-store/src/store/postgres/query/table.rs Adds Relation::is_to_many() to classify joins as fan-out vs to-one.
libs/@local/graph/postgres-store/src/store/postgres/query/statement/select.rs Adds unit test for has_to_many_join behavior (cache vs fan-out path).
libs/@local/graph/postgres-store/src/store/postgres/query/compile.rs Tracks has_to_many_join during relation-joining for later dedup decisions.
libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/summary.rs Adds Deduplication enum, updates SQL wrapping, and changes type aggregation unnest strategy.
libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/mod.rs Chooses Deduplication::{Skip,Required} for summarize_entities based on join fan-out + temporal axis shape.
apps/plugin-browser/src/pages/popup/popup-contents/action-center/history/shared/history-row/flow-metadata-cell-contents.tsx Inlines usage record type filter to type.baseUrl.
apps/hash-integration-worker/src/shared/graph-requests.ts Inlines optional entity type filter and flattens conditional clauses.
apps/hash-integration-worker/src/activities/flow-activities/integration-activities/persist-integration-entities-action.ts Inlines entity/link type filters to type.versionedUrl.
apps/hash-frontend/src/shared/use-user-or-org.ts Inlines user/org type filters to type.baseUrl.
apps/hash-frontend/src/shared/use-actors.ts Inlines machine type filter to type.baseUrl.
apps/hash-frontend/src/shared/notification-count-context.tsx Inlines notification type filters to type.baseUrl.
apps/hash-frontend/src/pages/shared/use-flow-runs-usage.ts Inlines usage record type filter to type.baseUrl.
apps/hash-frontend/src/pages/shared/integrations/google/google-auth-context/use-google-accounts.ts Inlines Google account type filter to type.baseUrl.
apps/hash-frontend/src/pages/shared/entity/entity-editor/claims-section.tsx Inlines claim type filter to type.baseUrl.
apps/hash-frontend/src/pages/shared/entity-selector.tsx Inlines expected entity type filters to type.versionedUrl.
apps/hash-frontend/src/pages/shared/block-collection/shared/mention-suggester.tsx Inlines user/org type filters to type.baseUrl.
apps/hash-frontend/src/pages/settings/organizations/[shortname]/integrations.page.tsx Inlines integration link type filter to type.baseUrl.
apps/hash-frontend/src/pages/notifications.page/notifications-with-links-context.tsx Inlines notification type filter to type.baseUrl.
apps/hash-frontend/src/pages/notes.page.tsx Inlines note type filter to type.baseUrl.
apps/hash-frontend/src/pages/index.page/waitlisted.tsx Inlines prospective user type filter to type.baseUrl.
apps/hash-frontend/src/pages/@/[shortname]/shared/flow-visualizer/outputs/claims-output.tsx Inlines claim type filter to type.baseUrl.
apps/hash-frontend/src/pages/@/[shortname].page.tsx Inlines include-type filters to type.versionedUrl.
apps/hash-frontend/src/components/hooks/use-users-with-links.ts Inlines user type filter to type.baseUrl.
apps/hash-frontend/src/components/hooks/use-orgs-with-links.ts Inlines org type filter to type.baseUrl.
apps/hash-api/src/graphql/resolvers/knowledge/user/get-usage-records.ts Simplifies user type filter to a single type.baseUrl equality filter.
apps/hash-api/src/graphql/resolvers/knowledge/org/invite-user-to-org.ts Inlines invitation type filter selection to type.baseUrl.
apps/hash-api/src/graph/knowledge/system-types/user.ts Inlines user/invitation type filters to type.baseUrl.
apps/hash-api/src/graph/knowledge/system-types/text.ts Inlines link/entity type filters (including nested leftEntity/incoming link paths) to type.baseUrl.
apps/hash-api/src/graph/knowledge/system-types/org.ts Migrates type(inheritanceDepth = 0).baseUrl to type.baseUrl.
apps/hash-api/src/graph/knowledge/system-types/notification.ts Inlines mention/comment notification type filters to type.baseUrl.
apps/hash-api/src/graph/knowledge/system-types/linear-user-secret.ts Inlines multiple nested link/entity type filters to type.baseUrl.
apps/hash-api/src/graph/knowledge/system-types/linear-integration-entity.ts Inlines linear integration / sync link type filters to type.baseUrl.
apps/hash-api/src/graph/knowledge/system-types/block.ts Inlines nested leftEntity type filter to type.baseUrl.
apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/util.ts Simplifies getEntitiesByType filter to type.versionedUrl equality.
apps/hash-api/src/auth/create-unverified-email-cleanup-job.ts Inlines user type filter to type.baseUrl.
apps/hash-ai-worker-ts/src/shared/testing-utilities/get-alice-user-account-id.ts Inlines user type filter to type.baseUrl.
apps/hash-ai-worker-ts/src/activities/shared/find-existing-entity.ts Inlines proposed entity type filters to type.versionedUrl.
apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/coordinating-agent/summarize-existing-entities.ai.test.ts Inlines user type filter to type.baseUrl.
apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action.ts Inlines claim type filter to type.baseUrl.
apps/hash-ai-worker-ts/src/activities/flow-activities/process-automatic-browsing-settings-action.ts Inlines browser plugin settings type filter to type.baseUrl.

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

Comment thread libs/@local/hash-isomorphic-utils/src/page-entity-type-ids.ts Outdated
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 25, 2026 12:19 Inactive
Comment thread apps/hash-api/src/graph/knowledge/system-types/block.ts
Comment on lines 34 to 36
/**
* We specify each of these page types individually rather than Page, which they both inherit from,
* because checking against types involving inheritance is currently slow.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This comment is no longer valid. We could replace the filter below with a single check against systemEntityTypes.page.entityTypeId. Or just delete this whole comment.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I removed the function and replaced the caller by a proper filter.

Copilot AI review requested due to automatic review settings June 25, 2026 21:14
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 25, 2026 21:14 Inactive
@TimDiekmann TimDiekmann requested a review from CiaranMn June 25, 2026 21:16

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8826211. Configure here.

Comment thread apps/hash-api/src/graph/knowledge/system-types/page.ts

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

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

Comment thread libs/@local/graph/postgres-store/src/store/postgres/knowledge/entity/summary.rs Outdated
TimDiekmann and others added 2 commits June 25, 2026 23:19
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 25, 2026 21:21 Inactive

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

Copilot reviewed 53 out of 53 changed files in this pull request and generated no new comments.

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

Copilot reviewed 53 out of 53 changed files in this pull request and generated no new comments.

@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 $$28.1 \mathrm{ms} \pm 197 \mathrm{μs}\left({\color{gray}1.96 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.60 \mathrm{ms} \pm 17.7 \mathrm{μs}\left({\color{red}5.07 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1001 $$13.4 \mathrm{ms} \pm 128 \mathrm{μs}\left({\color{red}7.46 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$44.7 \mathrm{ms} \pm 380 \mathrm{μs}\left({\color{gray}1.34 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$15.7 \mathrm{ms} \pm 130 \mathrm{μs}\left({\color{red}12.8 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1526 $$25.1 \mathrm{ms} \pm 226 \mathrm{μs}\left({\color{gray}2.43 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$29.3 \mathrm{ms} \pm 204 \mathrm{μs}\left({\color{gray}4.47 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$4.05 \mathrm{ms} \pm 32.1 \mathrm{μs}\left({\color{red}7.40 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$14.0 \mathrm{ms} \pm 98.7 \mathrm{μs}\left({\color{gray}4.18 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_medium

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 102 $$3.90 \mathrm{ms} \pm 27.7 \mathrm{μs}\left({\color{gray}-0.362 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.08 \mathrm{ms} \pm 18.0 \mathrm{μs}\left({\color{gray}0.591 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 51 $$3.44 \mathrm{ms} \pm 24.5 \mathrm{μs}\left({\color{gray}0.495 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.36 \mathrm{ms} \pm 36.4 \mathrm{μs}\left({\color{gray}1.01 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.65 \mathrm{ms} \pm 26.6 \mathrm{μs}\left({\color{gray}1.73 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 107 $$4.22 \mathrm{ms} \pm 24.4 \mathrm{μs}\left({\color{gray}0.812 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.58 \mathrm{ms} \pm 36.9 \mathrm{μs}\left({\color{gray}0.813 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.53 \mathrm{ms} \pm 25.5 \mathrm{μs}\left({\color{gray}0.435 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.20 \mathrm{ms} \pm 30.2 \mathrm{μs}\left({\color{gray}0.944 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.68 \mathrm{ms} \pm 18.4 \mathrm{μs}\left({\color{gray}2.62 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.58 \mathrm{ms} \pm 15.9 \mathrm{μs}\left({\color{gray}0.058 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1 $$2.65 \mathrm{ms} \pm 15.4 \mathrm{μs}\left({\color{gray}2.00 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$2.92 \mathrm{ms} \pm 16.9 \mathrm{μs}\left({\color{gray}2.32 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.72 \mathrm{ms} \pm 21.3 \mathrm{μs}\left({\color{gray}1.72 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$2.91 \mathrm{ms} \pm 17.1 \mathrm{μs}\left({\color{gray}0.599 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$3.09 \mathrm{ms} \pm 19.3 \mathrm{μs}\left({\color{gray}-0.646 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.80 \mathrm{ms} \pm 18.5 \mathrm{μs}\left({\color{gray}1.65 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 25 $$3.07 \mathrm{ms} \pm 16.8 \mathrm{μs}\left({\color{gray}1.67 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.52 \mathrm{ms} \pm 25.6 \mathrm{μs}\left({\color{gray}1.37 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.00 \mathrm{ms} \pm 15.4 \mathrm{μs}\left({\color{gray}1.04 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 26 $$3.34 \mathrm{ms} \pm 19.2 \mathrm{μs}\left({\color{gray}1.10 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.41 \mathrm{ms} \pm 18.1 \mathrm{μs}\left({\color{gray}-0.338 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.00 \mathrm{ms} \pm 17.6 \mathrm{μs}\left({\color{gray}0.557 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.40 \mathrm{ms} \pm 21.4 \mathrm{μs}\left({\color{gray}-1.610 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$43.5 \mathrm{ms} \pm 242 \mathrm{μs}\left({\color{gray}3.98 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$33.6 \mathrm{ms} \pm 223 \mathrm{μs}\left({\color{gray}0.876 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$36.7 \mathrm{ms} \pm 247 \mathrm{μs}\left({\color{gray}3.92 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$42.7 \mathrm{ms} \pm 1.41 \mathrm{ms}\left({\color{red}35.5 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$43.6 \mathrm{ms} \pm 268 \mathrm{μs}\left({\color{red}5.02 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$50.6 \mathrm{ms} \pm 267 \mathrm{μs}\left({\color{gray}3.59 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$41.7 \mathrm{ms} \pm 271 \mathrm{μs}\left({\color{gray}4.75 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$89.7 \mathrm{ms} \pm 583 \mathrm{μs}\left({\color{red}5.37 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$34.2 \mathrm{ms} \pm 195 \mathrm{μs}\left({\color{gray}3.07 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$286 \mathrm{ms} \pm 1.26 \mathrm{ms}\left({\color{gray}4.46 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$10.8 \mathrm{ms} \pm 64.0 \mathrm{μs}\left({\color{gray}2.70 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$10.9 \mathrm{ms} \pm 66.0 \mathrm{μs}\left({\color{gray}2.49 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$11.1 \mathrm{ms} \pm 63.5 \mathrm{μs}\left({\color{gray}3.53 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$10.8 \mathrm{ms} \pm 62.7 \mathrm{μs}\left({\color{gray}3.08 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$11.3 \mathrm{ms} \pm 64.1 \mathrm{μs}\left({\color{red}6.23 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$10.9 \mathrm{ms} \pm 76.0 \mathrm{μs}\left({\color{gray}4.10 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$10.9 \mathrm{ms} \pm 63.1 \mathrm{μs}\left({\color{gray}3.41 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$11.0 \mathrm{ms} \pm 63.8 \mathrm{μs}\left({\color{gray}3.30 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$11.4 \mathrm{ms} \pm 70.3 \mathrm{μs}\left({\color{red}6.71 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$11.4 \mathrm{ms} \pm 95.2 \mathrm{μs}\left({\color{red}6.92 \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 $$11.3 \mathrm{ms} \pm 70.1 \mathrm{μs}\left({\color{gray}4.14 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$11.4 \mathrm{ms} \pm 72.1 \mathrm{μs}\left({\color{red}5.29 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$11.5 \mathrm{ms} \pm 72.8 \mathrm{μs}\left({\color{red}5.75 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$11.7 \mathrm{ms} \pm 84.5 \mathrm{μs}\left({\color{red}7.24 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$11.4 \mathrm{ms} \pm 66.0 \mathrm{μs}\left({\color{gray}3.89 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$11.6 \mathrm{ms} \pm 84.1 \mathrm{μs}\left({\color{red}5.83 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$11.6 \mathrm{ms} \pm 72.4 \mathrm{μs}\left({\color{red}5.22 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$11.4 \mathrm{ms} \pm 95.5 \mathrm{μs}\left({\color{gray}3.31 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$11.5 \mathrm{ms} \pm 88.8 \mathrm{μs}\left({\color{gray}4.79 \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 $$9.11 \mathrm{ms} \pm 80.9 \mathrm{μs}\left({\color{gray}4.44 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$62.4 \mathrm{ms} \pm 430 \mathrm{μs}\left({\color{gray}3.53 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$115 \mathrm{ms} \pm 738 \mathrm{μs}\left({\color{gray}3.25 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$67.7 \mathrm{ms} \pm 495 \mathrm{μs}\left({\color{gray}3.26 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$76.3 \mathrm{ms} \pm 524 \mathrm{μs}\left({\color{gray}3.19 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$85.4 \mathrm{ms} \pm 489 \mathrm{μs}\left({\color{gray}2.06 \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 654 \mathrm{μs}\left({\color{gray}2.28 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$46.0 \mathrm{ms} \pm 247 \mathrm{μs}\left({\color{red}6.39 \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 $$77.1 \mathrm{ms} \pm 453 \mathrm{μs}\left({\color{red}5.62 \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 $$52.6 \mathrm{ms} \pm 287 \mathrm{μs}\left({\color{red}5.41 \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 $$64.0 \mathrm{ms} \pm 476 \mathrm{μs}\left({\color{red}7.53 \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 $$66.2 \mathrm{ms} \pm 523 \mathrm{μs}\left({\color{red}7.86 \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 $$66.2 \mathrm{ms} \pm 425 \mathrm{μs}\left({\color{red}7.53 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$119 \mathrm{ms} \pm 818 \mathrm{μs}\left({\color{lightgreen}-7.476 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$131 \mathrm{ms} \pm 620 \mathrm{μs}\left({\color{gray}-4.755 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$19.5 \mathrm{ms} \pm 128 \mathrm{μs}\left({\color{lightgreen}-20.074 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$535 \mathrm{ms} \pm 1.36 \mathrm{ms}\left({\color{gray}0.970 \mathrm{\%}}\right) $$ Flame Graph

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

Labels

area/apps > hash* Affects HASH (a `hash-*` app) area/apps > hash-api Affects the HASH API (app) area/apps area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

3 participants