Skip to content

Reduce redundant GitHub API calls when polling notifications #3101

Description

@joshfree

The problem

On every poll, Gitify re-fetches data it already has:

  1. Re-enriches every notification, even unchanged ones. For N visible notifications, getAllNotificationsenrichNotifications (src/renderer/utils/notifications/notifications.ts) issues ceil(N / 100) GraphQL detail queries every interval, with no change detection (enrich.ts, GITHUB_API_MERGE_BATCH_SIZE = 100).
  2. Disables caching on the list request. listNotificationsForAuthenticatedUser (client.ts) sets Cache-Control: no-cache, so the full notifications list is re-downloaded every poll even when nothing changed.

For someone watching busy repos, nearly every request each minute is redundant.

Why fixing it helps

GitHub's API makes the "nothing changed" case almost free — Gitify just isn't using the mechanisms:

  • Conditional requests (If-Modified-Since / If-None-Match) return 304 Not Modified with an empty body, and 304s don't count against the rate limit.
  • X-Poll-Interval tells clients the minimum safe poll spacing.

Adopting these turns the common steady-state poll from "re-download the whole list + re-fetch every notification" into "one conditional request that returns 304, zero detail fetches." Result: much lower API/
rate-limit usage and bandwidth, fewer throttled requests, and no change to user-visible behavior.
This especially helps heavy users and anyone running multiple accounts.

Proposed fixes (independent, in priority order)

  1. Skip re-enriching unchanged notifications. Cache the enriched subject keyed by account + id + updatedAt; reuse it when updatedAt is unchanged, only fetching cache misses. Prune to current
    notifications each cycle. Forge-agnostic — lives in the enrichment orchestrator.
  2. Conditional requests on the list. Drop Cache-Control: no-cache, send If-Modified-Since/If-None-Match, store the returned Last-Modified/ETag per account, and reuse the last list on 304. Localized to client.ts.
  3. Respect X-Poll-Interval. Poll no more often than max(userInterval, X-Poll-Interval) (useNotifications.ts currently uses only the fixed fetchIntervalMs).

References

Happy to open a PR for these.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or enhancement to existing functionalitypriority:mediumItems of medium importance. Applicable to most users or use-cases

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions