AL+

Language: RO (română) EN (English)

Email us: paul@alplustech.com

Looking back at the week of 28 October–3 November 2026

WebSocket delivery order needs a matching worker execution order

Action Cable needs command execution order within each connection. The Rails change preserves that boundary while other connections can run in parallel.

Citiți articolul în română

An ordered WebSocket stream does not, by itself, preserve the order in which server workers execute commands. When subscription state depends on sequence, the server needs to maintain that order for each connection. Concurrency across different connections can remain intact.

This retrospective covers the week of October 28, 2026, using evidence available through November 8. The October 30 Rails newsletter highlights a change to per-connection command ordering. It describes work in the Rails codebase, not proof that a particular stable gem or running application already contains the change.

The queue after the transport

The primary pull request explains the problem at the worker boundary. Messages from one connection were dispatched as separate worker jobs, allowing concurrent or reordered execution. Its author account is dated October 25; the page records a merge into main on October 27. Those dates describe discussion and integration, rather than deployment.

The distinction is easy to lose in an architecture conversation. A transport can deliver command A before command B while a worker finishes B first. Once work is submitted independently, the server needs an additional sequencing rule if B assumes that A has changed shared connection state. The existence of the ordered stream no longer answers the application question.

For a hypothetical room interface, consider leaving a subscription and immediately subscribing again. If the new subscription is processed while the old one still exists, the state the server sees differs from the user's intended sequence. If removal follows afterward, the final state can also differ. This is an illustration of the ordering dependency, not a report of an AL+ experiment.

A successful socket connection therefore says little about whether a subscription transition completed as intended. The business symptom could be an interface that appears connected while it waits for information. That possibility should guide diagnosis toward the state transition, rather than encouraging a conclusion that reliable transport has ruled out ordering problems throughout the server.

Preserve the right unit of order

The pull request describes serialized execution for work associated with one socket while keeping the worker pool. Different connections can still execute concurrently. That scope is the useful architectural idea: order the jobs that share the connection's sequencing assumptions without putting every connected user behind a single global queue.

A global lock would be a poor default response to a local ordering requirement. It would couple unrelated users to one another's work. In contrast, a connection-level boundary makes the dependency explicit. If two commands belong to the same state transition sequence, their relative execution matters. Work for another connection does not automatically belong to that sequence.

This does not make every slow handler harmless. Serial work on one connection can delay later work for that connection. A team evaluating the design should understand that tradeoff instead of promising both unrestricted parallel execution and strict sequencing for the same operations. The desirable outcome is predictable semantics with concurrency placed where those semantics permit it.

That distinction also helps a technical lead discuss capacity. A connection count and a worker count describe different things. Neither alone proves that commands are ordered correctly or that latency is acceptable. Capacity decisions need their own evidence; the historical change supplies a correctness argument, not a transferable performance number for another service.

Why a client workaround is insufficient

The strongest practical objection is that clients can avoid overlapping subscription changes. A well-behaved client that waits for an acknowledgement may reduce exposure. For an application with one controlled client, that can look easier than changing server dispatch. The approach deserves consideration when assessing an existing system's constraints.

Its limitation is ownership of the guarantee. A delay chosen by a client is not proof that earlier server work has completed. Other clients may also make different choices. When the server accepts a sequence whose meaning depends on prior commands, keeping the sequencing rule at that server boundary gives the contract a clearer owner.

This is not an argument that client behavior never matters. A reconnecting client still needs sensible recovery behavior, and the application still needs a definition of what counts as a completed subscription. Those concerns complement server ordering. They should not be used to imply that one worker-dispatch fix solves every failure visible in a real-time interface.

Keep the guarantee narrow

Per-connection execution order does not establish exactly-once delivery, global event order or ordering across nodes. A new connection after reconnection is also a different boundary from the original socket. Application requirements that span those boundaries need their own design and evidence. Expanding a local guarantee into a distributed one would conceal work that remains.

For maintenance planning, distinguish the upstream change, the version your application uses and the behavior you have actually verified. A main-branch merge establishes only the first of those. A proposed upgrade should identify where the fix enters the intended release before anyone promises that deployment will resolve a specific symptom.

Software maintenance should preserve such boundaries in the handover. Describe which commands depend on sequence and where that sequence is enforced. The decision to retain concurrency then becomes straightforward: keep independent connections concurrent, and make each connection's state transitions follow the order the application expects.