- Temporal
- /
- Delivering Temporal workflow output to multiple devices
Delivering Temporal workflow output to multiple devices
TL;DR Temporal workflows run once and produce output once. Getting that output to every device or tab a user is watching from requires a fan-out layer that Temporal doesn't provide. Each device polling independently multiplies query cost linearly. Redis pub/sub delivers only to whoever is connected at the moment of publish. A device joining mid-run has no path to catch up on what it missed without a delivery layer that buffers events and serves them by position.
A user starts an agent task on their laptop and walks away. They pick up their phone and want to see what the agent has done. The workflow has been running the whole time. The phone has not. When it connects, does it see everything from the beginning, just new output, or nothing at all? That depends entirely on how the delivery layer handles a mid-run join, and most approaches get it wrong.
What Temporal knows about connected clients
Temporal workflows execute on workers. The workflow knows its inputs, its current state, and the activities it has executed. It has no concept of which browsers, devices, or sessions are watching it.
This is correct by design. Execution durability is independent of client connections. A workflow runs to completion regardless of whether anyone is watching. The execution model doesn't change based on the audience.
The implication for multi-device delivery is that fan-out - sending the same output to multiple connected clients - is entirely outside Temporal's scope. The workflow produces output once. Distributing it is a separate problem.
The per-device polling problem
The default multi-device pattern is independent polling: each device polls the workflow's query handler every few seconds and renders whatever state it receives.
Two devices watching the same workflow means two independent polling loops. At two-second intervals, a five-minute workflow generates 150 query calls per device, or 300 total for two devices. At three devices it's 450. Each query runs on a worker.
The poll-per-device model scales linearly with the number of watching clients. For workflows where the number of observers is small and predictable, this may be acceptable. For workflows that are shared across teams e.g. a document processing job, a bulk operation or a background agent, the device count is not predictable, and polling cost grows proportionally.
The fan-out gap with Redis pub/sub
Teams that move beyond polling often reach for a Redis pub/sub relay. An activity publishes to a Redis channel and a relay forwards events to SSE endpoints the browser holds open.
Redis pub/sub is a broadcast to whoever is currently subscribed. A second device connecting to the SSE endpoint starts receiving events from that moment. It has no access to events that arrived before it connected.
A user switching from laptop to phone mid-run gets a partial view on the phone. Everything the workflow produced before the phone connected is not available. The phone sees the workflow from wherever it happened to join.
This is a structural constraint of pub/sub. Messages are not stored. There is no concept of a per-subscriber offset or catch-up position. Redis Streams provides persistence and consumer groups, but it changes the relay architecture significantly: the relay must now poll or block-read from the stream, and offset management per device adds complexity that the pub/sub pattern avoids.
What a device joining mid-run needs
For a second device to see the complete output of a running workflow, it needs two things: the history of what the workflow has produced so far, and all new output from that point forward.
A state query gives the current accumulated state. Useful for a snapshot but not a stream, as it doesn't provide the sequence of events that led to the current state, just where things stand now. For streaming output like LLM tokens or step-by-step progress, the current state is a collapsed view that loses the ordering information.
Position-based replay gives the device everything from a specific point in the event stream. The delivery layer buffers events and serves them by offset. The connecting device requests events from position zero and receives the full run history, then stays subscribed for new events.
Temporal Workflow Streams
Temporal's Workflow Streams improves on Redis pub/sub for a single connected device: subscribers track their own offset client-side, so a reconnecting client can resume from where it left off. However, a second device joining mid-run has no offset to start from. It receives events from the moment it connects and has no way to retrieve what came before. Two devices, or tabs, watching the same workflow see different, incomplete views.
Workflow Streams is also Python-only. Per-roundtrip latency is around 100ms, which suits step-level progress updates better than token-by-token streaming.
A delivery layer alongside Temporal for multi-device delivery
A delivery layer handles fan-out and per-device session tracking alongside Temporal. When a workflow activity publishes a single event, the delivery layer distributes it to every subscribed client simultaneously. Adding a second or third device doesn't change anything on the workflow side.
When a new device connects mid-run, it requests replay from position zero. The delivery layer serves the buffered event history and transitions seamlessly to the live stream. The device sees everything the workflow has produced, in order, from the beginning.
Each device maintains its own position independently. A phone that was offline during part of the run reconnects, requests events from its last received position, and catches up without a full workflow query. The workflow execution is unaffected throughout.
Temporal handles execution. The delivery layer handles every client, wherever they are, and whatever they missed - in a durable session.
Ably AI Transport provides a delivery layer for Temporal with fan-out to multiple devices, per-device session tracking, and catch-up replay for devices that connect mid-run. Visit the Ably AI Transport overview, read the documentation, or sign up free to start building. For a broader overview of why Temporal workflows need a frontend delivery layer, see ably.com/topic/temporal-realtime-transport.
,Frequently asked questions
Does Temporal support delivering workflow output to multiple devices simultaneously? No. Temporal workflows produce output once and have no concept of which browsers or devices are watching. Fan-out (sending the same output to multiple connected clients) is outside Temporal's scope. Distributing that output is a separate problem Temporal leaves entirely to you.
What does a second device see when it joins a running Temporal workflow? It depends on the delivery approach. With polling, it sees a snapshot of current state but not the ordered sequence that produced it — for streaming output like LLM tokens, a collapsed snapshot loses all meaning. With Redis pub/sub, it receives only events from the moment it connected (everything before is gone). Position-based replay is the only approach that gives a late-joining device the full run history from the beginning.
Why does Redis pub/sub fall short for multi-device Temporal delivery? Because it broadcasts only to whoever is subscribed at the moment of publish. A device connecting after an event was published has no way to retrieve it (there's no per-subscriber offset or catch-up position). A user switching from laptop to phone mid-run gets a partial view on the phone; everything the workflow produced before the phone connected is unavailable.
Does Temporal Workflow Streams solve the multi-device problem? Only partially. Workflow Streams lets a reconnecting client resume from its last offset, but a second device joining mid-run has no offset to start from (it receives events from the moment it connects and can't retrieve what came before). Two devices watching the same workflow see different, incomplete views. TypeScript and JavaScript developers have no equivalent today.
What does a multi-device delivery layer need to provide alongside Temporal? Two things:
Fan-out: a single workflow publish reaches every subscribed device simultaneously, so adding devices doesn't change the workflow
Position-based replay: a device joining mid-run requests from position zero, receives the full run history, then transitions to live events; each device tracks its own offset, so one that was offline catches up without querying the full workflow state
Recommended Articles
Why Temporal workflows need a frontend delivery layer
Temporal crash-proofs backend workflows. A durable sessions layer handles the rest: browser delivery, reconnect replay, and offline notifications.
Redis pub/sub limitations for Temporal frontend delivery
Redis pub/sub is fire-and-forget. Events published while a client is disconnected are gone permanently. Why it falls short for Temporal workflows and what to use instead.