When deploying a Mastra app to Cloudflare Workers via @mastra/deployer-cloudflare, SSE streaming responses from /agents/:agentId/stream are buffered and delivered
all at once instead of streaming incrementally.
Observed behavior (production — Cloudflare Workers):
- Response returns 200 with correct content-type: text/event-stream
- TTFB (time to first byte): ~10s — the entire agent generation completes before any data is sent
- Receive time: ~400ms — all ~10KB arrives in a single burst
- Chrome DevTools does not show the response as an event stream
Expected behavior (dev server — Node.js):
- TTFB: ~1.7s — first byte arrives as soon as the first token is generated
- Receive time: ~1.9s — data streams incrementally as the agent generates tokens
- Response includes transfer-encoding: chunked and streams correctly
Root cause analysis:
The MastraServer.stream() method in @mastra/deployer uses Hono's stream() helper, which:
1. Creates a TransformStream intermediary
2. Wraps the writable side in a StreamingApi object
3. Passes the readable side through c.newResponse()
4. Hono's CORS middleware accesses c.res.headers before await next(), which initializes c.#res
5. The set res() setter then calls new Response(_res.body, _res) to merge headers — creating yet another Response wrapper
This multi-layer Response wrapping appears to cause Cloudflare Workers to buffer the entire stream before sending it to the client.
By contrast, the datastream-response responseType works correctly because it returns a Response object directly without going through Hono's stream() helper.
Suggested fix:
Replace the Hono stream() helper usage in MastraServer.stream() with a direct new Response(ReadableStream, { headers }) pattern, similar to how datastream-response
already works and consistent with Cloudflare's SSE documentation.