Skip to content

feat(hashql-core): add LinkedGraph benchmarking suite with instruction counting#8420

Closed
indietyp wants to merge 1 commit intomainfrom
feat/linked-graph-benchmarks
Closed

feat(hashql-core): add LinkedGraph benchmarking suite with instruction counting#8420
indietyp wants to merge 1 commit intomainfrom
feat/linked-graph-benchmarks

Conversation

@indietyp
Copy link
Member

Summary

Add a comprehensive benchmarking suite for the LinkedGraph data structure in hashql-core. The benchmarks use instruction counting on Linux (via perf_event) with a fallback to wall-clock time on other platforms.

What's Included

Benchmark Groups

  • node: add_node, lookup by ID, iteration over nodes
  • edge: add_edge, lookup by ID, iteration over edges
  • adjacency: successors, predecessors, incident edges iteration
  • traversal: DFS, BFS, post-order traversal across various graph topologies
  • mutation: clear_edges, clear, derive operations

Graph Fixtures

  • Chain graph: Linear 0 → 1 → 2 → ... → n-1
  • Complete graph: Every node connected to every other
  • Binary tree: Balanced tree of configurable depth
  • Sparse graph: Fixed edges per node with deterministic distribution

Implementation Details

Instruction Counting (Linux)

Uses the perf_event crate to create a hardware instruction counter. This provides deterministic, reproducible benchmark results that are independent of system load.

let counter = Builder::new()
    .kind(Hardware::INSTRUCTIONS)
    .build()?;

Fallback (Non-Linux)

On platforms that don't support perf_event (macOS, Windows), the benchmarks automatically fall back to criterion's default wall-clock time measurement.

How to Run

# Run all linked graph benchmarks
cargo bench --package hashql-core --bench linked_graph

# Run specific benchmark group
cargo bench --package hashql-core --bench linked_graph -- "node"
cargo bench --package hashql-core --bench linked_graph -- "traversal"

Example Output (Linux with instruction counting)

node/add/10000          time:   [197.12 Ki 197.14 Ki 197.15 Ki]
                        thrpt:  [19.715 inst/elem 19.714 inst/elem 19.712 inst/elem]

node/iter/1000          time:   [4.0700 Ki 4.0700 Ki 4.0700 Ki]
                        thrpt:  [4.0700 inst/elem 4.0700 inst/elem 4.0700 inst/elem]

This PR was generated with Warp.

…n counting

Add a comprehensive benchmarking suite for the LinkedGraph data structure
that uses instruction counting on Linux (via perf_event) with a fallback
to wall-clock time on other platforms.

Benchmark groups:
- node: add, lookup, iteration operations
- edge: add, lookup, iteration operations
- adjacency: successors, predecessors, incident edges iteration
- traversal: DFS, BFS, post-order traversal on various topologies
- mutation: clear_edges, clear, derive operations

Graph fixtures include: chain, complete, binary tree, and sparse graphs.

Co-Authored-By: Warp <agent@warp.dev>
@cursor
Copy link

cursor bot commented Feb 13, 2026

PR Summary

Low Risk
Changes are limited to dev-dependencies, lockfile updates, and new benchmark code; no production logic is modified, with the main risk being CI/benchmark build issues on Linux due to perf-event permissions or platform differences.

Overview
Adds a new hashql-core benchmark suite (benches/linked_graph.rs) covering LinkedGraph node/edge operations, adjacency iteration, traversals, and mutation APIs across several graph fixtures.

On Linux, benchmarks now optionally measure CPU instruction counts via perf-event (custom Criterion Measurement + formatter), with a wall-clock fallback on other platforms; workspace/dev-dependencies are updated accordingly and linked_graph is registered as a new cargo bench target.

Written by Cursor Bugbot for commit 1c41c5f. This will update automatically on new commits. Configure here.

@vercel
Copy link

vercel bot commented Feb 13, 2026

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

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview, Comment Feb 13, 2026 4:49pm
hashdotdesign Ready Ready Preview, Comment Feb 13, 2026 4:49pm
hashdotdesign-tokens Ready Ready Preview, Comment Feb 13, 2026 4:49pm
petrinaut Ready Ready Preview, Comment Feb 13, 2026 4:49pm

@github-actions github-actions bot added area/deps Relates to third-party dependencies (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team labels Feb 13, 2026
@augmentcode
Copy link

augmentcode bot commented Feb 13, 2026

🤖 Augment PR Summary

Summary: Adds a new Criterion benchmarking suite for the hashql-core LinkedGraph data structure, with Linux instruction-count measurement.

Changes:

  • Adds perf-event to workspace dependencies and wires it as a Linux-only dev-dependency for hashql-core
  • Registers a new linked_graph bench target (non-harness) alongside the existing benches
  • Introduces benches/linked_graph.rs covering node, edge, adjacency, traversal, and mutation benchmark groups
  • Implements a Linux-only Criterion Measurement that counts CPU instructions via perf_event
  • Uses wall-clock time (WallTime) automatically on non-Linux targets
  • Adds deterministic graph fixtures (chain, complete, binary tree, sparse) to exercise different topologies

Technical Notes: On Linux, measurements are taken from a hardware instruction counter (reset/enable per iteration, disable/read at end). Throughput is primarily reported as instructions per element using Criterion’s throughput reporting.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

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

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

let counter = Builder::new()
.kind(Hardware::INSTRUCTIONS)
.build()
.expect(
Copy link

Choose a reason for hiding this comment

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

InstructionCount::new() currently expects on perf_event counter creation, which will make cargo bench fail on many Linux setups (e.g., containers/CI with restrictive perf_event_paranoid). Consider a graceful fallback (or an opt-in flag) so benchmarks still run when hardware counters aren’t available.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

criterion::Throughput::Bytes(bytes)
| criterion::Throughput::BytesDecimal(bytes) => {
for value in values {
*value = (*bytes as f64) / *value;
Copy link

Choose a reason for hiding this comment

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

In scale_throughputs for Throughput::Bytes*, the calculation is inverted: *value = bytes / value yields bytes-per-instruction, but the unit returned is inst/B. If you intend inst/B, this should scale like the Elements case (divide instructions by bytes).

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link

@github-advanced-security github-advanced-security bot left a comment

Choose a reason for hiding this comment

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

clippy found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

@codecov
Copy link

codecov bot commented Feb 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.99%. Comparing base (c8e4ac9) to head (1c41c5f).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8420      +/-   ##
==========================================
- Coverage   61.05%   60.99%   -0.07%     
==========================================
  Files        1247     1248       +1     
  Lines      121606   121739     +133     
  Branches     5267     5299      +32     
==========================================
+ Hits        74245    74251       +6     
- Misses      46489    46616     +127     
  Partials      872      872              
Flag Coverage Δ
apps.hash-ai-worker-ts 1.40% <ø> (-0.01%) ⬇️
apps.hash-api 0.00% <ø> (ø)
blockprotocol.type-system 40.84% <ø> (ø)
local.claude-hooks 0.00% <ø> (ø)
local.harpc-client 51.24% <ø> (ø)
local.hash-graph-sdk 7.78% <ø> (+1.11%) ⬆️
local.hash-isomorphic-utils 0.00% <ø> (ø)
rust.antsi 0.00% <ø> (ø)
rust.error-stack 90.88% <ø> (ø)
rust.harpc-codec 84.70% <ø> (ø)
rust.harpc-net 96.18% <ø> (+0.03%) ⬆️
rust.harpc-tower 66.80% <ø> (ø)
rust.harpc-types 0.00% <ø> (ø)
rust.harpc-wire-protocol 92.23% <ø> (ø)
rust.hash-codec 72.76% <ø> (ø)
rust.hash-graph-api 2.88% <ø> (ø)
rust.hash-graph-authorization 62.34% <ø> (ø)
rust.hash-graph-postgres-store 26.80% <ø> (ø)
rust.hash-graph-store 39.10% <ø> (ø)
rust.hash-graph-temporal-versioning 47.95% <ø> (ø)
rust.hash-graph-types 0.00% <ø> (ø)
rust.hash-graph-validation 83.45% <ø> (ø)
rust.hashql-ast 87.25% <ø> (ø)
rust.hashql-compiletest 46.65% <ø> (ø)
rust.hashql-core 81.75% <ø> (ø)
rust.hashql-diagnostics 72.43% <ø> (ø)
rust.hashql-eval 68.54% <ø> (ø)
rust.hashql-hir 89.10% <ø> (ø)
rust.hashql-mir 89.51% <ø> (ø)
rust.hashql-syntax-jexpr 94.05% <ø> (ø)

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

☔ View full report in Codecov by Sentry.
📢 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.

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 13, 2026

Merging this PR will not alter performance

✅ 21 untouched benchmarks


Comparing feat/linked-graph-benchmarks (1c41c5f) with main (c8e4ac9)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (c5edd55) during the generation of this report, so c8e4ac9 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Copy link

@cursor cursor bot left a comment

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 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

*value = (*bytes as f64) / *value;
}
"inst/B"
}
Copy link

Choose a reason for hiding this comment

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

Inverted throughput formula for Bytes measurement scaling

Medium Severity

The Bytes/BytesDecimal branch in scale_throughputs computes bytes / instructions (bytes per instruction) but labels the result "inst/B" (instructions per byte). The formula is the reciprocal of what the unit label indicates. The Elements branch correctly uses *value /= *elements as f64 to get instructions-per-element, but the Bytes branch inconsistently uses *value = (*bytes as f64) / *value instead of the analogous *value /= *bytes as f64.

Fix in Cursor Fix in Web

let mid = NodeId::new(size / 2);
b.iter(|| black_box(graph.node(mid)));
});
}
Copy link

Choose a reason for hiding this comment

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

Stale throughput leaks into lookup benchmark results

Low Severity

The group.throughput() call from the preceding "add" loop persists on the BenchmarkGroup and leaks into the "lookup" benchmarks, which don't reset it. In bench_node_operations, lookup benchmarks inherit a stale throughput of 10,000 elements; in bench_edge_operations, they inherit 249,500 elements. Since lookup measures a single O(1) operation, the reported throughput (inst/elem) values will be orders of magnitude off, producing misleading benchmark output.

Additional Locations (1)

Fix in Cursor Fix in Web

@github-actions
Copy link
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 $$27.2 \mathrm{ms} \pm 156 \mathrm{μs}\left({\color{gray}0.016 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.48 \mathrm{ms} \pm 16.9 \mathrm{μs}\left({\color{gray}-0.011 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1001 $$12.3 \mathrm{ms} \pm 76.2 \mathrm{μs}\left({\color{gray}-0.406 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$56.7 \mathrm{ms} \pm 423 \mathrm{μs}\left({\color{red}32.1 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$14.7 \mathrm{ms} \pm 88.8 \mathrm{μs}\left({\color{gray}-0.424 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1526 $$24.3 \mathrm{ms} \pm 165 \mathrm{μs}\left({\color{gray}0.868 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$28.4 \mathrm{ms} \pm 238 \mathrm{μs}\left({\color{gray}1.42 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.78 \mathrm{ms} \pm 15.6 \mathrm{μs}\left({\color{gray}-0.312 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$13.2 \mathrm{ms} \pm 71.5 \mathrm{μs}\left({\color{gray}-0.558 \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 22.8 \mathrm{μs}\left({\color{gray}0.125 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.09 \mathrm{ms} \pm 16.3 \mathrm{μs}\left({\color{gray}0.496 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 51 $$3.42 \mathrm{ms} \pm 16.6 \mathrm{μs}\left({\color{gray}-0.609 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.30 \mathrm{ms} \pm 26.2 \mathrm{μs}\left({\color{gray}-0.727 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.70 \mathrm{ms} \pm 26.4 \mathrm{μs}\left({\color{gray}-0.016 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 107 $$4.25 \mathrm{ms} \pm 21.7 \mathrm{μs}\left({\color{gray}0.058 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.58 \mathrm{ms} \pm 27.4 \mathrm{μs}\left({\color{gray}0.961 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.52 \mathrm{ms} \pm 18.7 \mathrm{μs}\left({\color{gray}0.671 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.21 \mathrm{ms} \pm 33.9 \mathrm{μs}\left({\color{gray}1.33 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.80 \mathrm{ms} \pm 16.2 \mathrm{μs}\left({\color{gray}-0.325 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.78 \mathrm{ms} \pm 15.3 \mathrm{μs}\left({\color{gray}1.37 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1 $$2.87 \mathrm{ms} \pm 15.1 \mathrm{μs}\left({\color{gray}-0.099 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$3.15 \mathrm{ms} \pm 21.7 \mathrm{μs}\left({\color{gray}0.995 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.94 \mathrm{ms} \pm 16.4 \mathrm{μs}\left({\color{gray}-0.141 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$3.22 \mathrm{ms} \pm 21.5 \mathrm{μs}\left({\color{gray}-0.481 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$3.15 \mathrm{ms} \pm 15.8 \mathrm{μs}\left({\color{gray}-0.342 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.88 \mathrm{ms} \pm 14.2 \mathrm{μs}\left({\color{gray}-0.094 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 25 $$3.05 \mathrm{ms} \pm 14.9 \mathrm{μs}\left({\color{gray}0.238 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.63 \mathrm{ms} \pm 20.8 \mathrm{μs}\left({\color{gray}-0.069 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.14 \mathrm{ms} \pm 13.6 \mathrm{μs}\left({\color{gray}-0.015 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 26 $$3.39 \mathrm{ms} \pm 14.5 \mathrm{μs}\left({\color{gray}-1.438 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.52 \mathrm{ms} \pm 16.2 \mathrm{μs}\left({\color{gray}-0.382 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.13 \mathrm{ms} \pm 16.8 \mathrm{μs}\left({\color{gray}-1.002 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.42 \mathrm{ms} \pm 18.8 \mathrm{μs}\left({\color{gray}-1.827 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$41.1 \mathrm{ms} \pm 188 \mathrm{μs}\left({\color{gray}0.112 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$78.9 \mathrm{ms} \pm 387 \mathrm{μs}\left({\color{gray}1.19 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$46.4 \mathrm{ms} \pm 202 \mathrm{μs}\left({\color{gray}2.91 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$48.1 \mathrm{ms} \pm 232 \mathrm{μs}\left({\color{gray}0.844 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$55.4 \mathrm{ms} \pm 355 \mathrm{μs}\left({\color{gray}-0.148 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$43.1 \mathrm{ms} \pm 195 \mathrm{μs}\left({\color{gray}1.58 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$426 \mathrm{ms} \pm 877 \mathrm{μs}\left({\color{gray}2.18 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$92.3 \mathrm{ms} \pm 537 \mathrm{μs}\left({\color{lightgreen}-5.372 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$88.2 \mathrm{ms} \pm 411 \mathrm{μs}\left({\color{gray}2.31 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$283 \mathrm{ms} \pm 933 \mathrm{μs}\left({\color{lightgreen}-9.823 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$15.8 \mathrm{ms} \pm 73.7 \mathrm{μs}\left({\color{gray}0.788 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$15.7 \mathrm{ms} \pm 88.6 \mathrm{μs}\left({\color{gray}-0.878 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$15.9 \mathrm{ms} \pm 83.3 \mathrm{μs}\left({\color{gray}-0.289 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$15.9 \mathrm{ms} \pm 99.1 \mathrm{μs}\left({\color{gray}2.57 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$18.0 \mathrm{ms} \pm 128 \mathrm{μs}\left({\color{gray}-4.051 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$15.3 \mathrm{ms} \pm 60.5 \mathrm{μs}\left({\color{gray}-2.667 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$15.6 \mathrm{ms} \pm 90.9 \mathrm{μs}\left({\color{gray}0.408 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$15.6 \mathrm{ms} \pm 69.8 \mathrm{μs}\left({\color{gray}0.046 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$16.2 \mathrm{ms} \pm 94.3 \mathrm{μs}\left({\color{gray}0.470 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$23.5 \mathrm{ms} \pm 158 \mathrm{μs}\left({\color{gray}-1.109 \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 $$30.4 \mathrm{ms} \pm 246 \mathrm{μs}\left({\color{gray}-2.677 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$31.0 \mathrm{ms} \pm 284 \mathrm{μs}\left({\color{gray}-2.597 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$30.5 \mathrm{ms} \pm 309 \mathrm{μs}\left({\color{gray}-0.751 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$29.8 \mathrm{ms} \pm 252 \mathrm{μs}\left({\color{gray}-3.203 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$31.6 \mathrm{ms} \pm 281 \mathrm{μs}\left({\color{gray}4.75 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$31.2 \mathrm{ms} \pm 281 \mathrm{μs}\left({\color{gray}0.967 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$31.0 \mathrm{ms} \pm 277 \mathrm{μs}\left({\color{gray}3.30 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$31.0 \mathrm{ms} \pm 315 \mathrm{μs}\left({\color{gray}-0.735 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$31.0 \mathrm{ms} \pm 335 \mathrm{μs}\left({\color{gray}-2.945 \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.60 \mathrm{ms} \pm 41.1 \mathrm{μs}\left({\color{gray}0.177 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$88.9 \mathrm{ms} \pm 438 \mathrm{μs}\left({\color{gray}-0.014 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$141 \mathrm{ms} \pm 530 \mathrm{μs}\left({\color{gray}-0.419 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$95.3 \mathrm{ms} \pm 435 \mathrm{μs}\left({\color{gray}-0.940 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$104 \mathrm{ms} \pm 479 \mathrm{μs}\left({\color{gray}-0.327 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$113 \mathrm{ms} \pm 504 \mathrm{μs}\left({\color{gray}-0.327 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$128 \mathrm{ms} \pm 3.30 \mathrm{ms}\left({\color{red}6.00 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$86.9 \mathrm{ms} \pm 354 \mathrm{μs}\left({\color{gray}-1.007 \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 $$114 \mathrm{ms} \pm 504 \mathrm{μs}\left({\color{gray}-1.308 \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 $$93.3 \mathrm{ms} \pm 370 \mathrm{μs}\left({\color{gray}-1.142 \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 $$106 \mathrm{ms} \pm 1.70 \mathrm{ms}\left({\color{gray}3.14 \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 $$103 \mathrm{ms} \pm 450 \mathrm{μs}\left({\color{gray}-1.329 \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 $$103 \mathrm{ms} \pm 423 \mathrm{μs}\left({\color{gray}-1.796 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$134 \mathrm{ms} \pm 532 \mathrm{μs}\left({\color{gray}1.15 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$135 \mathrm{ms} \pm 600 \mathrm{μs}\left({\color{gray}3.25 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$104 \mathrm{ms} \pm 548 \mathrm{μs}\left({\color{gray}0.263 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$590 \mathrm{ms} \pm 3.58 \mathrm{ms}\left({\color{gray}3.51 \mathrm{\%}}\right) $$ Flame Graph

@indietyp
Copy link
Member Author

Warp, creating a PR in my name, without asking me is a bad bad thing.

@indietyp indietyp closed this Feb 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/deps Relates to third-party dependencies (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team

Development

Successfully merging this pull request may close these issues.

1 participant