Skip to content
Articles
TechnicalInfrastructureProduction

How Live AI Progress Reaches the Browser

A practical comparison of polling, server-sent events, and WebSockets, including event contracts, reconnects, ordering, authorization, and honest progress percentages.

Published Jul 16, 2026Updated Jul 23, 202614 min readDifficulty: Intermediate3/5
In this article
Diagram showing GPU progress flowing through an event bus and API WebSocket to a browser progress bar
A progress update begins inside a worker, crosses a process boundary and an authenticated API connection, and finally updates a browser that may disconnect at any moment.

The Short Answer

A live progress bar is a distributed system in miniature. The GPU worker knows about nodes and sampling steps. The product knows about jobs and stages. The browser needs authorized, ordered, resumable updates.

Progress is a view, not the source of truth

Transient events make the interface feel live. Durable job state makes it correct after refresh, reconnect, process restart, or a missed message.

The Event Path From GPU To Browser

  1. ComfyUI emits a node or sampler progress message with a provider prompt ID.
  2. The worker maps that message to the application job and a product stage.
  3. The worker persists meaningful state changes and publishes a safe event.
  4. An API process subscribes and finds authorized connections for that job.
  5. The browser reduces the event into local UI state.
  6. A slower refresh path reconciles the UI with durable state.

Movey uses this layered translation because internal node IDs should not become a permanent public contract. The UI can display “Encoding video” while the workflow changes from one encoding node to another.

Polling, Server-Sent Events, And WebSockets

TransportDirectionStrengthCost
PollingRequest and responseSimple, cacheable, resilientRepeated headers and stale intervals
SSEServer to browserNative event stream and reconnectOne-way, text framing, auth constraints
WebSocketTwo-wayLow-overhead frequent messagesConnection state and proxy complexity

RFC 6455 defines WebSocket as an HTTP upgrade followed by framed, two-way communication over one TCP connection. The WHATWG HTML standard defines EventSource streams using text/event-stream and supports a last-event identifier for reconnection.

Design A Product-Level Message Contract

{
  "type": "job.progress",
  "job_id": "job_456",
  "attempt_id": "attempt_2",
  "sequence": 17,
  "stage": "generating",
  "progress": 67,
  "message": "Generating motion",
  "occurred_at": "2026-07-23T21:00:00Z"
}

Include enough identity to reject stale messages. Sequence numbers help detect duplicates and reordering. Stage names should be stable product vocabulary. A human-readable message may change without breaking client logic.

ComfyUI’s server messages include execution_start, executing, progress, executed, cached-node notifications, and execution errors. A bridge should preserve diagnostic detail in structured logs while publishing only safe user-facing fields.

Ordering, Duplicates, And Reconnect

A reconnecting browser may receive an old event after it has already fetched a newer durable state. The reducer should compare sequence or version values rather than blindly applying arrival order.

  • Ignore events for another authenticated owner or job.
  • Ignore an earlier attempt after a retry starts.
  • Ignore a lower state version than the current snapshot.
  • Treat completed, failed, and cancelled as terminal for that attempt.
  • Fetch a fresh snapshot after reconnect before resuming live events.

Make Progress Percentages Honest

A sampler with value 6 and max 9 is two-thirds through its sampling loop. It is not necessarily two-thirds through wall-clock time. Model loading may dominate the beginning, and VAE decoding or video encoding may dominate the end.

Use measured stage weights when historical timing is stable. Otherwise show named stages and an indeterminate indicator. Never let a progress bar reach 100 before the output is durable and readable.

overall = completedStageWeight + currentStageWeight × stageFraction
A stage-weighted estimate when stage totals are measurable.

Every Progress Channel Needs Authorization

Knowing a job ID must not grant access to its progress or output. Authenticate the connection, authorize each subscription, and recheck ownership when the server sends data. Do not place long-lived secrets in URLs.

Events should not include raw prompts, signed asset URLs, stack traces, provider credentials, or filesystem paths. The browser needs a stage, percentage, safe message, and stable identifiers.

A Resilient Browser Strategy

  1. Load the current job snapshot over authenticated HTTP.
  2. Open the live channel and subscribe to the job.
  3. Apply only newer authorized events.
  4. When disconnected, keep the last known state and start slower polling.
  5. Reconnect with bounded backoff.
  6. Fetch another snapshot before trusting the resumed stream.
  7. Stop all refresh work when the job reaches a durable terminal state.

Frequently Asked Questions

Why use WebSockets for AI generation progress?

WebSockets provide a persistent two-way channel with low per-message overhead. They suit frequent progress, status, preview, and cancellation messages, but they need authentication, reconnect logic, and a durable fallback.

Is polling a bad design?

No. Slow polling is a valuable recovery path and may be the simplest primary design for infrequent updates. The problem is aggressive polling that substitutes repeated full reads for a well-defined event model.

Should progress percentages be exact?

Only when the underlying stages have measurable totals. A sampler step ratio is real, but model loading, queue time, upload, and encoding often need stage-based or estimated progress.

Sources

Protocol standards and current ComfyUI server documentation used for the transport and message behavior.

Keep reading

Related articles

All guides
Diagram tracing an AI generation job from browser to API, queue, GPU worker, storage, and progress channel
TechnicalInfrastructure

From Click to Clip: Inside an AI Generation Job

Follow an AI generation request through validation, durable job state, Redis-backed queues, ComfyUI execution, WebSocket progress, output storage, and failure recovery.

15 min readDifficulty 2/5
Timeline diagram showing an AI job moving through acceptance, queueing, timeout, retry, and one durable completion
TechnicalInfrastructure

Queues, Retries, and Idempotency for Reliable AI Jobs

Design reliable GPU jobs with logical job identities, attempt records, idempotency keys, bounded retries, leases, reconciliation, durable outputs, and exactly-once effects.

16 min readDifficulty 4/5
How Live AI Progress Reaches the Browser | Movey