Skip to content

Debounce dashboard refresh dispatches in the webhook function #172

Description

@trask

The Netlify webhook dispatches one workflow run per accepted event. Bursty repositories generate far more runs than the dashboard needs, and job-level concurrency then cancels most of them.

Measured on 2026-07-28 against opentelemetry-collector-contrib:

  • GitHub Actions opens a separate check suite per workflow, so one push to a PR produces ~17 check_suite.completed events, hence 17 dispatches.
  • Worst burst observed: 53 dispatches for a single PR in 77 seconds.
  • Across a sample of 1,501 dashboard-eligible events, 82% were check_suite.completed.
  • 81% of completed dashboard runs in the sampled window were cancelled by concurrency.

Every dispatch in a burst produces the same dashboard output, because each run re-reads the full statusCheckRollup. Only the last one carries new information.

Proposal: collapse events per repository + PR number before dispatching.

  • On each accepted webhook, record lastEventAt in a Netlify Blobs entry keyed by ${repository}#${pr_number} instead of dispatching.
  • A scheduled function runs every minute and dispatches once a PR has been quiet for ~45s, then records lastDispatchAt.
  • Flush on lastDispatchAt < lastEventAt rather than a boolean, so a lost update from concurrent writes costs one extra tick instead of a dropped refresh.

Simulated against the real event stream, a 60s trailing debounce on all events removes 66% of dispatches. Leading-edge and check-suite-only variants both scored worse (54% and 52%), so the simplest policy is also the best one.

Trade-off: refresh latency goes from near zero to roughly 45-105 seconds. The hourly cron remains the backstop, and duplicate dispatches stay harmless because the existing concurrency group absorbs them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions