Services

Cloudflare Performance Recommendation 2026 06 16


Cloudflare performance and hosting recommendation — 2026-06-16

Scope: concise synthesis of the hosting inventory, performance audit, and Cloudflare options assessment for the Assistance monorepo. This is documentation-only; no product code changes are recommended here.

Current state#

  • Assistance already uses a coherent split deployment model:
    • apps/www and apps/manager deploy to Cloudflare Pages.
    • apps/blog, apps/docs, apps/academy, apps/design-system, and apps/ui-library deploy as Cloudflare Workers via OpenNext with Workers Assets.
    • Go APIs, Postgres, and Meilisearch remain self-hosted through production compose and the existing Caddy/service-registry path.
  • apps/www is a static Next export with service bindings to the blog and docs Workers.
  • apps/docs already uses Cloudflare-native edge state where it fits: KV for OpenNext incremental cache and D1 for docs search.
  • Root Cloudflare operations are centralized in .mise.toml through cf:build*, cf:deploy*, cf:health, and cf:release tasks.
  • Aggregate Cloudflare deploys require CLOUDFLARE_API_TOKEN; Wrangler OAuth alone is insufficient for OpenNext KV cache population.
  • Runtime proof is currently narrower than the full production matrix. The referenced docs/runtime/S02-RUNTIME-PROOF.md artifact was absent in the inspected checkout, and root docs explicitly do not prove full multi-app e2e coverage or the known manager preview/runtime path.
ComponentRecommendationRationale
apps/wwwKeep on Cloudflare Pages as static exportSimple, fast CDN delivery; service bindings already compose with blog/docs Workers. Move to OpenNext only if SSR becomes a product requirement.
apps/managerKeep on Cloudflare Pages as Vite SPACorrect fit for static SPA delivery. Validate the known preview/runtime path before claiming it is green.
apps/blogKeep on Workers + OpenNext + Workers Assets + KV cacheCurrent Worker model supports SSR/ISR-like behavior and is already integrated with www. Continue watching Worker bundle size.
apps/docsKeep on Workers + OpenNext + KV + D1 searchD1 is a good fit for docs search; explicit /docs* Worker routes should remain coordinated with www Pages routing.
apps/academyKeep on Workers + OpenNextFits current content/SSR deployment. Add KV only if incremental cache behavior requires it.
apps/design-systemKeep on Workers + OpenNext + KVNo migration value unless it becomes fully static.
apps/ui-libraryKeep on Workers + OpenNext + KVCurrent model fits registry/docs/LLMS outputs. Watch bundle size and cache behavior.
auth-apiKeep self-hostedAuth state, secrets, callback URLs, and DB adjacency favor the current stable path.
billing-apiKeep self-hostedBilling/webhook correctness and secret handling should not be moved without a separate production pilot.
academy-apiKeep self-hosted; consider only a narrow stateless Container pilot laterGood candidate for a future read-heavy endpoint pilot, not an immediate platform migration.
saas-apiClarify production target before hosting changesDev compose evidence exists, but no production compose service was found in the inventory.
Postgres / MeilisearchKeep outside Cloudflare edge primitivesDo not replace Postgres-backed auth/billing state with D1/KV. D1 already covers docs search where appropriate.

Performance opportunities#

  1. Add bundle and Worker-size gates for Cloudflare apps, especially blog, docs, ui-library, and design-system where MDX, Shiki/Twoslash, registry code, or OpenNext output can push Worker limits.
  2. Run and record per-app Cloudflare build evidence, including Worker script size, asset size, and cache binding validation.
  3. Add lightweight Lighthouse/Web Vitals checks for representative public routes after deploy or preview deploy.
  4. Validate cache headers and Cloudflare Cache Rules narrowly:
    • long TTL for immutable static assets such as /_next/static/*;
    • careful image caching because several apps use images.unoptimized;
    • bypass or explicit no-store behavior for API and personalized paths.
  5. Track KV incremental cache hit rate and cold-miss latency for OpenNext apps.
  6. Keep backend latency visible because frontend perceived performance still depends on self-hosted APIs, DB indexes, service timeouts, and cache hit rates.
  7. Restore, relocate, or update the missing runtime-proof artifact so root documentation points at current executable evidence.

Migration and validation plan#

Phase 1 — prove the current architecture#

  • Run focused builds before release:
    • mise run cf:build:www
    • mise run cf:build:manager
    • mise run cf:build:blog
    • mise run cf:build:docs
    • mise run cf:build:academy
    • mise run cf:build:ds
    • mise run cf:build:ui
  • Run mise run cf:deploy:preflight to confirm token availability and permissions.
  • Use preview deploys or wrangler deploy --dry-run where supported for Worker apps.
  • After deploy, run mise run cf:health and browser smoke tests for representative routes.

Phase 2 — validate performance and correctness#

  • Inspect deployed headers for static assets, images, SSR pages, search/API routes, and personalized paths.
  • Verify www.assistance.bg/docs* resolves through the assistance-docs Worker after every route change.
  • Verify www service bindings still resolve to assistance-blog and assistance-docs.
  • Run docs search indexing with mise run cf:index:search and smoke the D1-backed search path.
  • Add budget checks for bundle size, Worker script size, and representative Web Vitals.

Phase 3 — evaluate selective Cloudflare additions#

  • Add Turnstile to public forms/signup/auth-adjacent surfaces where abuse risk exists.
  • Consider Queues for async email, webhook retries, search indexing, or content processing.
  • Consider R2 or Cloudflare Images only when product asset volume and lifecycle requirements justify the migration.
  • Pilot Cloudflare Containers only with one stateless, read-only Go endpoint in staging and explicit latency, error-rate, observability, secrets, DB connection, and rollback acceptance criteria.

Risks and unknowns#

  • OpenNext Workers are not full Node.js; unsupported Node APIs, native packages, large bundles, or long-running work can pass local checks but fail at runtime.
  • Broad static-generation concurrency is tuned for a large build host (NODE_OPTIONS=--max-old-space-size=8192, UV_THREADPOOL_SIZE=16, and multiple experimental.cpus: 16 configs) but can still stress CI/build machines when several Next apps build in parallel.
  • Turbo dry-run emitted partial JSON and then crashed during the audit, reducing confidence in quick cache/build introspection.
  • Some production builds bypass TypeScript errors (apps/www, apps/blog), so separate typecheck/test gates must remain reliable.
  • Cloudflare route precedence can break www/docs composition if Pages and Worker routes are changed independently.
  • D1/KV are useful edge primitives but are not replacements for Postgres-backed auth, billing, or transactional state.
  • Cloudflare Containers may become useful for Go services, but platform limits, cold starts, persistent DB connectivity, logs/metrics, and secrets need a pilot first.
  • The manager preview/runtime path remains known-constrained in root docs and should not be represented as fully green without fresh runtime evidence.

Decision matrix#

OptionDecisionConfidenceWhy
Keep current Pages + Workers/OpenNext + self-hosted Go topologyAdopt as defaultHighMatches repo configuration, app needs, and current operational surfaces with minimal migration risk.
Move static apps from Pages to Workers Static AssetsDeferMediumCould simplify future Worker-first routing, but current Pages setup is already simple and sufficient.
Move Go APIs to Cloudflare ContainersPilot onlyLow-mediumInteresting for stateless endpoints, but not ready for auth/billing/database-adjacent production paths.
Expand D1/KV beyond cache/search into product stateReject for nowHighWrong consistency and data-model fit for auth, billing, and transactional state.
Add Turnstile for public forms/auth surfacesRecommendHighClear abuse-protection value with limited architecture impact.
Add Queues for async workRecommend selectivelyMedium-highGood fit for email/webhook/indexing jobs once retry/DLQ ownership is defined.
Add R2/Cloudflare ImagesDefer until asset need is concreteMediumValuable for media-heavy growth, but not evidenced as an immediate bottleneck.

Final recommendation#

Do not migrate platforms now. Keep the current Cloudflare Pages plus Workers/OpenNext frontend architecture and the self-hosted Go backend stack. Invest first in validation: per-app Cloudflare build artifacts, Worker/bundle budgets, Web Vitals checks, route/cache correctness tests, and updated runtime-proof documentation. Add Cloudflare services only where there is a concrete product fit: Turnstile for abuse-prone public flows, Queues for async work, and later R2/Images or Containers through scoped pilots with measurable acceptance criteria.