Skip to main content
All posts
Engineering5 min read

Fast Without Pretending

The August 14 mobile reliability work made PingRoom feel immediate while tightening the rules for rollback, reconciliation, account changes, retries, and stale network results.

An instant red Ping reflected in a slower server-confirmation path, with both paths converging on one verified result.

Speed is part of the PingRoom promise. Tap once and the room should respond immediately.

But a fast interface can behave in two ways. One moves before the network and knows how to recover. The other paints success, forgets the request is still uncertain, and leaves the user to discover the disagreement later.

The August 14 mobile source audit hardened optimistic Pings, Questions, Live Activities, room mutations, history, settings, attachment metadata, authentication, and refresh coordination around one principle:

Show the user’s intent immediately, but never confuse intent with confirmation.

This is a source-level engineering update, not a claim about a public release on that date.

Optimism Is A Contract

Quick Pings, custom Pings, Questions, and the first event in a Live Activity all travel through one mobile dispatcher. When a send is admitted, the sender’s room feed gets a temporary event immediately. The sender does not receive their own push, so waiting for a later rooms refresh would make the core action feel delayed.

That temporary event is not a decorative placeholder. It has enough structure to render the final shape: a Question has its prompt and options, an urgent Ping has its pending acknowledgement state, a live stream has its template and owner identity, and a Ping with files has its attachment metadata.

The PingRoom composer turning a prompt, options, link, and files into an immediate in-room Question.

If the request fails, the temporary event must leave. The cooldown must reopen for a real retry. The composer must recover the work that belonged to that request. If the server already persisted the event and a refresh reconciled the temporary row to a canonical one, a late rejection must not delete the delivered Ping.

The mobile source distinguishes optimistic identities from server identities. A sequence is included even when two sends happen in the same millisecond, so separate Pings never collide just because the clock returned the same number.

Duplicate Prevention Without A Frozen Button

The dispatcher reserves an outgoing intent before starting the request. An identical send already in flight, or repeated within the five-second cooldown, is rejected before it can create another notification. Non-live sends also reserve a durable idempotency key before transmission, so an interrupted process can reuse the same server identity instead of minting a duplicate.

The interface can return control without leaving every button spinning until a background refresh completes. The network owner performs the send, reconciles the room on success, and rolls back on failure.

The same boundary applies to answering a Question. Only one answer operation is admitted from a rendered cell at a time, and answer admission fails closed if there is no committed authenticated session. A stale notification, remounted cell, or account transition cannot keep ownership of an answer after its scope has changed.

The server still owns the terminal result. As described in the Question state machine, Pending may become Answered, Expired, or Cancelled, and terminal states do not reopen because a late tap arrived.

A Question moving from Pending to exactly one terminal state: Answered, Expired, or Cancelled.

Restore The Draft, Not The Past

A failed Question draft may contain much more than one line of text.

The hardened composer snapshots the title, emoji mode, raw emoji input, answer choices, link title and URL, acknowledgement setting, and uploaded attachments for the accepted operation. If that operation fails and nothing newer has happened, those exact values return so the person can correct or retry the send.

Restoration is allowed only while the failed operation still owns the active draft.

Every draft belongs to a room, an authenticated user session, and a generation of user intent. Opening a newer draft advances the generation. Moving rooms changes the scope. Logging out changes the authenticated owner. A delayed failure from the older operation may report, but it cannot reopen its composer over the newer one, attach files to another room, or delete an old account’s uploaded files using a new account’s credentials.

Rollback returns the current operation to its last honest state. Stale work cannot overwrite what the person did next.

Reconciliation Has Its Own Truth

The app must fetch authoritative room data and merge it without allowing a slow response to outrank a newer one.

The August 14 changes coordinate same-room fetches, isolate requests that can be cancelled, and let an explicit retry supersede a hung attempt. Callers waiting on the old request remain tied to the replacement result, while a late response from the abandoned generation is ignored. Initial-load failures schedule a backstop retry instead of quietly turning an error into an empty room list.

A conditional request for an unchanged room-icon manifest returns HTTP 304 with no JSON body. That is a cache hit, not a broken HTML response. The API client now classifies it as not_modified without logging a false error, while callers continue using the version they already have.

A successful mutation must not be rewritten by a failed refresh. Promoting an admin, removing an admin, or removing a member can commit successfully on the server and then encounter a transport error while refreshing rooms. The refresh failure is now handled separately, so PingRoom does not tell someone “Failed to make admin” after the role change already happened.

The operation reports two separate results:

  • Mutation success answers whether the requested change committed.
  • Refresh success answers whether this screen has already reloaded the latest representation.

Account And Live-Surface Fences

On iOS, deleting and reinstalling an app can leave a Keychain token behind while ordinary app storage is new. The August 14 source work added a paired random install identifier across Keychain and app defaults. A genuine mismatch identifies a reinstall and clears the surviving session; corroborating markers allow a lost defaults write to heal without signing out a valid installation. Fast auto-login is useful only when it belongs to this installation and this user.

Live Activities have a similar ownership boundary. On iOS 26, a push-started activity can receive its first per-activity update token before the usual update stream yields it. The native module now polls for that first token, and the JavaScript gate re-reads the current-token snapshot during evaluation. That gives the notification service another path to learn how to update the activity instead of leaving a live surface visible but stranded on its opening state.

What Fast Should Mean

Fast does not mean declaring success before the server speaks. It means separating what is already known from what is still pending.

PingRoom can render the tapped intent, block an identical request already in flight, and reject stale continuations after a room or account change. It then reconciles the authoritative result and reverses only the state that still belongs to that operation.

That is fast without pretending.

PingRoom

The Ping that cuts through.

Keep reading

Product

Share a Point, Not a Trail

A custom Ping or Question can now carry one deliberately chosen place, with a quiet feed preview, a useful map sheet, and no background location trail.

3 min read
Product

Urgent Is Not Confirmation

Urgent now controls time-sensitive delivery; confirmation asks for a recorded human response. Either can stand alone, and a Ping can carry both when the moment needs both.

3 min read