Skip to content

Reduce RTC Polling#77058

Open
the-hercules wants to merge 2 commits into
WordPress:trunkfrom
the-hercules:enhance/reduce-rtc-polling-76631
Open

Reduce RTC Polling#77058
the-hercules wants to merge 2 commits into
WordPress:trunkfrom
the-hercules:enhance/reduce-rtc-polling-76631

Conversation

@the-hercules
Copy link
Copy Markdown

Closes #76631

Why?

High-level implementation overview

This update adds adaptive RTC polling for the HTTP polling transport using two signals:

  1. Network Information API when available (navigator.connection.effectiveType)
  2. Observed poll RTT fallback when that API is not available (Firefox, Safari, iOS browsers)

The goal is to reduce unnecessary polling on slower networks without changing the existing polling model or interfering with error backoff / background-tab behavior.

1. Network Information API path

For browsers that expose navigator.connection.effectiveType, we use it as an immediate hint for active-tab polling.

Implemented in:

  • packages/sync/src/providers/http-polling/network-info.ts
  • packages/sync/src/providers/http-polling/polling-manager.ts

What changed:

  • Added feature detection for navigator.connection?.effectiveType
  • Kept the existing multiplier logic:
    • 4g -> 1x
    • 3g -> 4x
    • 2g / slow-2g -> 10x
  • Continued capping active-tab polling at 25000ms so awareness stays below the server timeout
  • Kept support for the change event so pending polling can be rescheduled if the browser reports a new connection type mid-session

2. Cross-browser RTT fallback

For browsers that do not expose effectiveType, polling now adapts based on recent successful poll latency.

Implemented in:

  • packages/sync/src/providers/http-polling/latency-info.ts
  • packages/sync/src/providers/http-polling/polling-manager.ts

What changed:

  • Added a small internal helper to track the last 3 successful poll durations
  • Measured RTT around postSyncUpdate() in the polling loop
  • Only recorded successful polls
  • Used the average of the last 3 successful polls to choose a multiplier:
    • average < 500ms -> 1x
    • average >= 500ms and < 1500ms -> 4x
    • average >= 1500ms -> 10x
  • Applied that multiplier to the existing base interval:
    • collaborators -> 1000ms
    • solo editing -> 4000ms
  • Cleared RTT history when the last room unregisters so a new session starts cleanly

Polling behavior preserved

This change intentionally does not alter the rest of the transport model:

  • Background tabs still poll at 25000ms
  • Existing exponential error backoff is unchanged
  • Failed polls do not contribute to RTT sampling
  • retryNow() continues to affect retry timing only, not latency history
  • No browser sniffing or UA detection was added; this uses feature detection only

Result

With this change:

  • Chromium browsers get an immediate network-quality hint from effectiveType
  • Firefox / Safari / iOS browsers can still reduce polling on slower conditions via measured RTT
  • RTC polling remains conservative, capped, and compatible with the existing sync and awareness behavior

Use of AI Tools

Codex was used to strategize and plan and also for testing. Functionality is properly tested by human.

…d on network conditions and adding network-aware polling functionality.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 6, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: the-hercules <thehercules@git.wordpress.org>
Co-authored-by: alecgeatches <alecgeatches@git.wordpress.org>
Co-authored-by: chrisdavidmiles <chrisdavidmiles@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions github-actions Bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Apr 6, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 6, 2026

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @the-hercules! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@the-hercules the-hercules changed the title Eeduce RTC Polling Reduce RTC Polling Apr 6, 2026
@yogeshbhutkar yogeshbhutkar added the [Type] Enhancement A suggestion for improvement. label Apr 6, 2026
@alecgeatches alecgeatches added the [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration label May 19, 2026
@alecgeatches
Copy link
Copy Markdown
Contributor

Hello @the-hercules, thank you for this contribution! I'd like to review this, but could you please rebase or merge trunk first?

We merged a PR for a disconnect timing issue in #76966, roughly the same time this PR was opened. Note that #76966 changed the way disconnect backoff timing worked because the results were counter intuitive and multiplying caused disconnect dialogs to be more easily triggered.

From the Why? section in #76966:

The previous system used exponential back-off (pollInterval * 2, capped at 30s) and ran a time-based debounce depending on the number of collaborators. The two mechanisms interacted in ways that made changes like #76704 difficult to reason about.

Even though we increased both the poll interval and disconnect debounce by 4x, the exponential math worked out so just one failed request could cause a disconnect dialog:

Previous behavior (4s base poll interval, 2x backoff, 8s debounce):

t=0s:  Fail. Next retry in 8s  (4 * 2)
t=8s:  Retry.                  <- debounce fires at the same time, modal flashes

Because the backoff multiplied the base polling interval, the behavior was different in solo mode, and not in a useful way. Solo editing had fewer retries before showing the dialog, even though solo users are the least likely to hit CRDT conflicts from a brief disconnect. Collaborative editing had more retries, despite being the mode where stale state matters most. Adjusting either the backoff multiplier or the debounce timer required recalculating the tables for both modes to make sure the timing still made sense.

Predefined retry schedules fix all of this by making the timing readable at a glance. Each mode has its own array of delays, and you can see exactly when each retry happens and when the dialog appears without doing any math.

This PR is more focused on successful connecting timing, but I just wanted to note that we changed disconnects from a exponential back-off system. I'm not sure if that will affect your work here. I'm open to changing the implementation in #76966 as long as we fix the "difficult to reason about" part.

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

Labels

[Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository [Package] Sync [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reduce RTC polling frequency on slow connections

3 participants