Skip to content

Bound sliding sync per-connection state under position replay#19924

Draft
erikjohnston wants to merge 2 commits into
developfrom
erikj/sliding-sync-position-buildup
Draft

Bound sliding sync per-connection state under position replay#19924
erikjohnston wants to merge 2 commits into
developfrom
erikj/sliding-sync-position-buildup

Conversation

@erikjohnston

Copy link
Copy Markdown
Member

Clients may resend the same sliding sync position many times, e.g. if they repeatedly fail to process our responses. Each such request records a new connection position, but the clean-up of old positions only ran the first time a position was used: it lives in get_and_clear_connection_positions, whose result is cached, so replayed positions never triggered it. A wedged client replaying one position could thus accumulate unboundedly many rows in sliding_sync_connection_positions (and, via the per-position state, in sliding_sync_connection_streams/_room_configs). Seen in the wild: ~1k positions on one connection over a few hours.

Fix by deleting all other positions for the connection whenever we persist a new one: only the position the request was based on (which the client may retry from, not yet having seen our response) and the newly created position remain valid.

Also update the connection's last_used_ts when persisting, since for replayed positions the cached read no longer does so; otherwise a connection in constant use from the same position would be expired as idle.

erikjohnston and others added 2 commits July 7, 2026 17:14
Clients may resend the same sliding sync position many times, e.g. if
they repeatedly fail to process our responses. Each such request
records a new connection position, but the clean-up of old positions
only ran the first time a position was used: it lives in
`get_and_clear_connection_positions`, whose result is cached, so
replayed positions never triggered it. A wedged client replaying one
position could thus accumulate unboundedly many rows in
`sliding_sync_connection_positions` (and, via the per-position state,
in `sliding_sync_connection_streams`/`_room_configs`). Seen in the
wild: ~1k positions on one connection over a few hours.

Fix by deleting all other positions for the connection whenever we
persist a new one: only the position the request was based on (which
the client may retry from, not yet having seen our response) and the
newly created position remain valid.

Also update the connection's `last_used_ts` when persisting, since for
replayed positions the cached read no longer does so; otherwise a
connection in constant use from the same position would be expired as
idle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant