Services

Performance Audit 2026 06 16


Assistance performance audit — 2026-06-16

Scope: read-only inspection of frontend/backend performance-relevant configuration, tests, and artifacts for Cloudflare-hosted surfaces. No product code was changed.

Commands run#

1
$ find apps -maxdepth 2 \( -name 'next.config.*' -o -name 'vite.config.*' -o -name 'wrangler.*' -o -name 'open-next.config.*' -o -name 'package.json' \) | sort
2
apps/academy/next.config.cjs
3
apps/academy/open-next.config.ts
4
apps/academy/package.json
5
apps/academy/wrangler.jsonc
6
apps/blog/next.config.mjs
7
apps/blog/open-next.config.ts
8
apps/blog/package.json
9
apps/blog/wrangler.jsonc
10
apps/design-system/next.config.mjs
11
apps/design-system/open-next.config.ts
12
apps/design-system/package.json
13
apps/design-system/wrangler.jsonc
14
apps/docs/next.config.mjs
15
apps/docs/open-next.config.ts
16
apps/docs/package.json
17
apps/docs/wrangler.jsonc
18
apps/manager/package.json
19
apps/manager/vite.config.ts
20
apps/manager/wrangler.toml
21
apps/ui-library/next.config.mjs
22
apps/ui-library/open-next.config.ts
23
apps/ui-library/package.json
24
apps/ui-library/wrangler.jsonc
25
apps/www/next.config.mjs
26
apps/www/next.config.test.ts
27
apps/www/package.json
28
apps/www/wrangler.toml
1
$ mise exec -- pnpm exec turbo run build --filter=www --dry=json | head -80
2
• turbo 2.9.6
3
{
4
"packages": ["www"],
5
"envMode": "strict",
6
"tasks": [{ "taskId": "www#build", "hash": "c6028c40dfb114d7", ... }]
7
}
8
Oops! Turbo has crashed.
9
A report has been written to /tmp/report-a46d59b9-c210-452e-b6e3-8c81d1872186.toml
1
$ mise exec -- pnpm exec turbo run test --filter=www --dry=json | head -80
2
• turbo 2.9.6
3
{
4
"packages": ["www"],
5
"envMode": "strict",
6
"tasks": [{ "taskId": "www#test", "hash": "f2eb12592af8432a", ... }]
7
}
8
Oops! Turbo has crashed.
9
A report has been written to /tmp/report-3278114a-f40a-43af-9c9a-34b846286dc6.toml

Cloudflare hosting model#

  • apps/www/wrangler.toml is Cloudflare Pages (pages_build_output_dir = ".next-build") with service bindings to assistance-blog and assistance-docs Workers.
  • apps/manager/wrangler.toml is Cloudflare Pages (pages_build_output_dir = "build").
  • Docs/blog/academy/design-system/ui-library use OpenNext Cloudflare Worker configs with .open-next/worker.js and assets from .open-next/assets; docs also binds NEXT_INC_CACHE_KV and D1 search in apps/docs/wrangler.jsonc.

Bundle/build risks#

  1. Broad static-generation concurrency can be resource-heavy. .mise.toml sets Turbo cache on tmpfs plus NODE_OPTIONS=--max-old-space-size=8192 and UV_THREADPOOL_SIZE=16; multiple Next configs set experimental.cpus: 16. This is optimized for a large build host, but six parallel Next builds can still be memory/CPU intensive.
  2. Build verification is currently narrow. README says runtime proof covers one representative apps/www path, not the full multi-app matrix. The documented docs/runtime/S02-RUNTIME-PROOF.md was not present in this checkout, so durable runtime evidence may have drifted or moved.
  3. Turbo dry-run currently crashes after producing partial JSON. The crash makes cache/build status introspection less reliable for quick audits even though task metadata is emitted first.
  4. Worker size pressure is known. apps/blog/next.config.mjs aliases @vercel/og out under OPEN_NEXT because its WASM files push the Worker toward the 3 MiB free limit.
  5. Type errors are bypassed in some production builds. apps/www/next.config.mjs and apps/blog/next.config.mjs set typescript.ignoreBuildErrors: true; performance builds can ship even if separate typecheck coverage is missed.

Cache/static generation behavior#

  • apps/www/next.config.mjs: output: 'export', images.unoptimized: true, optional asset CDN prefix, static Pages output. Redirects/rewrites are intentionally disabled when exporting; blog/docs routing is delegated through Pages Functions/service bindings.
  • apps/docs/next.config.mjs: output: 'standalone'; non-OpenNext builds use config/next-cache-handler.mjs with cacheMaxMemorySize: 0; OpenNext builds rely on KV incremental cache. Headers include CDN-Cache-Control via surrogateCache('/:path*', 3600).
  • apps/blog/next.config.mjs: output: 'standalone', basePath: '/blog', images.unoptimized: true, and OpenNext-specific server bundle slimming.
  • apps/manager/vite.config.ts: manual chunks split charts, router, query, UI, and React vendors for perceived performance and cacheability.
  • Backend academy catalog has a 5-minute in-memory CachedCatalog with 256-entry cap (backend/internal/academy/service/cache.go), plus SQL indexes in migrations including backend/migrations/008_performance_indexes.up.sql.

Verification coverage found#

  • Unit/integration tests exist across apps via Vitest: e.g. apps/www/__integration__/landing-page.test.tsx, apps/docs/__integration__/guide-page.test.tsx, apps/blog/test/smoke.test.ts, apps/manager/vitest.config.ts.
  • E2E scripts exist in root package.json: e2e:www, e2e:docs, e2e:academy, e2e:manager; top-level e2e only runs www and academy.
  • No obvious Lighthouse/Web Vitals budget gate was found in the inspected scripts/artifacts.
  • Backend has make test, Prometheus HTTP metrics middleware (backend/internal/shared/metrics/metrics.go), and HTTP server timeouts in academy/saas APIs; no broad backend load/performance test gate was found.

Cloudflare-relevant bottlenecks to watch#

  • OpenNext Worker bundle size, especially docs/ui-library pages with MDX, Shiki/Twoslash, API/search code, and server externals.
  • KV incremental cache hit rate for docs/blog/academy; cold misses can become Worker CPU latency.
  • Static export image behavior: images.unoptimized shifts optimization responsibility to source assets/CDN.
  • Manager chunking is explicit, but without bundle-size budgets regressions can pass tests.
  • Backend APIs are not Cloudflare-hosted in the current model, but frontend perceived latency depends on API timeouts, DB indexes, and cache hit rates.
  • Add or run app-specific bundle analysis: ANALYZE=true for Next apps and Vite bundle visualizer/size budget for manager.
  • Run focused Cloudflare builds for each Worker app (build:cf) and record Worker script size/assets size.
  • Add a lightweight Lighthouse/Web Vitals CI gate for representative Pages/Worker routes.
  • Restore or relocate the missing runtime proof artifact referenced by README, or update README to the current evidence path.