Skip to main content
The Streams API allows you to read streaming data from your Trigger.dev tasks in your backend code. This is particularly useful for consuming AI/LLM outputs, progress updates, or any other real-time data that your tasks emit.
To learn how to emit streams from your tasks, see our Realtime Streams documentation. For frontend applications using React, see our React hooks streams documentation.

Reading streams

The recommended approach is to use defined streams for full type safety:

Direct stream reading

If you prefer not to use defined streams, you can read directly by specifying the stream key:

Reading from the default stream

Every run has a default stream, so you can omit the stream key:

Stream options

The read() method accepts several options for controlling stream behavior:

Timeout

Set a timeout to stop reading if no data is received within a specified time:

Start index

Resume reading from a specific chunk index (useful for reconnection scenarios):

Abort signal

Use an AbortSignal to cancel stream reading:

Combining options

You can combine multiple options:

Practical examples

Reading AI streaming responses

Here’s a complete example of consuming an AI stream from your backend:

Reading multiple streams

If a task emits multiple streams, you can read them concurrently or sequentially:

Piping streams to HTTP responses

You can pipe streams directly to HTTP responses for server-sent events (SSE):

Implementing retry logic

Handle transient errors with retry logic:

Processing streams in chunks

Process streams in batches for efficiency:

Using with runs.subscribeToRun()

For more advanced use cases where you need both the run status and streams, you can use the runs.subscribeToRun() method with .withStreams():
For most use cases, we recommend using streams.read() with defined streams for better type safety and clearer code. Use runs.subscribeToRun().withStreams() only when you need to track both run status and stream data simultaneously.