Skip to content

SRE-868: Replace cargo:wasm-opt with prebuilt Binaryen in mise config - #9105

Merged
TimDiekmann merged 2 commits into
mainfrom
claude/sre-868-wasm-opt-prebuilt
Aug 1, 2026
Merged

TimDiekmann merged 2 commits into
mainfrom
claude/sre-868-wasm-opt-prebuilt

Conversation

@claude

@claude claude Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Ciaran Morinan, Tim Diekmann · Slack thread

🌟 What is the purpose of this PR?

Before: every Vercel frontend build spent ~6m54s — roughly 75% of the 9-minute install phase — compiling the wasm-opt crate from source. cargo-binstall can never find a prebuilt binary for it, because the crates.io wasm-opt crate (brson/wasm-opt-rs) publishes no release binaries; the real prebuilt wasm-opt binaries live in WebAssembly/binaryen releases.

After: wasm-opt comes from the prebuilt Binaryen version_131 release binaries on every platform — Vercel installs, CI, and the linux/arm64 Docker image builds (version_131 is the first Binaryen release that ships an aarch64-linux asset). Downloads take seconds, and cargo:wasm-opt is removed entirely: one tool, one version, everywhere.

How: "github:WebAssembly/binaryen" = "version_131" uses mise's github backend to install release assets directly. The aqua backend was considered first (its registry converts Binaryen's version_131-style tags, which keeps renovate updates working, per Bilal) — but the aqua registry constrains binaryen ≥ 108 to supported_envs: [darwin, amd64] and has no arm64→aarch64 asset-name mapping for linux, so aqua:WebAssembly/binaryen fails on linux/arm64 at any version and can't serve the arm64 Docker builds. An upstream aqua-registry PR adding linux/arm64 support would allow switching back later.

The mise.lock entries are hand-authored for all four platforms (linux-x64, linux-arm64, macos-arm64, macos-x64 — version_131 publishes assets for all of them). Checksums were taken from the sha256 digests GitHub displays on the release page and cross-checked against the .sha256 companion assets (they match for all four). The tarball's nested binaryen-version_131/bin/ layout is handled by mise's automatic strip_components + bin-directory detection, so wasm-opt lands on PATH via mise shims and wasm-pack finds it as before.

🔗 Related links

🔍 What does this change?

  • .config/mise/config.toml: replaces both "aqua:WebAssembly/binaryen" = "version_116" and "cargo:wasm-opt" = "0.116.1" with a single "github:WebAssembly/binaryen" = "version_131"
  • .config/mise/mise.lock: removes the cargo:wasm-opt and aqua Binaryen entries; adds github:WebAssembly/binaryen entries for linux-x64, linux-arm64, macos-arm64, and macos-x64 (URL + sha256 each)
  • apps/{hash-api,hash-frontend,hash-ai-worker-ts,hash-integration-worker}/docker/Dockerfile: swap cargo:wasm-opt → github:WebAssembly/binaryen in the mise install --locked tool list (these images build for linux/arm64, now covered by the aarch64-linux asset)
  • apps/hash-frontend/vercel-install.sh and apps/petrinaut-website/vercel-install.sh: swap aqua:WebAssembly/binaryen → github:WebAssembly/binaryen

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

  • Version jump 116 → 131: the builds previously used binaryen 116 (crate 0.116.1); they now use binaryen 131. wasm-pack invokes wasm-opt identically, but the optimizer itself is 15 releases newer.
  • Renovate: the github backend tracks release tags verbatim (version_131), unlike the aqua registry's tag conversion — the renovate mise manager may need a check that it picks up version_... tags for this tool; if not, updates are a one-line manual bump.
  • The lock entries have no url_api asset-id fields (api.github.com for WebAssembly/binaryen is unreachable from the sandbox this was authored in). mise lock on a dev machine would normalize the entries if wanted — CI's mise install --locked will tell if the hand-authored form is insufficient.
  • Dev machines running a full mise install will download the Binaryen tarball (~86 MB on linux-x64, ~7 MB on macOS).

🐾 Next steps

  • Tim floated removing the "ancient wasm-setup for the type system" entirely in the Slack thread — if that lands, github:WebAssembly/binaryen and cargo:wasm-pack can be dropped altogether.
  • Optional: upstream an aqua-registry PR adding linux/arm64 (aarch64 replacement) support for binaryen ≥ 131, then switch back to aqua: for registry-managed renovate updates.

🛡 What tests cover this?

  • CI runs mise install --env ci --jobs 1 --locked on linux-x64, which installs the tool from the locked URL and verifies its checksum.
  • The four service Docker image builds run mise install --locked … github:WebAssembly/binaryen on linux/arm64, exercising the aarch64-linux lock entry.

❓ How to test this?

  1. Check the Vercel preview builds on this PR: the install phase should drop from ~9 min to ~2 min (no more cargo:wasm-opt compile).
  2. In the build log, github:WebAssembly/binaryen should install in seconds and wasm-pack builds should still find wasm-opt.
  3. Trigger a service Docker image build: the arm64 build should install Binaryen from the aarch64-linux asset instead of compiling the crate.

@vercel

vercel Bot commented Jul 27, 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 1, 2026 6:54pm
hashdotdesign-tokens Ready Ready Preview Aug 1, 2026 6:54pm
petrinaut Ready Ready Preview Aug 1, 2026 6:54pm

@github-actions github-actions Bot added area/apps > hash* Affects HASH (a `hash-*` app) type/eng > frontend Owned by the @frontend team area/apps labels Jul 27, 2026
@vercel
vercel Bot temporarily deployed to Preview – hashdotdesign-tokens July 27, 2026 12:26 Inactive
@vercel
vercel Bot temporarily deployed to Preview – petrinaut July 27, 2026 12:28 Inactive
@github-actions github-actions Bot added area/apps > hash-api Affects the HASH API (app) type/eng > backend Owned by the @backend team labels Jul 27, 2026
@vercel
vercel Bot temporarily deployed to Preview – hashdotdesign-tokens July 27, 2026 12:47 Inactive
@vercel
vercel Bot temporarily deployed to Preview – petrinaut July 27, 2026 12:50 Inactive
@claude
claude Bot force-pushed the claude/sre-868-wasm-opt-prebuilt branch from bfb4f7a to 84cff8d Compare August 1, 2026 15:22
@vercel
vercel Bot temporarily deployed to Preview – hashdotdesign-tokens August 1, 2026 15:24 Inactive
@codecov

codecov Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.58%. Comparing base (af5e3eb) to head (51f1224).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9105   +/-   ##
=======================================
  Coverage   59.58%   59.58%           
=======================================
  Files        1410     1410           
  Lines      137980   137980           
  Branches     6494     6494           
=======================================
+ Hits        82210    82212    +2     
+ Misses      54734    54732    -2     
  Partials     1036     1036           
Flag Coverage Δ
apps.hash-ai-worker-ts 1.99% <ø> (ø)
apps.hash-api 12.57% <ø> (ø)
blockprotocol.type-system 40.84% <ø> (ø)
local.claude-hooks 0.00% <ø> (ø)
local.harpc-client 51.49% <ø> (ø)
local.hash-backend-utils 2.55% <ø> (ø)
local.hash-graph-sdk 10.02% <ø> (ø)
local.hash-isomorphic-utils 12.25% <ø> (ø)
rust.antsi 0.00% <ø> (ø)
rust.error-stack 90.89% <ø> (ø)
rust.harpc-codec 84.70% <ø> (ø)
rust.harpc-net 96.23% <ø> (+0.03%) ⬆️
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 7.37% <ø> (ø)
rust.hash-graph-authorization 62.59% <ø> (ø)
rust.hash-graph-embeddings 91.88% <ø> (ø)
rust.hash-graph-postgres-store 29.66% <ø> (ø)
rust.hash-graph-store 42.16% <ø> (ø)
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.

@vercel
vercel Bot temporarily deployed to Preview – petrinaut August 1, 2026 15:27 Inactive
@codspeed

codspeed Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 18.18%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
✅ 96 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
⚡ bit_matrix/dense/iter_row[64] 170 ns 140.8 ns +20.71%
⚡ bit_matrix/dense/iter_row[200] 215 ns 185.8 ns +15.7%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing claude/sre-868-wasm-opt-prebuilt (51f1224) with main (9b60522)

Open in CodSpeed

claude added 2 commits August 1, 2026 18:39
…alls

Every Vercel build spent ~6m54s compiling the wasm-opt crate from source
because cargo-binstall finds no prebuilt binary for it. Install wasm-opt
from the WebAssembly/binaryen release binaries (aqua backend) instead,
keeping version parity (crate 0.116.1 = binaryen version_116).

The Docker images keep cargo:wasm-opt: they build natively for
linux/arm64, where Binaryen publishes no release asset.
Use mise's github backend to install prebuilt Binaryen release binaries
on every platform, including linux/arm64 (aarch64-linux asset shipped
since version_131). This removes the cargo:wasm-opt crate build - the
last consumer was the Docker images - so wasm-opt is now one tool at
one version everywhere: CI, Vercel installs, and Docker image builds.

The aqua backend was considered (registry tags are renovate-friendly)
but the aqua registry does not support linux/arm64 for binaryen >= 108,
which the arm64 Docker builds need.

Lock entries are hand-authored from the release page digests and the
.sha256 companion assets (verified to match).
@claude
claude Bot force-pushed the claude/sre-868-wasm-opt-prebuilt branch from 84cff8d to 51f1224 Compare August 1, 2026 18:40
@vercel
vercel Bot temporarily deployed to Preview – hashdotdesign-tokens August 1, 2026 18:42 Inactive
@vercel
vercel Bot temporarily deployed to Preview – petrinaut August 1, 2026 18:45 Inactive
@github-actions

github-actions Bot commented Aug 1, 2026

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 216 \mathrm{μs}\left({\color{gray}1.26 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.50 \mathrm{ms} \pm 20.0 \mathrm{μs}\left({\color{gray}-0.337 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1002 $$13.6 \mathrm{ms} \pm 104 \mathrm{μs}\left({\color{gray}0.382 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$44.6 \mathrm{ms} \pm 401 \mathrm{μs}\left({\color{gray}-0.591 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$15.1 \mathrm{ms} \pm 143 \mathrm{μs}\left({\color{gray}2.29 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1527 $$25.3 \mathrm{ms} \pm 200 \mathrm{μs}\left({\color{gray}0.505 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$29.2 \mathrm{ms} \pm 221 \mathrm{μs}\left({\color{gray}-0.289 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.81 \mathrm{ms} \pm 20.3 \mathrm{μs}\left({\color{gray}-1.274 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$14.7 \mathrm{ms} \pm 116 \mathrm{μs}\left({\color{gray}0.589 \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 29.1 \mathrm{μs}\left({\color{gray}-0.048 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.08 \mathrm{ms} \pm 16.9 \mathrm{μs}\left({\color{gray}-0.053 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 52 $$3.49 \mathrm{ms} \pm 21.2 \mathrm{μs}\left({\color{gray}0.398 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.30 \mathrm{ms} \pm 33.7 \mathrm{μs}\left({\color{gray}-0.465 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.59 \mathrm{ms} \pm 17.7 \mathrm{μs}\left({\color{gray}-0.136 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 108 $$4.25 \mathrm{ms} \pm 27.9 \mathrm{μs}\left({\color{gray}1.15 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.55 \mathrm{ms} \pm 41.6 \mathrm{μs}\left({\color{gray}0.988 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.56 \mathrm{ms} \pm 25.2 \mathrm{μs}\left({\color{gray}1.17 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.17 \mathrm{ms} \pm 23.1 \mathrm{μs}\left({\color{gray}-0.154 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.76 \mathrm{ms} \pm 18.0 \mathrm{μs}\left({\color{gray}0.020 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.60 \mathrm{ms} \pm 16.8 \mathrm{μs}\left({\color{gray}0.969 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 2 $$2.71 \mathrm{ms} \pm 17.2 \mathrm{μs}\left({\color{gray}-0.614 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$2.99 \mathrm{ms} \pm 15.2 \mathrm{μs}\left({\color{gray}0.368 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.82 \mathrm{ms} \pm 18.8 \mathrm{μs}\left({\color{gray}1.50 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$2.98 \mathrm{ms} \pm 14.2 \mathrm{μs}\left({\color{gray}-0.098 \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 24.1 \mathrm{μs}\left({\color{gray}0.883 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.83 \mathrm{ms} \pm 15.9 \mathrm{μs}\left({\color{gray}-0.217 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 26 $$3.09 \mathrm{ms} \pm 17.9 \mathrm{μs}\left({\color{gray}0.259 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.55 \mathrm{ms} \pm 23.6 \mathrm{μs}\left({\color{gray}0.843 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.07 \mathrm{ms} \pm 17.3 \mathrm{μs}\left({\color{gray}0.538 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 27 $$3.37 \mathrm{ms} \pm 19.9 \mathrm{μs}\left({\color{gray}0.278 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.47 \mathrm{ms} \pm 20.0 \mathrm{μs}\left({\color{gray}-0.014 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.05 \mathrm{ms} \pm 21.3 \mathrm{μs}\left({\color{gray}0.454 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.45 \mathrm{ms} \pm 27.7 \mathrm{μs}\left({\color{gray}0.790 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$44.2 \mathrm{ms} \pm 220 \mathrm{μs}\left({\color{gray}0.196 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$34.9 \mathrm{ms} \pm 227 \mathrm{μs}\left({\color{gray}0.512 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$37.9 \mathrm{ms} \pm 196 \mathrm{μs}\left({\color{gray}1.31 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$33.6 \mathrm{ms} \pm 196 \mathrm{μs}\left({\color{lightgreen}-27.080 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$44.9 \mathrm{ms} \pm 327 \mathrm{μs}\left({\color{gray}1.52 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$51.7 \mathrm{ms} \pm 385 \mathrm{μs}\left({\color{gray}0.450 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$42.3 \mathrm{ms} \pm 272 \mathrm{μs}\left({\color{gray}0.339 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$90.3 \mathrm{ms} \pm 595 \mathrm{μs}\left({\color{gray}-0.692 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$35.5 \mathrm{ms} \pm 202 \mathrm{μs}\left({\color{lightgreen}-11.633 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$282 \mathrm{ms} \pm 923 \mathrm{μs}\left({\color{gray}-0.632 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$11.5 \mathrm{ms} \pm 62.1 \mathrm{μs}\left({\color{gray}-0.339 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$11.7 \mathrm{ms} \pm 80.0 \mathrm{μs}\left({\color{gray}0.527 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$11.7 \mathrm{ms} \pm 76.8 \mathrm{μs}\left({\color{gray}0.060 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$11.5 \mathrm{ms} \pm 67.1 \mathrm{μs}\left({\color{gray}-0.953 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$11.7 \mathrm{ms} \pm 69.1 \mathrm{μs}\left({\color{gray}-0.061 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$11.5 \mathrm{ms} \pm 75.2 \mathrm{μs}\left({\color{gray}-0.621 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$11.7 \mathrm{ms} \pm 78.2 \mathrm{μs}\left({\color{gray}0.192 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$11.7 \mathrm{ms} \pm 63.4 \mathrm{μs}\left({\color{gray}0.169 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$11.9 \mathrm{ms} \pm 77.6 \mathrm{μs}\left({\color{gray}0.340 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$12.0 \mathrm{ms} \pm 72.0 \mathrm{μs}\left({\color{gray}0.526 \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.2 \mathrm{ms} \pm 82.3 \mathrm{μs}\left({\color{gray}-1.160 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$12.2 \mathrm{ms} \pm 80.5 \mathrm{μs}\left({\color{gray}0.462 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$12.2 \mathrm{ms} \pm 87.0 \mathrm{μs}\left({\color{gray}0.164 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$11.9 \mathrm{ms} \pm 70.8 \mathrm{μs}\left({\color{gray}-2.711 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$12.0 \mathrm{ms} \pm 67.0 \mathrm{μs}\left({\color{gray}-0.846 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$12.1 \mathrm{ms} \pm 86.4 \mathrm{μs}\left({\color{gray}-1.832 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$12.2 \mathrm{ms} \pm 79.9 \mathrm{μs}\left({\color{gray}-0.357 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$12.0 \mathrm{ms} \pm 71.6 \mathrm{μs}\left({\color{gray}-0.909 \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 66.3 \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.92 \mathrm{ms} \pm 51.7 \mathrm{μs}\left({\color{gray}-0.752 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$58.9 \mathrm{ms} \pm 456 \mathrm{μs}\left({\color{gray}-2.745 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$113 \mathrm{ms} \pm 613 \mathrm{μs}\left({\color{gray}-2.027 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$66.4 \mathrm{ms} \pm 510 \mathrm{μs}\left({\color{gray}-2.739 \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.1 \mathrm{ms} \pm 555 \mathrm{μs}\left({\color{gray}-1.923 \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.6 \mathrm{ms} \pm 587 \mathrm{μs}\left({\color{gray}-1.231 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$91.6 \mathrm{ms} \pm 630 \mathrm{μs}\left({\color{gray}-1.417 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$45.0 \mathrm{ms} \pm 285 \mathrm{μs}\left({\color{gray}-0.649 \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 $$74.2 \mathrm{ms} \pm 423 \mathrm{μs}\left({\color{gray}-0.180 \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 $$51.1 \mathrm{ms} \pm 326 \mathrm{μs}\left({\color{gray}-1.622 \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 $$60.8 \mathrm{ms} \pm 357 \mathrm{μs}\left({\color{gray}-1.071 \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 $$63.5 \mathrm{ms} \pm 385 \mathrm{μs}\left({\color{gray}-0.080 \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 $$63.0 \mathrm{ms} \pm 317 \mathrm{μs}\left({\color{gray}-1.567 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$116 \mathrm{ms} \pm 781 \mathrm{μs}\left({\color{gray}-2.733 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$128 \mathrm{ms} \pm 585 \mathrm{μs}\left({\color{gray}-1.340 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$19.9 \mathrm{ms} \pm 125 \mathrm{μs}\left({\color{gray}-2.011 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$541 \mathrm{ms} \pm 1.58 \mathrm{ms}\left({\color{gray}-0.764 \mathrm{\%}}\right) $$ Flame Graph

@TimDiekmann
TimDiekmann marked this pull request as ready for review August 1, 2026 22:30
Copilot AI review requested due to automatic review settings August 1, 2026 22:30
@cursor

cursor Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
Tooling-only change to how wasm-opt is installed; low runtime risk aside from possible WASM output differences from the Binaryen version bump.

Overview
Replaces source-built wasm-opt with prebuilt Binaryen so Vercel and Docker installs no longer spend several minutes compiling the cargo:wasm-opt crate.

Mise now pins github:WebAssembly/binaryen at version_131, with locked download URLs and checksums for linux-x64, linux-arm64, macos-x64, and macos-arm64 in mise.lock. cargo:wasm-opt is removed from the shared mise config.

Dockerfiles (hash-api, hash-frontend, hash-ai-worker-ts, hash-integration-worker) and Vercel install scripts (hash-frontend, petrinaut-website) swap cargo:wasm-opt (or the prior aqua binaryen reference) for github:WebAssembly/binaryen in their mise install --locked tool lists so wasm-pack still gets wasm-opt on PATH.

Note: optimizer version moves from the old ~116 line to Binaryen 131, which may slightly change WASM optimization output.

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

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

Replaces source-built wasm-opt with prebuilt Binaryen assets to reduce installation time across CI, Vercel, and Docker builds.

Changes:

  • Pins Binaryen version_131 through mise’s GitHub backend.
  • Adds checksummed lock entries for Linux and macOS architectures.
  • Updates Vercel and Docker installation commands.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
.config/mise/config.toml Configures prebuilt Binaryen.
.config/mise/mise.lock Locks platform-specific Binaryen assets.
apps/hash-api/docker/Dockerfile Installs Binaryen in API builds.
apps/hash-frontend/docker/Dockerfile Installs Binaryen in frontend builds.
apps/hash-ai-worker-ts/docker/Dockerfile Installs Binaryen in AI worker builds.
apps/hash-integration-worker/docker/Dockerfile Installs Binaryen in integration worker builds.
apps/hash-frontend/vercel-install.sh Uses Binaryen during Vercel installation.
apps/petrinaut-website/vercel-install.sh Uses Binaryen during Vercel installation.

@TimDiekmann
TimDiekmann added this pull request to the merge queue Aug 1, 2026
Merged via the queue into main with commit 60caa1d Aug 1, 2026
190 checks passed
@TimDiekmann
TimDiekmann deleted the claude/sre-868-wasm-opt-prebuilt branch August 1, 2026 22:53

This branch was successfully deployed

1 active and 2 inactive deployments
Preview – hash — 51f1224d Deployed Aug 1, 2026 by vercel[bot]
Preview – petrinaut — 51f1224d Deployed Aug 1, 2026 by vercel[bot]
Preview – hashdotdesign-tokens — 51f1224d Deployed Aug 1, 2026 by vercel[bot]
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 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