ReferenceAsk
Remy Reference/Architecture/Architecture/Request Lifecycles
15Architecture

Request Lifecycles

The path a browser request takes from DNS to the response, the one execution step every other kind of trigger joins, and the callbacks a running method makes back to the platform.

This chapter traces requests end to end. Each trace is a numbered list. Every step names the component it runs on and the boundary it crosses, so the trace reads as a flow diagram. The first trace is the canonical one. The rest show where each other kind of trigger joins it.


#1. A Browser Request to a Live App

  1. DNS. A request to the app's own origin resolves to Cloudflare. A custom domain resolves to Cloudflare for SaaS, which terminates TLS with the customer's certificate.
  2. Edge. The edge Worker forces HTTPS, reads the app's subdomain label or its custom hostname, and rewrites the request to the platform: a page load becomes one route, a call to the app's internal surface under /_/ becomes another. The app's identity travels as query parameters, so the platform never routes on the Host header.
  3. Load balancer. The Worker's request reaches the internet-facing load balancer, which terminates TLS with the FIPS policy and forwards to an HTTP-role pod by IP.
  4. Resolve the app. The HTTP role looks up the app by subdomain or custom hostname. A double-hyphen label is a branch preview, and is gated before anything else.
  5. Resolve the environment. The host says live or preview. If the request carries an interface session, the session refines that under the precedence rule in Environments. The result is an execution environment, required by every handler below.
  6. Serve or dispatch. A page load is served from the release's static bundle in S3, with the session injected and the security headers set: content-type sniffing off, a referrer policy, and a frame-ancestors policy when the app declares one. A call under /_/ goes to the segment switch, which routes to methods, files, auth, events, voice, MCP, data sources, uploads, analytics, issue reports, jewel proposals and their review queue, and prerender invalidation.
  7. Authorize. For a method call, the platform resolves the app user from the app's auth cookie or a bearer credential, loads the app's roles for that user, and checks the method's requirements from the manifest.
  8. Load the method. The platform loads the compiled bundle for the method from the release, mints a hook token scoped to this execution and this environment, and records the request.
  9. Find a sandbox. The execution service looks up the release's assigned sandbox in the registry. If none exists, it asks the orchestrator to claim a warm one and configure it for the release: dependency artifact, secrets, callback origin. See Release Sandboxes.
  10. Execute. The HTTP role sends an execute frame over the persistent WebSocket to the sandbox, across the VPC peering on the worker port. The frame carries the bundle key, the handler name, the parameters, the hook token, the auth context, and the database bindings for the environment's release.
  11. Callbacks. While the method runs, its SDK calls return to the callback origin over HTTPS through the edge: database queries reach the app database role through the WebSocket role, file operations reach the brokered file routes, model calls reach the model service, and platform actions reach the hook endpoints. Each carries the hook token, which names the environment, so a dev method never touches live data.
  12. Return. The sandbox returns the result, its captured output, and its timing. The HTTP role records metrics, writes the request-log row, emits an audit event for a human-invoked method, and answers the browser.
  13. Edge caching. The Worker caches content-addressed assets long-term, and never caches session HTML.

#2. An API Call

An app's API interface follows trace 1, entering at a different point. The caller presents an app API key as a bearer credential, either to the app's own origin under /_/api/... or to the platform's API host with the app named in the path. The key resolves to the app and to the identity it was issued for, and from step 7 the trace is identical.

#3. An MCP Client

An MCP client connects to the app's origin under /_/mcp. The platform speaks the protocol, lists the methods the manifest exposes as tools with their schemas, and invokes each tool call from step 8 onward. A downloadable skill document describes the tool set to an agent.

#4. A Cron Job

  1. The app's manifest declares its cron interfaces, and the build writes them to the job table with their schedule and time zone.
  2. A dispatcher runs on every HTTP pod, without leader election. Each scan claims a disjoint batch of due jobs with FOR UPDATE SKIP LOCKED, computes each job's next fire with missed-tick coalescing, and hands execution to a bounded pool. A stable per-job skew spreads the top-of-the-hour stampede.
  3. Each run is dispatched as a system invocation of the method, under the system user and the system role, to a disposable sandbox that exits after the run.
  4. The run is finalized exactly once: by the surviving await, by the sandbox's completion callback, or by a reaper on a stale heartbeat. Failure streaks pause a job; platform-side failures do not count against it.

#5. A Webhook

An external sender posts to the app's origin under /_/webhook/.... The platform verifies the webhook's configured secret, maps the route to the method the manifest declares, and runs it as a system invocation on a warm sandbox from step 8, since webhook senders enforce a latency limit.

#6. An Inbound Email

  1. The sender's mail server resolves the app's address on a platform apex and connects over SMTP to the Network Load Balancer, which forwards to the mail-inbound role.
  2. The SMTP server parses the recipient, matches the domain to a platform apex, and takes the single label as the app's subdomain. Reserved labels are refused.
  3. The message is parsed, and the manifest's email interface names the method. The run is dispatched as a system invocation to a disposable sandbox.

#7. A Voice Call

  1. A caller dials a phone number the app owns, or a browser starts a voice session. Telephony arrives through Telnyx into a LiveKit room; a browser joins the room directly.
  2. The voice worker picks up the room, authenticates to the platform with a per-session credential, fetches the runtime configuration, and bridges the media to a realtime model.
  3. When the model calls a tool, the worker invokes the method through the platform, which runs it from step 8 with the voice session as its originating identity.
  4. Transcripts append to the session as it runs, and the session is finalized and billed at the end.

#8. An Agent Chat Turn

A browser sends a turn to the app's origin under /_/agent/.... The platform runs the agent loop in the model service, with the app's methods as tools and its data sources as retrieval, streams tokens back, and invokes each tool call from step 8. Threads are persisted per user.

#9. A Model Call From a Method

  1. The SDK inside the sandbox calls the model service on the callback origin with the hook token.
  2. The model service resolves the workspace, checks the counterparty setting for the model's provider, and selects a route: a user pin, then the workspace's own key, then the capability filter, then the preferred route.
  3. The adapter for that route calls the provider: Bedrock over the PrivateLink endpoint, a first-party provider through NAT, or the platform's own serving pool.
  4. Usage is billed to the workspace as an event, metrics are recorded with the route as a dimension, and the response streams back into the sandbox.

#10. A File Upload

  1. The browser asks the app's method for an upload; the method asks the platform for a grant and returns it.
  2. The browser posts the bytes directly to S3's accelerated endpoint using the presigned grant. No platform pod sees the bytes.
  3. S3 emits an object-created event to that region's SNS topic, which delivers to the central file-scan queue.
  4. A worker picks up the event, streams the object to the ClamAV and Presidio services, and records the result. The dashboard shows the badge.

#11. A Dev Session

  1. A person opens an app in the editor. The platform resumes or creates their dev release and session, and asks the orchestrator for a dev box, or resumes their existing one.
  2. The editor opens the control channel to the sandbox control host, authenticated with the person's platform session and the session id. The sandbox-proxy role resolves the session to the box's address and proxies over the peering.
  3. The box clones the workspace, restores the person's latest snapshot, installs, and serves the preview. The preview is reachable on the box's own preview host through the preview Worker and the same proxy role.
  4. Method calls from the preview run on the box against the person's dev database, with a hook token whose environment is dev. Table changes sync to the dev database on save.
  5. The editor's keepalive and each agent call renew the lease. On shutdown, the box snapshots its home directory to S3.

#12. A Preview Host

A request to a gated preview host follows trace 1, with three differences: the host names a preview release, the gate requires a workspace session or a share link before any of the app's internal surface answers, and the data plane is the preview release's clone. The host wins over any session token presented there.

DiagramFIG. 15 — REQUEST LIFECYCLES
Browserpage load · live appAPI callbearer · API keyMCP clientMCP tool callsWebhookverified secretAgent chat turnchat turn · agent loopCrondispatcher · HTTP podsInbound emailSMTP → mail-inboundVoice callLiveKit → voice workerCloudflare Workerforces HTTPSALBTLS 1.3 · FIPSONE-WAY TRUST BOUNDARY (VPC PEERED)REQUEST LIFECYCLE · MANY DOORS, ONE PATHTHROUGH THE EDGEDIRECT · NO EDGEcallbacks return over public HTTPS through the front door · never the boundaryTRUSTED VPCHTTP rolethe full path runs for every entryResolve appsubdomain / custom hostResolve environmentlive · preview · devServe | dispatchpage → S3 bundle · /_/ → dispatchAuthorizeapp user · roles · manifest reqsLoad methodcompiled bundle · mint hook tokenFind sandboxassigned, else claim warmworker portUNTRUSTED VPC · kata_appsKATA microVMRelease sandboxruns the compiled methodreturns on the same socket
release sandbox · Kata microVMplatform / edge componentrequest flowthe one crossing · worker portVPC trust boundarycallbacks · via the front dooruntrusted VPC
Every trigger into a Remy app runs the same path. The web-facing ones, a browser page load, an API call, an MCP client, a webhook, an agent chat turn, reach the platform through the Cloudflare Worker and the load balancer; the internal ones, cron, inbound email, a voice call, reach the HTTP role directly, with no edge. From there the path is the same for all of them: the HTTP role resolves the app and its environment, authorizes the caller, loads the compiled method, mints a hook token scoped to this execution, and finds a sandbox. A single execute frame then crosses the VPC trust boundary on the worker port, the one crimson line in the whole reference, into the release sandbox, where the method runs and returns on the same socket. Its callbacks reach back over public HTTPS through the front door, carrying the hook token, and never cross the boundary.

Figure 15, "Request Lifecycles": many doors, one path. On the left, the triggers, in two groups. The web-facing ones collect through the Cloudflare Worker and the load balancer (ALB, TLS with the FIPS policy): a browser page load, an API call, an MCP client, a webhook, an agent chat turn. The internal ones reach the HTTP role directly, with no edge: cron (a dispatcher on every HTTP pod), inbound email (SMTP to the mail-inbound role), and a voice call (through the voice worker). Both lanes converge into one entry at the top of the HTTP-role hub, and the full path runs for every entry: resolve the app, resolve the environment, serve or dispatch, authorize, load the compiled method and mint the hook token, and find a sandbox. From the foot of that ladder, one crimson crossing on the worker port carries the execute frame across the ONE-WAY TRUST BOUNDARY (VPC PEERED) into the release sandbox, a Kata microVM on the kata_apps island in the untrusted VPC, where the method runs and returns on the same socket. This is the one crimson line on the plate, and one of the three crossings the trust-boundary chapter enumerates: the request flow is the thing that actually crosses the boundary the earlier chapters describe. While the method runs, its callbacks leave the sandbox and re-enter the front door over public HTTPS, carrying the hook token; they go up and over the top of the plate and never cross the boundary. Crimson is spent on exactly one crossing.