Skip to content

FE-1322: Add a Starlight site that renders the docs bundle - #9206

Merged
kube merged 1 commit into
mainfrom
cf/fe-1322-arch-docs-site
Aug 14, 2026
Merged

FE-1322: Add a Starlight site that renders the docs bundle#9206
kube merged 1 commit into
mainfrom
cf/fe-1322-arch-docs-site

Conversation

@kube

@kube kube commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

🌟 What is the purpose of this PR?

Adds an Astro and Starlight site that renders the docs bundle from #9204 and #9205. It is the first thing that reads the bundle, so it is also the first check that the bundle can be rendered by a host that did not produce it.

The site holds no content. Everything it serves is copied from bundle/, and src/content/ is git-ignored.

Third of three PRs, on top of #9205.

flowchart LR
  A["doc:architecture"] --> B["sync:bundle"]
  B --> C["build / lint:tsc / dev"]
Loading

🔍 What does this change?

sync:bundle only copies files. The chain above resolves entirely in the task graph, so Turborepo orders and reports each step. Running the sync with no bundle present exits 1 and names the Turborepo command to run, rather than failing part-way through a copy.

trailingSlash: "never" is required rather than a preference. Links between generated pages are relative and assume slugs map to URLs with no trailing slash. A host serving /architecture/core/simulation/ has to rewrite them, and manifest.json lists every slug for that purpose.

The sidebar is built from manifest.json rather than Starlight frontmatter, so the nesting comes from the bundle rather than from anything specific to this site.

🔗 Related links

  • FE-1322
  • FE-1157, moving Petrinaut docs to hash.dev/docs/petrinaut. Worth settling before choosing where this deploys, so there is one URL rather than two.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

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

Adds a private app. Nothing is published.

📜 Does this require a change to the docs?

  • require changes to docs which are made as part of this PR

AGENTS.md gains the command for browsing the docs, with a note that it has to run through Turborepo, since the package script alone skips regenerating the bundle.

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

  • affected the execution graph, and the turbo.json's have been updated to reflect this

@apps/petrinaut-docs#{build,lint:tsc,dev}#sync:bundle@local/petrinaut-arch-docs#doc:architecture.

⚠️ Known issues

  • Most of this diff is yarn.lock. Astro, Starlight and sharp add 311 packages. That is why it is a separate PR: none of it affects whether the architecture model is correct.
  • Nothing is deployed yet. d2 will need to be added to the Vercel install step, and should be settled against FE-1157 first.
  • d2 is probed, not required. If it is missing, the build warns, leaves out the images, and succeeds. A CI runner without d2 would produce a site with no diagrams and still pass.
  • starlight-llms-txt was dropped. It renders MDX in a container with no React renderer, and its exclude option is accepted but never passed to the /llms-full.txt route. The site serves the bundle's own architecture.md and architecture.json instead.
  • $x_{t}$ in MDX fails the build here, and on any host without remark-math, because {…} parses as a JSX expression. Authored pages have to avoid it.

🐾 Next steps

  • Choose where this deploys, against FE-1157.

🛡 What tests cover this?

No unit tests, since the app holds no logic. It is covered by lint:tsc, which runs astro check over the synced content and the diagram components, and by build. Both fail if the bundle cannot be rendered.

❓ How to test this?

turbo run dev --filter @apps/petrinaut-docs   # http://localhost:4321

Open Architecture for the overview, then any layer, including a leaf such as core.clipboard. Each page opens with a diagram of what it imports and what imports it.

To watch the task graph order the work, delete the bundle first:

rm -rf libs/@local/petrinaut-arch-docs/bundle
turbo run build --filter @apps/petrinaut-docs

To check that formatting and generation do not fight over the bundle's files:

yarn fix:format && yarn workspace @local/petrinaut-arch-docs doc:architecture
yarn lint:format   # 0

@vercel

vercel Bot commented Aug 12, 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 14, 2026 10:28am
hashdotdesign-tokens Ready Ready Preview Aug 14, 2026 10:28am
petrinaut Ready Ready Preview Aug 14, 2026 10:28am

@codspeed-hq

codspeed-hq Bot commented Aug 12, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 98 untouched benchmarks


Comparing cf/fe-1322-arch-docs-site (083e453) with main (e28fe6f)1

Open in CodSpeed

Footnotes

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

@cursor

cursor Bot commented Aug 12, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Private documentation app and build wiring only; no changes to product runtime, auth, or data paths beyond a large but isolated dependency footprint.

Overview
Adds @apps/petrinaut-docs, a private Astro/Starlight app that copies the @local/petrinaut-arch-docs bundle into src/content/ and public/ (git-ignored) instead of authoring pages locally. sync:bundle only copies; Turborepo wires doc:architecturesync:bundlebuild / lint:tsc / dev so concurrent tasks do not race on the same directories.

astro.config.mjs builds the sidebar from manifest.json, sets trailingSlash: "never" and build.format: "file" to match the bundle’s relative links, redirects //architecture when there is no authored home page, and serves the bundle’s architecture.md / architecture.json rather than a separate llms plugin. AGENTS.md documents browsing via turbo run dev --filter @apps/petrinaut-docs. yarn.config.cjs allows TypeScript as an unscripted devDependency for astro check; installConfig.hoistingLimits isolates Astro’s cookie dependency from the monorepo hoist.

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

Comment thread apps/petrinaut-docs/scripts/sync-bundle.mjs Outdated

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

Adds a private Astro/Starlight app for rendering the generated Petrinaut architecture bundle.

Changes:

  • Adds the Starlight site, navigation, branding, and bundle synchronization.
  • Connects generation, synchronization, checking, development, and builds through Turborepo.
  • Documents usage and adds required dependencies.

Reviewed changes

Copilot reviewed 13 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
AGENTS.md Documents browsing the architecture site.
yarn.config.cjs Allows the app’s TypeScript dependency.
yarn.lock Locks the new Astro/Starlight dependencies.
apps/petrinaut-docs/.gitignore Ignores generated and build output.
apps/petrinaut-docs/LICENSE-APACHE.md Adds the Apache license.
apps/petrinaut-docs/LICENSE-MIT.md Adds the MIT license.
apps/petrinaut-docs/LICENSE.md Declares dual licensing.
apps/petrinaut-docs/README.md Documents operation and bundle contracts.
apps/petrinaut-docs/astro.config.mjs Configures Starlight and manifest-driven navigation.
apps/petrinaut-docs/package.json Defines app scripts and dependencies.
apps/petrinaut-docs/public/favicon.ico Adds the site favicon.
apps/petrinaut-docs/scripts/sync-bundle.mjs Copies bundle content into the app.
apps/petrinaut-docs/src/assets/petrinaut-helmet.png Adds site branding.
apps/petrinaut-docs/src/content.config.mjs Configures the Starlight docs collection.
apps/petrinaut-docs/tsconfig.json Enables strict Astro type checking.
apps/petrinaut-docs/turbo.json Connects bundle generation to app tasks.

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

Comment thread apps/petrinaut-docs/astro.config.mjs Outdated
Comment thread apps/petrinaut-docs/scripts/sync-bundle.mjs Outdated
Copilot AI review requested due to automatic review settings August 12, 2026 21:19
@kube
kube force-pushed the cf/fe-1322-arch-docs-site branch from c34b7be to 61ef474 Compare August 12, 2026 21:19
@kube
kube deployed to pull-request August 12, 2026 21:19 — with GitHub Actions Active
@kube
kube deployed to pull-request August 12, 2026 21:19 — 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

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

Suppressed comments (2)

apps/petrinaut-docs/scripts/sync-bundle.mjs:55

  • The generator deliberately supports an absent authored-content directory, but in that state it removes bundle/components and emits no replacement (libs/@local/petrinaut-arch-docs/src/cli.ts:69-76). This unconditional copy therefore makes the documented “no authored content” build fail with ENOENT. Treat a missing components directory as an empty optional input (while still propagating other filesystem errors).
// Diagram components imported by authored pages. Copied as siblings of `docs/`
// because that is the layout the bundle's own relative imports assume.
await cp(`${bundleRoot}components`, `${contentRoot}components`, {
  recursive: true,
});

apps/petrinaut-docs/astro.config.mjs:70

  • The generator accepts authored pages recursively and preserves their directory in the slug (libs/@local/petrinaut-arch-docs/src/content.ts:142,206). For a valid page such as content/guides/setup.mdx without a separate guides page, this traversal never reaches guides/setup: the root call only selects pages whose parent is empty, and recursion only starts from actual page slugs. The page is consequently missing from navigation. Build groups for intermediate slug segments, or explicitly flatten parentless authored paths.
  const itemsUnder = (parentSlug) =>
    pages
      .filter((page) => parentOf(page.slug) === parentSlug)

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 13 out of 16 changed files in this pull request and generated no new comments.

Suppressed comments (2)

apps/petrinaut-docs/astro.config.mjs:121

  • The PR says the deployment location is still to be chosen, but Astro's site setting declares the final deployed origin and is used for generated canonical URLs. A build hosted at the documented demo.petrinaut.org/docs candidate would therefore advertise petrinaut-docs.hash.dev URLs. Remove this setting until deployment is settled, or derive site (and any base) from deployment-specific configuration.
  site: "https://petrinaut-docs.hash.dev",

apps/petrinaut-docs/astro.config.mjs:23

  • The navigation reads manifest.json directly from the generator bundle while the pages come from the copied src/content snapshot. After regenerating the bundle without running sync:bundle, the direct dev command documented in README.md:14-15 combines a new sidebar with old pages; deleting the bundle also makes that command fail instead of rendering the last synced content. Copy the manifest during sync:bundle and read that copied file here so the sidebar and pages always come from the same snapshot.
const manifestPath = fileURLToPath(
  new URL(
    "../../libs/@local/petrinaut-arch-docs/bundle/manifest.json",
    import.meta.url,
  ),

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 13 out of 16 changed files in this pull request and generated no new comments.

Suppressed comments (1)

apps/petrinaut-docs/astro.config.mjs:140

  • The manifest order is lost when sidebar entries cross group boundaries. itemsUnder always emits direct pages before implied groups here, and the top-level result similarly appends the Architecture group after every authored item. For example, the generator explicitly supports an authored page with sidebar_order: 2000 sorting after generated reference pages (libs/@local/petrinaut-arch-docs/src/emit/mdx.ts:31-36), but this sidebar will still place it before Architecture; a nested guide with a lower order than a direct sibling is likewise placed after that sibling. Carry each group’s effective order into the constructed sidebar entries and sort all siblings together before returning them.
      return [

@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 0230207. Configure here.

Comment thread apps/petrinaut-docs/astro.config.mjs Outdated

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 13 out of 16 changed files in this pull request and generated no new comments.

Suppressed comments (1)

apps/petrinaut-docs/astro.config.mjs:162

  • Appending every implied directory after all direct pages drops the manifest ordering. For example, the valid pages guides/setup with order 1 and intro with order 10 produce “Intro” before the synthesized “Guides” group, despite order specifying the reverse. Merge direct pages and implied groups into one ordered list (using the minimum descendant order for an implied group, with slug as the tie-breaker) before mapping them to sidebar items, and add this case as a regression test.
        ...implied.map((slug) => ({

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 14 out of 17 changed files in this pull request and generated no new comments.

Suppressed comments (1)

apps/petrinaut-docs/astro.config.mjs:44

  • buildSidebar contains the app's core navigation logic, but no test asserts its output; astro build only proves the pages render, not that they are reachable. For example, the comments document a previous regression where guides/setup built successfully while being omitted from the sidebar. Please extract this pure function and add focused tests for nested implied groups, attached guides, and the authored-index fallback so those regressions fail CI.
const buildSidebar = () => {

The bundle is meant to be portable — the same artefact rendering locally, in
hash.dev, or read as plain text by an agent. Nothing proved that. A generator
with exactly one consumer, and no consumer at all in this case, drifts toward
whatever that consumer happens to need.

This is that consumer, and it deliberately owns no content. Everything it
serves is synced from `bundle/`, and `src/content/` is git-ignored, so anything
it renders had to survive the trip through a bundle a different host could
equally well read. When something cannot be expressed portably, the site is
where that shows up as a failure rather than as a quiet coupling.

`sync:bundle` only copies. It used to spawn the generator itself with
`spawnSync`, which put a cross-package build step inside a shell call
Turborepo could not see, order or report on. The whole chain now resolves in
the task graph:

  build / lint:tsc / dev → sync:bundle → @local/petrinaut-arch-docs#doc:architecture

Running the sync without a bundle exits 1 naming the Turborepo command to use,
rather than failing partway through a copy.

`trailingSlash: "never"` is required, not stylistic: links between generated
pages are relative and assume slugs map to URLs without a trailing slash. A
host serving `/architecture/core/simulation/` has to rewrite them, and
`manifest.json` carries every slug for exactly that.

This is the largest part of the change by line count and almost all of it is
`yarn.lock` — Astro, Starlight and sharp bring 311 packages. It is separated
from the generator for that reason: none of it needs reviewing to judge whether
the architecture model is right, and none of it ships to a URL yet. Where the
site is deployed is still open, and worth settling against FE-1157 so there is
one canonical location.

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 17 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (1)

apps/petrinaut-docs/astro.config.mjs:44

  • buildSidebar is substantial custom navigation logic, but the only stated checks (astro check and build) verify that the current manifest renders, not that every manifest page is present and correctly nested. For example, removing the implied-directory recursion would still build successfully while making a valid guides/advanced/setup page unreachable from the sidebar. Please extract this function into an importable module and add focused tests for generated/authored separation, attached guides, missing parent pages, deep implied directories, and ordering.
const buildSidebar = () => {

@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.2 \mathrm{ms} \pm 265 \mathrm{μs}\left({\color{gray}1.03 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.53 \mathrm{ms} \pm 17.4 \mathrm{μs}\left({\color{gray}2.01 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1002 $$12.9 \mathrm{ms} \pm 128 \mathrm{μs}\left({\color{gray}-1.931 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$44.0 \mathrm{ms} \pm 443 \mathrm{μs}\left({\color{gray}-0.607 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$16.3 \mathrm{ms} \pm 197 \mathrm{μs}\left({\color{red}8.99 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1527 $$25.2 \mathrm{ms} \pm 216 \mathrm{μs}\left({\color{gray}0.495 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$28.6 \mathrm{ms} \pm 244 \mathrm{μs}\left({\color{gray}-2.606 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.95 \mathrm{ms} \pm 26.0 \mathrm{μs}\left({\color{red}5.67 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$14.6 \mathrm{ms} \pm 120 \mathrm{μs}\left({\color{gray}1.92 \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 25.2 \mathrm{μs}\left({\color{gray}-0.270 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.01 \mathrm{ms} \pm 19.7 \mathrm{μs}\left({\color{gray}-0.223 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 52 $$3.40 \mathrm{ms} \pm 22.3 \mathrm{μs}\left({\color{gray}1.29 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.20 \mathrm{ms} \pm 34.9 \mathrm{μs}\left({\color{gray}-2.177 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.59 \mathrm{ms} \pm 26.6 \mathrm{μs}\left({\color{lightgreen}-6.062 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 108 $$4.16 \mathrm{ms} \pm 26.1 \mathrm{μs}\left({\color{gray}-2.541 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.53 \mathrm{ms} \pm 41.3 \mathrm{μs}\left({\color{gray}-0.269 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.51 \mathrm{ms} \pm 19.8 \mathrm{μs}\left({\color{gray}1.97 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.16 \mathrm{ms} \pm 37.7 \mathrm{μs}\left({\color{gray}0.953 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.73 \mathrm{ms} \pm 19.5 \mathrm{μs}\left({\color{gray}-1.729 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.58 \mathrm{ms} \pm 16.5 \mathrm{μs}\left({\color{gray}0.672 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 2 $$2.68 \mathrm{ms} \pm 16.2 \mathrm{μs}\left({\color{gray}0.425 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$2.98 \mathrm{ms} \pm 17.5 \mathrm{μs}\left({\color{gray}-3.925 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.74 \mathrm{ms} \pm 15.9 \mathrm{μs}\left({\color{gray}-2.049 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$2.97 \mathrm{ms} \pm 16.1 \mathrm{μs}\left({\color{gray}-2.862 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$3.07 \mathrm{ms} \pm 18.6 \mathrm{μs}\left({\color{gray}-0.619 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.82 \mathrm{ms} \pm 23.0 \mathrm{μs}\left({\color{gray}1.52 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 26 $$3.00 \mathrm{ms} \pm 19.8 \mathrm{μs}\left({\color{gray}-0.415 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.52 \mathrm{ms} \pm 23.6 \mathrm{μs}\left({\color{gray}1.42 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.09 \mathrm{ms} \pm 21.3 \mathrm{μs}\left({\color{gray}2.57 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 27 $$3.30 \mathrm{ms} \pm 20.7 \mathrm{μs}\left({\color{gray}-1.016 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.44 \mathrm{ms} \pm 23.9 \mathrm{μs}\left({\color{gray}0.511 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.99 \mathrm{ms} \pm 20.3 \mathrm{μs}\left({\color{gray}-1.728 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.32 \mathrm{ms} \pm 22.7 \mathrm{μs}\left({\color{gray}-2.161 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$44.8 \mathrm{ms} \pm 346 \mathrm{μs}\left({\color{gray}2.39 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$33.7 \mathrm{ms} \pm 250 \mathrm{μs}\left({\color{lightgreen}-6.848 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$37.6 \mathrm{ms} \pm 228 \mathrm{μs}\left({\color{gray}-3.089 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$32.1 \mathrm{ms} \pm 193 \mathrm{μs}\left({\color{lightgreen}-15.462 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$44.0 \mathrm{ms} \pm 289 \mathrm{μs}\left({\color{gray}-2.463 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$51.1 \mathrm{ms} \pm 417 \mathrm{μs}\left({\color{gray}-2.876 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$41.0 \mathrm{ms} \pm 291 \mathrm{μs}\left({\color{lightgreen}-7.100 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$91.3 \mathrm{ms} \pm 615 \mathrm{μs}\left({\color{lightgreen}-5.544 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$35.2 \mathrm{ms} \pm 301 \mathrm{μs}\left({\color{gray}-2.992 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$309 \mathrm{ms} \pm 1.15 \mathrm{ms}\left({\color{red}8.04 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$11.5 \mathrm{ms} \pm 104 \mathrm{μs}\left({\color{gray}2.86 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$11.5 \mathrm{ms} \pm 74.1 \mathrm{μs}\left({\color{gray}0.570 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$11.7 \mathrm{ms} \pm 71.1 \mathrm{μs}\left({\color{gray}1.58 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$11.4 \mathrm{ms} \pm 82.3 \mathrm{μs}\left({\color{gray}2.20 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$11.5 \mathrm{ms} \pm 78.6 \mathrm{μs}\left({\color{gray}-0.063 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$11.3 \mathrm{ms} \pm 73.5 \mathrm{μs}\left({\color{gray}-3.235 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$11.6 \mathrm{ms} \pm 108 \mathrm{μs}\left({\color{gray}0.866 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$11.6 \mathrm{ms} \pm 75.0 \mathrm{μs}\left({\color{gray}-1.409 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$11.5 \mathrm{ms} \pm 66.5 \mathrm{μs}\left({\color{gray}-1.739 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$11.5 \mathrm{ms} \pm 74.2 \mathrm{μs}\left({\color{gray}-1.259 \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 $$12.0 \mathrm{ms} \pm 66.7 \mathrm{μs}\left({\color{gray}1.57 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$11.9 \mathrm{ms} \pm 91.0 \mathrm{μs}\left({\color{gray}-1.142 \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 57.1 \mathrm{μs}\left({\color{lightgreen}-8.142 \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 76.2 \mathrm{μs}\left({\color{gray}-4.241 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$12.1 \mathrm{ms} \pm 104 \mathrm{μs}\left({\color{gray}2.85 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$12.0 \mathrm{ms} \pm 83.0 \mathrm{μs}\left({\color{gray}1.54 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$11.9 \mathrm{ms} \pm 91.7 \mathrm{μs}\left({\color{gray}-1.916 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$11.9 \mathrm{ms} \pm 70.2 \mathrm{μs}\left({\color{gray}-0.371 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$12.0 \mathrm{ms} \pm 81.9 \mathrm{μs}\left({\color{gray}-0.085 \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.78 \mathrm{ms} \pm 56.2 \mathrm{μs}\left({\color{gray}-4.119 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$62.1 \mathrm{ms} \pm 455 \mathrm{μs}\left({\color{gray}-3.709 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$117 \mathrm{ms} \pm 585 \mathrm{μs}\left({\color{gray}-2.466 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$68.2 \mathrm{ms} \pm 488 \mathrm{μs}\left({\color{lightgreen}-5.080 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$78.9 \mathrm{ms} \pm 537 \mathrm{μs}\left({\color{lightgreen}-5.009 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$86.4 \mathrm{ms} \pm 525 \mathrm{μs}\left({\color{lightgreen}-6.515 \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.9 \mathrm{ms} \pm 563 \mathrm{μs}\left({\color{lightgreen}-5.533 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$45.1 \mathrm{ms} \pm 276 \mathrm{μs}\left({\color{gray}-4.835 \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 $$75.2 \mathrm{ms} \pm 566 \mathrm{μs}\left({\color{gray}-0.397 \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 $$53.1 \mathrm{ms} \pm 435 \mathrm{μs}\left({\color{gray}-0.291 \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 $$61.6 \mathrm{ms} \pm 433 \mathrm{μs}\left({\color{gray}-1.753 \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 $$64.7 \mathrm{ms} \pm 616 \mathrm{μs}\left({\color{gray}-1.381 \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 $$64.1 \mathrm{ms} \pm 396 \mathrm{μs}\left({\color{gray}-0.969 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$127 \mathrm{ms} \pm 881 \mathrm{μs}\left({\color{gray}4.42 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$136 \mathrm{ms} \pm 746 \mathrm{μs}\left({\color{red}5.26 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$18.9 \mathrm{ms} \pm 115 \mathrm{μs}\left({\color{lightgreen}-7.747 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$524 \mathrm{ms} \pm 1.31 \mathrm{ms}\left({\color{gray}-0.812 \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 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) type/eng > backend Owned by the @backend team type/legal Owned by the @legal team

Development

Successfully merging this pull request may close these issues.

4 participants