1. Temporal
  2. /
  3. Delivering Temporal workflow output to multiple devices
8 min readPublished Jun 22, 2026

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.

Copy link to clipboard

Key takeaways

  • Temporal has no concept of connected devices: fan-out is entirely outside its scope, and this is correct by design, not a shortcoming to work around.

  • Polling scales linearly with device count, Redis pub/sub only reaches whoever is connected at the moment of publish, and Workflow Streams solves reconnect for one device but not a second.

  • Closing the gap needs position-based replay plus fan-out. Ably AI Transport ships this as a documented Temporal integration today.

Copy link to clipboard

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: a workflow's execution doesn't depend on who's watching, so it runs to completion whether a client is connected or not.

The implication for multi-device delivery is direct. Temporal produces the workflow's output once. Getting that output to more than one connected client is a separate problem, and closing it is entirely on the team building the delivery layer.

See Why Temporal workflows need a frontend delivery layer for the full picture of why Temporal leaves delivery to something else. Closing that gap starts with knowing exactly what a late-joining device needs.

Copy link to clipboard

What a device joining mid-run actually needs

For a second device to see the complete output of a running workflow, it needs two things. It needs the history of what the workflow has produced so far, and all new output from that point forward.

One option is to query the workflow: Temporal's built-in mechanism for reading a workflow's current state without affecting its execution.

A query gives a device the current accumulated state. It's useful for a snapshot, but not a stream. 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.

The alternative is position-based replay: instead of asking for current state, the device asks for every event from a specific point onward. The delivery layer buffers events and serves them by offset. The connecting device requests events from position zero, receives the full run history, then stays subscribed for new events.

That's the bar any approach to multi-device delivery has to clear: fan-out to every connected device, and position-based replay for whoever joins late. Here's how the three common approaches measure up.

Copy link to clipboard

Approaches to multi-device Temporal delivery

Copy link to clipboard

Per-device polling

Per-device polling works by having each device ask the workflow's query handler for its current state every few seconds, then render whatever it gets back.

It doesn't give a joining device position-based replay. A query only returns current state, not the sequence of events that produced it. A device that joins mid-run has no way to see what it missed.

Polling also has another challenge: cost scales directly with the number of watching devices. At two-second intervals, a five-minute workflow generates 150 query calls for one device watching, or 300 for two. At three devices it's 450, with every one of those calls running on a worker.

The model scales linearly, in other words: each additional device is another full polling loop, not a shared one. For workflows where the number of observers is small and predictable, this may be acceptable.

For workflows shared across teams, such as a document processing job, a bulk operation, or a background agent, the device count isn't predictable. Polling cost grows proportionally as a result.

Copy link to clipboard

Redis pub/sub

Teams that move beyond polling often reach for a Redis pub/sub relay next. An activity publishes to a Redis channel, and a relay forwards events to SSE endpoints the browser holds open.

Redis pub/sub solves the polling-cost problem: one publish reaches every subscribed device at once, so adding a third or fourth device doesn't add load. It still doesn't solve replay for a device joining mid-run, though.

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, with no access to anything that arrived before it connected.

A user switching from a laptop to a phone mid-run gets a partial view on the phone. Everything the workflow produced before the phone connected is unavailable, so the phone sees the workflow from wherever it happened to join.

This is a structural constraint of pub/sub, not a configuration gap: messages aren't stored, and there's no concept of a per-subscriber offset or catch-up position. See Redis pub/sub limitations for Temporal frontend delivery for the full comparison of Redis Streams, Workflow Streams, and building a custom delivery layer.

Copy link to clipboard

Temporal Workflow Streams

Workflow Streams shipped first as a Python-only contrib module. TypeScript support followed, reaching Public Preview on 17 June 2026, with Go and Java still on the roadmap. It solves reconnect for a single device: subscribers track their own offset client-side, so a dropped client reconnects and resumes from where it left off.

But it doesn't solve fan-out. A second device joining mid-run has no offset of its own to start from. It receives events from the moment it connects, with no way to retrieve what came before.

Two devices, or tabs, watching the same workflow end up with different, incomplete views of the same run. Additionally, per-roundtrip latency is around 100ms, which suits step-level progress updates better than token-by-token streaming. But that's a separate consideration from the fan-out gap itself.

Copy link to clipboard

Temporal and AI Transport: solving multi-device fan-out

Ably AI Transport is a documented Temporal integration that provides both fan-out and position-based replay. That's the gap that polling, Redis pub/sub, and Workflow Streams each left open.

Ably publishes each Temporal activity's output as a Step: AI Transport's basic unit of published output, keyed to the activity's own Temporal activity ID. Every subscribed device receives that publish simultaneously, so adding a third or fourth device doesn't change anything on the workflow side.

When a new device connects mid-run, it requests replay from position zero. Ably serves the buffered event history, then transitions to the live stream. The device sees everything the workflow has produced, in order, from the beginning.

Each device tracks its own position independently. A phone that was offline during the run reconnects, requests events from its last received position, and catches up without a full workflow query. Cancel signals route through the Ably channel directly, without an extra Temporal signal.

Visit the Ably AI Transport overview, read the documentation, or sign up free to start building.

Copy link to clipboard

Frequently asked questions

Copy link to clipboard

Can I use Temporal signals or queries to notify multiple devices instead?

Not directly. Signals and queries are point-to-point. A query call returns state to the caller that made it, and a signal targets a specific workflow, not a specific set of subscribers. Neither has a broadcast primitive, so notifying multiple devices still means building a fan-out layer on top.

Copy link to clipboard

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, not the sequence that produced it, which loses meaning for streaming output like LLM tokens. With Redis pub/sub, it receives only events from the moment it connected. Position-based replay is the only approach that gives a late-joining device the full run history from the beginning.

Copy link to clipboard

Would switching from Redis pub/sub to Redis Streams solve multi-device delivery on its own?

Only the storage half. Streams persist messages, so a client can read from any position instead of just the current moment. But multi-device fan-out still needs each device tracking its own read position independently, which Redis Streams doesn't do for you. See [Redis pub/sub limitations for Temporal frontend delivery](https://ably.com/temporal/temporal-redis-pubsub-limitations) for the full breakdown.

Copy link to clipboard

Would Workflow Streams solve multi-device delivery once TypeScript, Go, and Java all have full support?

No. Language support and fan-out are separate problems. Workflow Streams' architecture ties each client's replay position to that client's own connection, so a second device still has no offset to start from. Broader language support closes the reconnect gap for more developers, not the fan-out gap for any of them.

Copy link to clipboard

How do I know if a delivery layer actually provides position-based replay, not just reconnect?

Ask whether a device joining mid-run for the first time, not just reconnecting, gets the full run history from position zero. Reconnect-only support means an already-connected device can resume after a drop, but a second device joining fresh still starts from nothing. True position-based replay serves both cases from the same buffered event history.

Join the Ably newsletter today

1000s of industry pioneers trust Ably for monthly insights on the realtime data economy.
Enter your email