Skip to content

WorkerHandler blocks the main thread under event bursts #20547

Description

@logaretm

WorkerHandler.postMessage in @sentry-internal/replay attaches a fresh 'message' listener to the compression worker for every request, and removes it only when the matching response arrives. Under a burst of N in-flight requests, every worker response is dispatched to all N attached listeners (each then runs an id/method check and returns), producing O(n²) main-thread dispatch work.

This was hit in production by two enterprise customers when Zendesk's web widget started inserting CSS rules at high frequency: rrweb emitted a mutation per rule, Replay forwarded each via postMessage, and the listener fan-out made the page unresponsive for several seconds.

Source: packages/replay-internal/src/eventBuffer/WorkerHandler.ts#L71-L106

public postMessage<T>(method, arg): Promise<T> {
  const id = this._getAndIncrementId();
  return new Promise((resolve, reject) => {
    const listener = ({ data }) => {
      if (response.method !== method) return;
      if (response.id !== id) return;
      this._worker.removeEventListener('message', listener);
      // resolve/reject…
    };
    this._worker.addEventListener('message', listener); // ← N listeners during burst
    this._worker.postMessage({ id, method, arg });
  });
}

Reproduction: https://github.com/logaretm/sentry-replay-worker-quadratic-repro

Activity

  1. self-assigned this
    on Apr 28, 2026
  2. linear-code commented on Apr 28, 2026

    @linear-code
  3. added 2 commits that reference this issue on Apr 28, 2026
    08a0812
    6708ff2
  4. sbimochan commented on Apr 29, 2026

    @sbimochan

    Amazing! will test it out soon.

  5. github-actions commented on Apr 29, 2026

    @github-actions
    Contributor

    A PR closing this issue has just been released 🚀

    This issue was referenced by PR #20548, which was included in the 10.51.0 release.

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions