Worker Api Performance

ExploreSelf-hostDocumentationBlogSign In
Documentation
Overview
Getting Started
Getting StartedPlatform IntegrationsAgentPlaybooks in ClaudePortable Bot TeamsHermes Memory ProviderHermes for OrganisationsAgentPlaybooks Tools in HermesCLI & Editor PluginsCross-platform Agent BackupsRelease DistributionTeam CollaborationFederated MCP & OpenAPI ToolsMCP Registry PublishingRoadmap
Core Concepts
PlaybooksSkillsMemoryMCP Integration
Reference
ArchitectureAPI ReferenceManagement APIDeveloper GuideSelf-HostingEnvironment Setup
View on GitHub
DocsWorker Api Performance

Cloudflare API execution

worker.ts dispatches native Request/Hono API routes directly, using the same route exports and authorization helpers as Next.js. MCP, operation HTTP projections, memory, canvas, secrets, runs, and the Hono REST catch-all therefore avoid the Next server wrapper and its response lifecycle waitUntil task. The playbook export, collaboration, snapshot, backup, connection catalogue, registry search, and site-wide/per-playbook OAuth/skill discovery routes also use native Request/Response handlers. Frontend pages use reviewed build-owned assets, with OpenNext as fallback.

scripts/generate-worker-api-routes.mjs generates the dispatch manifest during prebuild. It includes reservations for Next-specific routes so the REST catch-all cannot shadow them. Specific routes take precedence over dynamic segments. Handler modules are loaded lazily: public metadata does not initialize the MCP, snapshot, secret, or Next page implementations. Catch-all parameters retain their array shape, including optional empty paths. The configuration test re-export is included explicitly. Unsupported methods, HEAD, and OPTIONS retain route-handler semantics. API responses use the same security headers as Next and default to Cache-Control: no-store. Authentication is checked on every request before cached discovery content is returned; this is not a response cache or an authentication cache.

Federation timeouts cover response bodies as well as headers. SSE responses are read incrementally until the matching JSON-RPC result/error, then cancelled; notifications and other request IDs cannot satisfy the request. Upstream bodies are limited to 8 MiB. This also applies to OpenAPI specifications, operations, and OAuth token requests. Initialization notification responses are cancelled without waiting for an unnecessary body.

Connection logs record bounded, client-declared names/versions, User-Agent, and validated key prefixes (never tokens or request arguments). Discovery logs are sampled at 2%; they can help diagnose reconnect/discovery loops without logging every tool call. Client-declared identity is an attribution hint, not proof of which program or person sent a request.

Only full-document GETs of /, /docs, /blog, and published public Markdown document/post paths without query strings, credentials, session cookies, conditional/range headers, or Next/RSC headers are eligible for the public HTML Cache API. NEXT_LOCALE is the only accepted cookie; cache keys use the same locale selector as SSR plus the origin and Worker version ID. Successful HTML is retained for five minutes, concurrent fills are coalesced, and errors, redirects, Set-Cookie, JSON, and Vary-star responses are not stored. Browser/CDN responses remain no-store, avoiding implicit locale or RSC mixing. Authenticated pages and all API responses bypass this HTML cache. Changes that introduce personalized server rendering on any allowlisted page require removing that page from the cache allowlist. generate-public-page-paths.mjs builds this exact path list from public Markdown filenames; unknown slugs, subroutes, and asset requests are excluded. The manifest contains paths only, so loading the Worker does not load the embedded blog content index.

The unpublished /.well-known/traffic-advice policy answers its existing 404 directly, without initializing Next to render a not-found page.

Registry search has its own bounded five-minute public-data cache with eight entries and concurrent-load coalescing; upstream headers and bodies share a ten-second timeout and a 2 MiB body limit. Credentials are never forwarded to the registry or stored in cache keys.

Public HTML produced during deployment

generate-public-html.ts starts the built standalone Next server on loopback during the Worker build and produces complete HTML for every reviewed public path in English, Hungarian, German and Spanish, plus separate full RSC and prefetch and route-tree payloads from the same Next build. Only public Markdown and localized README files are supplied. Requests have no cookies or credentials; private secret/token/password environment variables are removed from the renderer's environment and their values are checked against the generated HTML. The build fails for non-200 responses, cookies, an incorrect locale, missing client assets, loopback URLs or HTML exceeding 2 MiB. The output is deployment assets, not embedded Worker source; no snapshot content is loaded by API calls.

Eligible GET/HEAD requests read the locale-specific file through the ASSETS binding before initializing Next or using the fallback HTML Cache API. This also avoids Next rendering on the first request in a new location when the asset cache is empty. X-APB-Page-Source: STATIC and X-APB-Page-Cache: ASSET identify this path. X-APB-Page-Variant distinguishes HTML, navigation RSC, prefetch RSC and route-tree RSC. A signed-in visitor receives the same public build-owned content: credentials, session cookies, router trees and query strings are never forwarded to ASSETS. Only NEXT_LOCALE affects the asset selection. These exact pages have no personalized server data or query-dependent server content. /docs?page=... redirects to the published canonical doc path; /login and /explore snapshots contain only their public initial UI, not sessions, user stars or playbook rows. Their existing browser effects load auth settings and live data after hydration; their API authorization is unchanged. other query values do not change their server content. Private page paths and all API paths are excluded. Draft mode, server actions and unsupported Next internal protocols still reach Next. HEAD has no body, security headers are restored, and browser responses remain no-store to prevent locale mixing. Asset ETags/Last-Modified are not exposed as validators for the locale-varying public URL. The snapshot uses its own weak ETag bound to the Worker version, locale, path and HTML/Flight variant. Matching If-None-Match returns 304; non-wildcard If-Match returns 412 because weak tags cannot strongly match. Date conditions are ignored without Last-Modified. Range is optional and receives the complete 200 representation with Accept-Ranges: none, never partial Flight or a cold Next render. These headers are not forwarded to ASSETS.

Missing/unavailable assets fall back to Next and the bounded HTML Cache API. Private pages and requests excluded from the public policy still need Next; this change does not promise every such cold render fits the free-plan CPU allowance.

Normal navigation receives a full build-owned RSC payload rather than a response tailored to a client router tree. Prefetch has its own payload; HTML is never returned as RSC. The browser policy is no-store for all variants, and Vary declares locale, cookies and router representation. There are no interception routes in this application. Personalization or interception added to a reviewed page requires removing it from the snapshot allowlist or extending the policy.

Native page redirects and misses

generate-page-route-patterns.mjs reserves the application's declared page routes, including dynamic dashboard and invite paths. Existing API reservations and metadata routes retain their handlers. Unknown public blog/doc slugs and other missing URLs receive a small native 404, without Next initialization, credentials or request data in the body. Static asset aliases are checked before declaring a miss, and a binding failure falls back to Next. Canonical trailing slashes, legal redirects and legacy documentation URLs use native redirects. RSC misses return non-RSC 404 HTML so Next's browser router can perform a full navigation to the error page; it is never a successful cached Flight response.

Avoiding repeated client and upstream requests

Explore waits 300 ms after nonempty search input before fetching playbooks. A new query cancels the previous timer/fetch, and a superseded response cannot replace current results even if its transport ignores cancellation. Loading Skills or MCP catalogue data no longer refetches the Playbooks tab.

Federated calls to tool names already declared in the freshly loaded server row skip an extra upstream tools/list discovery request. Upstream authentication and execution still run; undeclared names retain discovery and fallback behavior. A stale declaration fails at execution rather than bypassing upstream checks.

Discovery observability logs the first tools/list or resources/list event per five-minute identity/method/user-agent window in each Worker isolate; repeats are sampled at 2%. The window map is bounded to 128 entries. Initialize events remain logged. Only bounded client metadata and key prefixes are recorded; credentials, tool arguments, content and IP addresses are excluded. Window events are observations, not an exact client census or request counter.

MCP transport alone does not imply polling. Local audits should compare global MCP entries with plugin-bundled entries and inspect client initialization logs. Native Hermes memory uses REST memory routes and has no periodic tools/list poller. Other Hermes MCP clients or remote integrations require separate evidence.

Edit this page on GitHub
On this page
Public HTML produced during deploymentNative page redirects and missesAvoiding repeated client and upstream requests