Skip to content

perf(mobile): stop following presence for people no longer shown - #9480

Draft
brow wants to merge 2 commits into
mainfrom
tomb/mobile-presence-release
Draft

brow wants to merge 2 commits into
mainfrom
tomb/mobile-presence-release

Conversation

@brow

@brow brow commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator

#9444 narrows the live presence subscription (kind 20001) to the people the app has shown this session. That set only grows, so scrolling through a long DM list or opening many profiles keeps receiving presence for people who are no longer on screen, and each new person reopens the subscription with everyone seen so far. This was raised in Jude's review.

With this change, presence follows only who is on screen now:

  • track returns a release callback. DM rows and profile sheets release when they unmount. Counts are per person, so someone shown in a DM row and an open profile sheet stays followed until both are gone.
  • A person nobody has shown for at least 30 seconds is retired: dropped from the tracked set and the cache, and the live subscription is replaced with one for the people still shown. A sweep every 30 seconds retires everyone whose own 30 seconds are up, so each person stays followed for 30 to 60 seconds after their release and the subscription narrows at most once per 30 seconds. Scrolling back within 30 seconds keeps the current subscription.
  • A read that started before someone was retired doesn't fill in their presence if they are shown again; they wait for a read of their own.
  • When nobody is shown, the stream closes, and the next person shown opens a new one immediately.
  • Switching communities keeps following people still on screen, instead of dropping everyone.

Regressions

  • Mention picker ranking. The picker reads the presence cache without tracking anyone itself, so it ranks by presence only for people currently on screen (before, also for anyone shown earlier in the session). Keeping a retired person's last value would show stale presence, which is worse.
  • Dot pop-in. A retired person's dot is missing when they come back (scrolling back after 30 seconds, or switching the Home filter to Solo and back after 30 seconds) until the replacement subscription is ready and their snapshot read returns. On a slow link that can take seconds. Before, the dot stayed for the whole session.
  • Network. A retirement costs one replacement REQ and a CLOSE, at most once per 30 seconds of scrolling. A person shown again after being retired costs one snapshot read, the same as the first time they were shown.
  • Reliability. Narrowing uses perf(mobile): subscribe to presence only for people on screen #9444's replacement path (the old stream stays until the new one is ready), so a failed narrowing keeps the wider stream and the poll retries it.

Validation

iPhone 12 mini on Builderlab (measured on bda9e214f, before the sweep change), cold launch, scroll the Home list to the bottom and back to the top, then 60 s idle:

#9444 head This PR
Live presence authors at the end 37 (only grows) 1 (37 at the bottom, then 11, then 1)
Presence events while idle (60 s) 29 (10.7 KB) 0
Presence REQs during the run 36 37

Presence dots still show on the DM rows visible at the bottom of the list. Both heads still reopen the subscription once per newly shown person while scrolling (36 swaps for 37 people); batching those during a fling would be the next bound, and is not part of this PR.

Added tests:

  • A person shown in two places stays followed until both release. Released people leave the subscription only after the delay, and their late live events are ignored.
  • Showing someone again within the delay keeps the same subscription and their cached presence.
  • Releasing everyone closes the stream, and the next person shown gets a new subscription and a snapshot read right away.
  • Scrolling 500 rows past a window of 10 leaves a subscription for exactly the last 10, with exactly two replacement opens after scrolling stops (the sweeps 30 s apart).
  • A person released 29 seconds after another keeps their subscription and cached presence when the first one is retired, and is retired at a later sweep.
  • A person retired while their snapshot is in flight stays absent.
  • A read started a second before someone is retired doesn't fill them in once they're shown again; the other people in that read keep their results, and the person's own read does.
  • Production seam: removing a DM row from the Home list stops following that person after the delay (the stream closes and the cache empties).

Each guard was mutation-checked: removing it fails at least one of these tests.

Changed test: the community-switch snapshot test now expects people still on screen to be read in the new community.

Full mobile suite: 4857 passed, 71 skipped (on ca0066d, after rebasing onto main).

@brow

brow commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-13T21:19:18.073085Z 6c49173 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: bda9e214f5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@brow

brow commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 6c491736d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Base automatically changed from tomb/mobile-presence-tracked-only to main November 13, 2026 21:32
square-tomb and others added 2 commits November 13, 2026 13:34
Presence tracking now hands back a release. DM rows and profile sheets
release on unmount, and people nobody has shown for 30 seconds leave the
tracked set, the cache and the live subscription, which narrows to who is
still on screen. With nobody shown the stream closes.

Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz>
Signed-off-by: Tom Brow <tomb@squareup.com>
Retire released keys in a 30 s sweep that takes only those released at
least the delay ago, so a key released just before the sweep keeps its
coverage while the subscription still narrows at most once per delay.
Retiring a key also bumps its revision, so a read started in its previous
lifetime can't fill it in once it is shown again.

Signed-off-by: Tom Brow <tomb@squareup.com>
@brow
brow force-pushed the tomb/mobile-presence-release branch from 6c49173 to ca0066d Compare November 13, 2026 21:40

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants