Skip to content

BE-714: Gate the actor-ID header behind a service credential - #9233

Open
TimDiekmann wants to merge 7 commits into
mainfrom
t/be-714-define-node-api-authentication-to-the-graph
Open

BE-714: Gate the actor-ID header behind a service credential#9233
TimDiekmann wants to merge 7 commits into
mainfrom
t/be-714-define-node-api-authentication-to-the-graph

Conversation

@TimDiekmann

Copy link
Copy Markdown
Member

🌟 What is the purpose of this PR?

Closes the last unauthenticated path into the Graph REST API: the X-Authenticated-User-Actor-Id header is only honored next to a service secret. Internal services (Node API, Temporal workers) authenticate themselves before naming the actor they act for, and the bootstrap routes require the same secret instead of being reachable by anyone on the network.

🔗 Related links

🚫 Blocked by

🔍 What does this change?

  • AuthenticationProvider returns ControlFlow<Authentication>: Continue(()) means the request carries no credential the provider handles, Break(Verified | Rejected) is terminal. Chaining is the ? operator, so a rejected credential structurally cannot fall through to another provider
  • Authentication::Verified carries the authorization crate's AuthenticatedActor — Kratos verifies to a typed Id, service delegation passes the claimed actor through as Uuid
  • delegation::ServiceDelegationProvider recognizes the pair of X-HASH-Service-Secret and the actor-ID header as one credential. The secret is compared in constant time. An actor-ID header without the secret is rejected, never ignored
  • the bare actor-ID header fallback in resolve_request_actor is deleted; the new rejections log at warn level, since only internal services send these credentials and a mismatch is a deployment problem
  • bootstrap routes (/policies/seed, /actors/machine/identifier/system/{identifier}) require the service secret and lose their unauthenticated allowlist entries
  • the server requires a non-empty HASH_GRAPH_SERVICE_SECRET to start (parse-optional so server --healthcheck works without it), and an empty configured secret never matches — a set-but-empty variable cannot silently disable the credential
  • bootstrap routes admit only requests carrying no credential at all: an actively rejected credential (malformed actor header, stale session cookie) stays rejected there too
  • the Node API and both Temporal workers send the secret as an axios default header from the same variable; the config structs mask it (and the OpenAI key) in Debug output
  • compose sets the secret on the graph service and all four senders; the httpyac suite injects it via a .httpyac.config.js hook, and service-delegation.http pins the rejection paths end-to-end
  • drive-by: hide_env_values on the five sensitive clap env args (Postgres password ×2, OpenAI key, Mailchimp key, Sentry DSN) — --help no longer prints their values

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

  • Deploy order matters: the senders roll out first (the current Graph ignores the extra header), then the Graph — it refuses to start without the secret. The secret must exist in Secrets Manager and the task definitions before rollout; that is the next internal-infra PR.
  • One static secret shared by all senders; rotating it requires restarting every consumer in lockstep. A dual-secret rotation window is tracked in BE-763 (internal).
  • Delegated actors are passed through as claimed rather than validated against the principal store: the secret authenticates the sender, the Node API legitimately delegates to the public actor for anonymous requests, and a per-request store lookup would tax the hottest path before the BE-755 (internal) cache exists.
  • The admin server keeps its bare actor-ID header middleware (behind Cloudflare Access) until BE-761 (internal) moves it onto the shared pipeline.
  • The custom header is transitional by design and superseded by Hydra client_credentials (BE-728 (internal)).

🐾 Next steps

  • provision the secret in staging/production (internal-infra)
  • Cloudflare Access JWTs as a provider and admin-server unification (BE-761) (internal)
  • OAuth2 client_credentials for service identity (BE-728) (internal)

🛡 What tests cover this?

  • delegation.rs unit tests: the full header matrix — pair verifies, wrong secret, actor header without secret (the no-fallback case), secret without actor, malformed actor UUID
  • provider.rs chain tests: falls through on Continue, stops at the first Verified or Rejected
  • middleware tests: bootstrap routes with/without/with-wrong secret, bare actor headers, verified passthrough
  • service-delegation.http end-to-end rejection paths with client-safe message asserts; the entire HTTP suite now runs through the delegation path via the injected secret

❓ How to test this?

  1. Start the external services and the Graph (yarn start:graph or cargo run --bin hash-graph --all-features -- server)
  2. curl -i http://127.0.0.1:4000/actors/machine/identifier/system/h -H "X-HASH-Service-Secret: hash-svc-local-dev-secret" → 200; without the header → 401
  3. Any request with X-Authenticated-User-Actor-Id but without the secret → 401 the actor-ID header requires the service credential
  4. Full suite: cd tests/graph/http && sh test.sh

🐒 Demo

N/A — backend authentication path; see the httpyac suite output for the wire-level flow.

@TimDiekmann TimDiekmann self-assigned this Aug 17, 2026
@vercel

vercel Bot commented Aug 17, 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 Aug 21, 2026 9:08pm
petrinaut Ready Ready Preview Aug 21, 2026 9:08pm
petrinaut-docs Ready Ready Preview Aug 21, 2026 9:08pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hashdotdesign-tokens Ignored Ignored Preview Aug 21, 2026 9:08pm

@github-actions github-actions Bot added area/deps Relates to third-party dependencies (area) area/apps > hash* Affects HASH (a `hash-*` app) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team area/tests New or updated tests area/apps area/apps > hash-graph labels Aug 17, 2026
@TimDiekmann
TimDiekmann deployed to pull-request August 17, 2026 11:26 — with GitHub Actions Active
@TimDiekmann
TimDiekmann deployed to pull-request August 17, 2026 11:26 — with GitHub Actions Active
@codecov

codecov Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.34368% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.94%. Comparing base (357589c) to head (1d41299).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
libs/@local/graph/api/src/rest/mod.rs 0.00% 10 Missing ⚠️
libs/@local/graph/authentication/src/request.rs 80.95% 3 Missing and 1 partial ⚠️
libs/@local/graph/authentication/src/delegation.rs 98.25% 1 Missing and 2 partials ⚠️
libs/@local/graph/authentication/src/kratos.rs 97.22% 0 Missing and 2 partials ⚠️
libs/@local/graph/authentication/src/provider.rs 97.22% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9233      +/-   ##
==========================================
+ Coverage   59.71%   59.94%   +0.23%     
==========================================
  Files        1423     1427       +4     
  Lines      138862   139949    +1087     
  Branches     6572     6595      +23     
==========================================
+ Hits        82915    83899     +984     
- Misses      54881    54976      +95     
- Partials     1066     1074       +8     
Flag Coverage Δ
apps.hash-ai-worker-ts 1.99% <ø> (ø)
apps.hash-api 14.66% <ø> (ø)
blockprotocol.type-system 40.84% <ø> (ø)
local.claude-hooks 0.00% <ø> (ø)
local.harpc-client 51.49% <ø> (ø)
local.hash-backend-utils 3.27% <ø> (ø)
local.hash-graph-sdk 10.02% <ø> (ø)
local.hash-isomorphic-utils 12.22% <ø> (ø)
rust.antsi 2.36% <ø> (ø)
rust.error-stack 90.81% <ø> (ø)
rust.harpc-codec 84.70% <ø> (ø)
rust.harpc-net 96.21% <ø> (ø)
rust.harpc-tower 67.03% <ø> (ø)
rust.harpc-types 0.00% <ø> (ø)
rust.harpc-wire-protocol 92.23% <ø> (ø)
rust.hash-codec 72.76% <ø> (ø)
rust.hash-graph-api 12.34% <90.29%> (+4.84%) ⬆️
rust.hash-graph-authentication 93.63% <96.83%> (+9.66%) ⬆️
rust.hash-graph-authorization 62.59% <ø> (ø)
rust.hash-graph-embeddings 91.88% <ø> (ø)
rust.hash-graph-postgres-store 29.33% <ø> (ø)
rust.hash-graph-store 46.78% <ø> (ø)
rust.hash-graph-temporal-versioning 47.95% <ø> (ø)
rust.hash-graph-types 0.00% <ø> (ø)
rust.hash-graph-validation 84.71% <ø> (ø)
rust.hashql-ast 89.63% <ø> (ø)
rust.hashql-compiletest 28.39% <ø> (ø)
rust.hashql-core 78.98% <ø> (ø)
rust.hashql-diagnostics 72.51% <ø> (ø)
rust.hashql-eval 79.82% <ø> (ø)
rust.hashql-hir 89.09% <ø> (ø)
rust.hashql-mir 87.92% <ø> (ø)
rust.hashql-syntax-jexpr 94.04% <ø> (ø)

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.

Comment thread apps/hash-graph/src/subcommand/server.rs
@codspeed-hq

codspeed-hq Bot commented Aug 17, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 15.38%

❌ 2 regressed benchmarks
✅ 96 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
bit_matrix/dense/iter_row[64] 140.8 ns 170 ns -17.16%
bit_matrix/dense/iter_row[200] 185.8 ns 215 ns -13.57%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing t/be-714-define-node-api-authentication-to-the-graph (1d41299) with main (206ca32)

Open in CodSpeed

@vercel
vercel Bot temporarily deployed to Preview – petrinaut August 17, 2026 11:39 Inactive
@TimDiekmann
TimDiekmann marked this pull request as ready for review August 17, 2026 11:42
Copilot AI balanced review requested due to automatic review settings August 17, 2026 11:42
@cursor

cursor Bot commented Aug 17, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Changes Graph REST authentication: the actor-ID header is no longer trusted alone, and bootstrap routes now require a service secret. Misconfiguration or rollout order can lock out internal services or leave a shared secret incorrectly deployed.

Overview
Closes the last unauthenticated Graph REST path: X-Authenticated-User-Actor-Id is only honored next to Authorization: HASH-Service <secret>. Internal services (Node API, Temporal workers) must present that secret to act as an actor; bootstrap routes (/policies/seed, system machine identifiers) now require the same secret instead of being open on the network.

Providers now return ControlFlow<Authentication> so a rejected credential cannot fall through. Kratos sessions still win over a delegation pair. ServiceDelegationProvider treats secret + actor header as one credential (constant-time compare); a bare actor header is rejected. The Graph refuses to start without a non-empty HASH_GRAPH_SERVICE_SECRET. Compose, the Graph HTTP client, and httpyac inject the secret; clap also hides other sensitive env values in --help.

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

@TimDiekmann
TimDiekmann force-pushed the t/be-714-define-node-api-authentication-to-the-graph branch from 65ebe47 to 3654b9c Compare August 17, 2026 11:43
@TimDiekmann
TimDiekmann deployed to pull-request August 17, 2026 11:44 — with GitHub Actions Active
@TimDiekmann
TimDiekmann deployed to pull-request August 17, 2026 11:44 — with GitHub Actions Active

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

Gates Graph actor delegation and bootstrap routes behind a shared service credential.

Changes:

  • Adds composable Kratos and service-delegation authentication providers.
  • Wires the credential through Graph clients, server configuration, and Compose.
  • Adds delegation tests and masks sensitive CLI environment values.

Reviewed changes

Copilot reviewed 23 out of 24 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.env Defines the local service secret.
Cargo.toml Adds the constant-time comparison dependency.
Cargo.lock Records generated dependency updates.
apps/hash-graph/Cargo.toml Adds debug-derivation support.
apps/hash-graph/src/subcommand/admin_server.rs Hides the Mailchimp key in help.
apps/hash-graph/src/subcommand/server.rs Validates and masks the service secret.
infra/compose/compose.yml Distributes the secret to Graph services.
libs/@local/graph/api/src/rest/auth.rs Enforces authentication and bootstrap gating.
libs/@local/graph/api/src/rest/mod.rs Wires the provider chain into REST.
libs/@local/graph/authentication/Cargo.toml Adds subtle.
libs/@local/graph/authentication/src/actor.rs Shares a test actor resolver.
libs/@local/graph/authentication/src/delegation.rs Implements service delegation.
libs/@local/graph/authentication/src/kratos.rs Adapts Kratos to provider chaining.
libs/@local/graph/authentication/src/lib.rs Exports delegation support.
libs/@local/graph/authentication/src/provider.rs Introduces terminal provider chaining.
libs/@local/graph/authentication/src/request.rs Removes bare actor-header fallback.
libs/@local/graph/migrations/src/bin/cli/subcommand/mod.rs Hides database passwords in help.
libs/@local/graph/postgres-store/src/store/config.rs Hides database passwords in help.
libs/@local/hash-backend-utils/src/create-graph-client.ts Sends the service credential by default.
libs/@local/telemetry/src/traces/sentry.rs Hides Sentry DSN values in help.
tests/graph/http/.httpyac.config.js Injects the secret into HTTP tests.
tests/graph/http/test.sh Runs delegation integration tests.
tests/graph/http/tests/hashql.http Preserves the no-credentials test case.
tests/graph/http/tests/service-delegation.http Covers delegation rejection paths.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread infra/compose/compose.yml
Comment thread tests/graph/http/.httpyac.config.js
Comment thread tests/graph/http/tests/service-delegation.http Outdated
Comment thread libs/@local/graph/api/src/rest/auth.rs Outdated
Copilot AI review requested due to automatic review settings August 17, 2026 11:47
Comment thread libs/@local/graph/api/src/rest/auth.rs Outdated
@vercel
vercel Bot temporarily deployed to Preview – petrinaut-docs August 21, 2026 12:27 Inactive
@vercel
vercel Bot temporarily deployed to Preview – petrinaut August 21, 2026 12:27 Inactive
Base automatically changed from t/be-760-verify-kratos-sessions-in-the-graph-api to main August 21, 2026 12:49
@TimDiekmann
TimDiekmann force-pushed the t/be-714-define-node-api-authentication-to-the-graph branch from 956742e to 10e4e63 Compare August 21, 2026 13:05
@TimDiekmann
TimDiekmann deployed to pull-request August 21, 2026 13:06 — with GitHub Actions Active
@TimDiekmann
TimDiekmann deployed to pull-request August 21, 2026 13:06 — with GitHub Actions Active
@TimDiekmann
TimDiekmann requested a review from indietyp August 21, 2026 13:07
Comment thread libs/@local/graph/authentication/src/delegation.rs Fixed
Comment thread libs/@local/graph/authentication/src/delegation.rs Fixed
@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 $$15.2 \mathrm{ms} \pm 220 \mathrm{μs}\left({\color{gray}2.21 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.00 \mathrm{ms} \pm 8.24 \mathrm{μs}\left({\color{gray}0.330 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1002 $$6.99 \mathrm{ms} \pm 48.9 \mathrm{μs}\left({\color{gray}1.14 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$24.6 \mathrm{ms} \pm 243 \mathrm{μs}\left({\color{gray}-0.120 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$8.96 \mathrm{ms} \pm 75.5 \mathrm{μs}\left({\color{gray}-1.758 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1527 $$13.8 \mathrm{ms} \pm 129 \mathrm{μs}\left({\color{gray}-1.123 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$16.0 \mathrm{ms} \pm 105 \mathrm{μs}\left({\color{gray}0.981 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.18 \mathrm{ms} \pm 10.2 \mathrm{μs}\left({\color{gray}-1.060 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$7.53 \mathrm{ms} \pm 52.1 \mathrm{μs}\left({\color{gray}-0.749 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_medium

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 102 $$2.18 \mathrm{ms} \pm 23.0 \mathrm{μs}\left({\color{gray}-0.610 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$1.76 \mathrm{ms} \pm 5.44 \mathrm{μs}\left({\color{gray}-2.232 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 52 $$2.00 \mathrm{ms} \pm 10.7 \mathrm{μs}\left({\color{gray}-1.305 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$3.02 \mathrm{ms} \pm 16.6 \mathrm{μs}\left({\color{gray}0.047 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$2.16 \mathrm{ms} \pm 22.9 \mathrm{μs}\left({\color{gray}3.57 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 108 $$2.39 \mathrm{ms} \pm 19.2 \mathrm{μs}\left({\color{gray}-1.600 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$2.56 \mathrm{ms} \pm 27.7 \mathrm{μs}\left({\color{gray}1.32 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.11 \mathrm{ms} \pm 20.4 \mathrm{μs}\left({\color{gray}3.83 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$2.35 \mathrm{ms} \pm 10.4 \mathrm{μs}\left({\color{gray}-0.887 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$1.58 \mathrm{ms} \pm 6.47 \mathrm{μs}\left({\color{lightgreen}-6.342 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$1.54 \mathrm{ms} \pm 8.96 \mathrm{μs}\left({\color{gray}0.875 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 2 $$1.65 \mathrm{ms} \pm 14.5 \mathrm{μs}\left({\color{gray}1.94 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$1.77 \mathrm{ms} \pm 11.5 \mathrm{μs}\left({\color{gray}-2.743 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$1.62 \mathrm{ms} \pm 6.96 \mathrm{μs}\left({\color{gray}-4.607 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$1.76 \mathrm{ms} \pm 7.50 \mathrm{μs}\left({\color{gray}-2.883 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$1.82 \mathrm{ms} \pm 21.0 \mathrm{μs}\left({\color{gray}2.68 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$1.62 \mathrm{ms} \pm 7.21 \mathrm{μs}\left({\color{gray}-3.014 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 26 $$1.75 \mathrm{ms} \pm 7.72 \mathrm{μs}\left({\color{gray}-2.955 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$2.01 \mathrm{ms} \pm 10.9 \mathrm{μs}\left({\color{gray}-1.921 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$1.77 \mathrm{ms} \pm 9.12 \mathrm{μs}\left({\color{gray}-3.039 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 27 $$1.95 \mathrm{ms} \pm 13.3 \mathrm{μs}\left({\color{gray}-3.252 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$1.95 \mathrm{ms} \pm 13.0 \mathrm{μs}\left({\color{gray}-0.558 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$1.75 \mathrm{ms} \pm 7.09 \mathrm{μs}\left({\color{gray}-1.242 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$1.97 \mathrm{ms} \pm 11.9 \mathrm{μs}\left({\color{gray}2.61 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$25.7 \mathrm{ms} \pm 122 \mathrm{μs}\left({\color{gray}2.20 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$20.3 \mathrm{ms} \pm 124 \mathrm{μs}\left({\color{gray}-0.427 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$21.1 \mathrm{ms} \pm 88.3 \mathrm{μs}\left({\color{gray}-4.989 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$24.5 \mathrm{ms} \pm 685 \mathrm{μs}\left({\color{red}25.3 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$24.9 \mathrm{ms} \pm 264 \mathrm{μs}\left({\color{gray}-1.644 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$29.5 \mathrm{ms} \pm 291 \mathrm{μs}\left({\color{gray}1.62 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$23.5 \mathrm{ms} \pm 101 \mathrm{μs}\left({\color{gray}-1.763 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$51.1 \mathrm{ms} \pm 377 \mathrm{μs}\left({\color{gray}1.21 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$20.8 \mathrm{ms} \pm 155 \mathrm{μs}\left({\color{gray}2.33 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$156 \mathrm{ms} \pm 599 \mathrm{μs}\left({\color{lightgreen}-5.080 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$6.78 \mathrm{ms} \pm 33.4 \mathrm{μs}\left({\color{gray}-0.497 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$6.87 \mathrm{ms} \pm 42.8 \mathrm{μs}\left({\color{gray}3.42 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$6.68 \mathrm{ms} \pm 63.9 \mathrm{μs}\left({\color{gray}-0.588 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$6.84 \mathrm{ms} \pm 33.1 \mathrm{μs}\left({\color{gray}2.13 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$6.69 \mathrm{ms} \pm 33.1 \mathrm{μs}\left({\color{gray}-1.497 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$6.84 \mathrm{ms} \pm 39.6 \mathrm{μs}\left({\color{gray}3.43 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$6.95 \mathrm{ms} \pm 31.1 \mathrm{μs}\left({\color{gray}2.09 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$6.91 \mathrm{ms} \pm 40.2 \mathrm{μs}\left({\color{gray}2.33 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$6.92 \mathrm{ms} \pm 39.7 \mathrm{μs}\left({\color{gray}3.87 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$6.82 \mathrm{ms} \pm 39.6 \mathrm{μs}\left({\color{gray}-1.774 \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 $$7.27 \mathrm{ms} \pm 89.3 \mathrm{μs}\left({\color{gray}3.29 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$6.89 \mathrm{ms} \pm 29.1 \mathrm{μs}\left({\color{gray}0.273 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$7.10 \mathrm{ms} \pm 30.9 \mathrm{μs}\left({\color{gray}3.79 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$7.15 \mathrm{ms} \pm 33.7 \mathrm{μs}\left({\color{gray}3.88 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$7.13 \mathrm{ms} \pm 36.7 \mathrm{μs}\left({\color{gray}3.26 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$6.92 \mathrm{ms} \pm 32.0 \mathrm{μs}\left({\color{gray}-0.602 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$7.12 \mathrm{ms} \pm 31.4 \mathrm{μs}\left({\color{gray}1.77 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$7.12 \mathrm{ms} \pm 40.6 \mathrm{μs}\left({\color{gray}1.01 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$7.16 \mathrm{ms} \pm 32.6 \mathrm{μs}\left({\color{gray}2.16 \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 $$5.32 \mathrm{ms} \pm 30.4 \mathrm{μs}\left({\color{gray}1.97 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$34.5 \mathrm{ms} \pm 220 \mathrm{μs}\left({\color{gray}-1.218 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$66.3 \mathrm{ms} \pm 365 \mathrm{μs}\left({\color{gray}1.95 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$38.3 \mathrm{ms} \pm 328 \mathrm{μs}\left({\color{gray}-2.522 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$44.5 \mathrm{ms} \pm 365 \mathrm{μs}\left({\color{gray}-4.112 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$51.2 \mathrm{ms} \pm 341 \mathrm{μs}\left({\color{gray}-1.377 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$54.4 \mathrm{ms} \pm 386 \mathrm{μs}\left({\color{gray}1.38 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$24.6 \mathrm{ms} \pm 202 \mathrm{μs}\left({\color{gray}2.54 \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 $$41.9 \mathrm{ms} \pm 306 \mathrm{μs}\left({\color{gray}2.79 \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 $$28.0 \mathrm{ms} \pm 199 \mathrm{μs}\left({\color{gray}-0.246 \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 $$33.6 \mathrm{ms} \pm 306 \mathrm{μs}\left({\color{gray}-0.547 \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 $$33.7 \mathrm{ms} \pm 207 \mathrm{μs}\left({\color{gray}-2.598 \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 $$34.1 \mathrm{ms} \pm 231 \mathrm{μs}\left({\color{gray}-1.151 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$67.6 \mathrm{ms} \pm 457 \mathrm{μs}\left({\color{gray}-1.593 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$74.8 \mathrm{ms} \pm 283 \mathrm{μs}\left({\color{gray}-4.427 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$13.6 \mathrm{ms} \pm 163 \mathrm{μs}\left({\color{red}21.6 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$309 \mathrm{ms} \pm 962 \mathrm{μs}\left({\color{gray}-1.788 \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-graph area/apps area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) 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.

4 participants