Cloudflare Docs
Workers
Edit this page on GitHub
Set theme to dark (⇧+D)

Streams

The Streams API is a web standard API that allows JavaScript to programmatically access and process streams of data.

Workers do not need to prepare an entire response body before delivering it to event.respondWith(). You can use TransformStream to stream a response body after sending the front matter (that is, HTTP status line and headers). This allows you to minimize:

  • The visitor’s time-to-first-byte.
  • The buffering done in the Worker.

Minimizing buffering is especially important for processing or transforming response bodies larger than the Worker’s memory limit. For these cases, streaming is the only implementation strategy.

The two primitives developers use to perform active streaming are TransformStream and the ReadableStream.pipeTo() method.

A basic pass-through usage of streams:

export default {
async fetch(request, env, ctx) {
// Fetch from origin server.
let response = await fetch(request);
// Create an identity TransformStream (a.k.a. a pipe).
// The readable side will become our new response body.
let { readable, writable } = new TransformStream();
// Start pumping the body. NOTE: No await!
response.body.pipeTo(writable);
// ... and deliver our Response while that’s running.
return new Response(readable, response);
}
}
addEventListener('fetch', event => {
event.respondWith(fetchAndStream(event.request));
});
async function fetchAndStream(request) {
// Fetch from origin server.
let response = await fetch(request);
// Create an identity TransformStream (a.k.a. a pipe).
// The readable side will become our new response body.
let { readable, writable } = new TransformStream();
// Start pumping the body. NOTE: No await!
response.body.pipeTo(writable);
// ... and deliver our Response while that’s running.
return new Response(readable, response);
}

This example calls response.body.pipeTo(writable) but does not await it. This is so it does not block the forward progress of the remainder of the fetchAndStream() function. It continues to run asynchronously until the response is complete or the client disconnects.

The runtime can continue running a function (response.body.pipeTo(writable)) after a response is returned to the client. This example pumps the subrequest response body to the final response body. However, you can use more complicated logic, such as adding a prefix or a suffix to the body or to process it somehow.


​​ Common issues