Get AI summaries of any video or article — Sign up free
Remix's Concurrent Submissions Are Fundamentally Flawed thumbnail

Remix's Concurrent Submissions Are Fundamentally Flawed

The PrimeTime·
5 min read

Based on The PrimeTime's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Remix’s “submission and revalidation” can still commit stale data to the UI when multiple mutations overlap and revalidations read/finish out of order.

Briefing

Remix’s “concurrent submissions” and its related “submission and revalidation” safeguards are portrayed as unreliable for real-world apps, especially when multiple mutations overlap. The core claim is that even with mechanisms meant to prevent stale UI updates, race conditions can still surface—leading to UI flicker, “deleted” items reappearing, or users seeing state that doesn’t match what the server ultimately committed.

The argument starts with a broader design debate: where application state should live—client or server. Client-side state can improve perceived responsiveness and enable rich interactivity, but it also risks divergence when server truth arrives late. Server-side state can reduce divergence, yet it still requires careful handling of latency and ordering. The discussion frames “offline support” as a weak justification for client-heavy state in typical websites, while latency and interactivity are treated as solvable even with server-driven approaches.

From there, attention narrows to Remix’s specific concurrency model. “Submission and revalidation” is described as a two-step pattern: after a mutation (like a form post that triggers a patch/delete), the client issues a follow-up request to reload data. That already costs extra round trips. More importantly, the concurrency promise—avoiding stale commits when overlapping actions occur—is challenged with concrete timing diagrams. The critique hinges on an incorrect assumption: that the revalidation that finishes first corresponds to the “earlier” or “correct” version of data. In overlapping requests, revalidation can read from the database at different moments, so an earlier revalidation may commit later to the UI, effectively rolling the interface backward in time.

A practical example makes the failure mode tangible: deleting multiple rows quickly can cause the UI to temporarily remove all rows, then “bring back” a row due to an out-of-order revalidation read, and later correct itself. The same pattern generalizes to non-trivial mutations where one action affects many properties—tracking what should be visible becomes difficult, and the UI can oscillate between states.

The discussion then explores why “just wait to revalidate until all submissions finish” is not a free fix. Doing so would require grouping actions that “collide,” stalling updates until the last one completes, and still not guaranteeing correctness when concurrent submissions modify overlapping resources—particularly in horizontally scaled or serverless setups where requests may hit different instances, experience cold starts, or encounter garbage-collection pauses.

Alternative solutions are offered as conceptually stronger but operationally complex: causal ordering (ensuring later operations depend on earlier ones), database-level serialization/locking (with performance and deadlock risks), sticky sessions plus ordering logic, or persistence via Phoenix LiveView-style long-lived connections where events are processed in order. The conclusion is that concurrent submissions driven by server state can become a source of race conditions and inconsistencies, and that addressing it robustly requires ordering guarantees or persistence—not just best-effort cancellation or timestamps.

Finally, the critique extends to Remix’s cancellation behavior: canceling a submission may not prevent the server from processing it if the request already crossed proxies/load balancers and entered the event loop, or if infrastructure timing differs. The result can be stale UI immediately after an action, potentially escalating from cosmetic glitches to user-impacting errors (e.g., a “Buy now” button reflecting fewer line items than what the server actually stored).

Cornell Notes

The central issue is that Remix’s concurrency approach—especially “submission and revalidation”—cannot reliably prevent stale UI updates when multiple mutations overlap. The pattern uses a second request to reload data after a mutation, but overlapping revalidations can read from the database at different times and commit results out of order. That can make the interface roll backward (e.g., deleted items reappearing) until later requests correct it. The critique argues that robust fixes require stronger ordering guarantees (causal ordering, sticky-session ordering, database serialization/locking, or persistent connections like Phoenix LiveView), not just best-effort cancellation or timestamps. The stakes range from flicker to potentially incorrect user decisions if the UI diverges from what the server committed.

What is “submission and revalidation,” and why does it create a correctness problem under concurrency?

Submission and revalidation is described as: (1) send a mutation request (post/patch/delete), then (2) issue a follow-up request to load the updated data and commit it to the UI. Under concurrency, multiple submissions can overlap, so multiple revalidations can be in flight. If an earlier revalidation reads the database before a later mutation commits, but that earlier revalidation finishes and updates the UI after the later one, the UI can reflect an older state—effectively rolling the interface backward in time.

Why is the “first revalidation finishes = correct version” assumption considered wrong?

The critique points to a diagram where revalidation reads from the database at different moments (labeled with an added “R” step). Even if submissions start in order, revalidation completion order can differ. A revalidation that finishes first may have read before a later submission’s effects were committed, so committing it to the UI can overwrite newer state. The UI then “jumps” forward later when the correct revalidation finally commits.

How does the deletion example illustrate the race condition?

Imagine a table with three rows and a delete button for each row. If three delete submissions are triggered quickly, the first revalidation might remove all rows from the UI. Then a second revalidation—reading at a moment when the third row’s deletion hadn’t been committed yet—can bring the third row back. Later, another revalidation corrects the UI again. The example shows how out-of-order reads/commits can cause visible inconsistencies.

Why doesn’t “just revalidate after all submissions complete” solve everything?

Waiting for the last submission to finish would require the system to know which actions “collide” and to group them, potentially stalling UI updates until the slowest overlapping mutation completes. Even then, correctness is not guaranteed when concurrent submissions modify overlapping resources: without serialization or convergence rules, there’s no guarantee the “last submission sent by the user” is also the “last applied on the server,” especially across multiple instances.

What ordering/persistence approaches are proposed as more reliable alternatives?

Several are discussed: (1) causal ordering, where later submissions carry dependency information so the server can order updates and reads; (2) sticky sessions plus server-side ordering logic so overlapping requests hit the same instance; (3) database transactions/locks to enforce per-client ordering, though this risks deadlocks and performance hits; and (4) persistence via Phoenix LiveView-style long-lived connections (websockets/long polling tied to a stable server-side process) so events are processed in order. Long polling alone can reintroduce routing/order problems unless the session is pinned to the same server-side process.

Review Questions

  1. In overlapping submissions, what specific mismatch between “revalidation completion order” and “database read time” can cause the UI to revert to an older state?
  2. What additional guarantees are required to make causal ordering feasible in a horizontally scaled environment, and why do sticky sessions matter?
  3. Compare the trade-offs between database locking/serialization and persistent event ordering (e.g., Phoenix LiveView) for preventing stale UI after concurrent mutations.

Key Points

  1. 1

    Remix’s “submission and revalidation” can still commit stale data to the UI when multiple mutations overlap and revalidations read/finish out of order.

  2. 2

    The critique targets an incorrect expectation that the earliest revalidation completion corresponds to the correct (latest) database state.

  3. 3

    Concurrent deletes can produce visible UI rollback, such as deleted rows reappearing until later requests correct the interface.

  4. 4

    Deferring revalidation until all overlapping submissions finish requires collision grouping and can degrade UX by stalling updates.

  5. 5

    In serverless or horizontally scaled deployments, requests may hit different instances, experience cold starts or GC pauses, and lose any implicit ordering guarantees.

  6. 6

    Cancellation doesn’t necessarily prevent server-side effects if the request already progressed through proxies/load balancers and the event loop.

  7. 7

    More robust fixes rely on ordering guarantees (causal ordering, sticky-session ordering, database serialization/locking, or persistent connections like Phoenix LiveView), not just best-effort client/server synchronization.

Highlights

The central failure mode is out-of-order revalidation commits: an earlier revalidation can read before a later mutation commits, then overwrite newer UI state when it finishes later.
“Submission and revalidation” costs extra round trips and still can’t reliably prevent stale UI under concurrent mutations.
A concrete scenario: deleting multiple rows quickly can temporarily resurrect a row due to revalidation reading at different database times.
Cancellation is not a guaranteed safety net when infrastructure timing differs—requests may still be processed after being “canceled” on the client.

Topics

  • Remix Concurrency
  • Submission and Revalidation
  • Race Conditions
  • Causal Ordering
  • Phoenix LiveView

Mentioned

  • Jose
  • UI
  • HTM X
  • SQS
  • HTTP
  • HTTP2
  • HTTP3
  • TCP
  • V8
  • GC