Skip to content

fix(granola): add incremental sync with early termination#436

Open
aculich wants to merge 1 commit intorowboatlabs:mainfrom
aculich:pr/granola-incremental-sync
Open

fix(granola): add incremental sync with early termination#436
aculich wants to merge 1 commit intorowboatlabs:mainfrom
aculich:pr/granola-incremental-sync

Conversation

@aculich
Copy link
Copy Markdown
Contributor

@aculich aculich commented Mar 18, 2026

Summary

Reduces API calls and sync time for Granola integration by:

  1. Passing updated_since parameter to the API (works if API supports it)
  2. Early termination after 20 consecutive unchanged documents (fallback)

Fixes #435

Problem

The Granola sync fetches ALL documents from the API on every sync cycle, even when most documents haven't changed. With 500 meetings, this means ~50 API calls with 1-second delays = 50+ seconds per sync, even when nothing changed.

Solution

Dual strategy with graceful fallback:

  1. Try updated_since parameter - If the Granola API accepts this parameter, it will return only documents updated since the last sync, drastically reducing API calls.

  2. Early termination fallback - If the API ignores the parameter (returning all docs anyway), the sync stops after hitting 20 consecutive documents that haven't changed since the last sync. This works because the API typically returns documents in a consistent order.

Changes

apps/x/packages/core/src/knowledge/granola/sync.ts:

  1. Add EARLY_TERMINATION_STREAK = 20 constant
  2. Modify getDocuments() to accept optional updatedSince parameter
  3. Pass state.lastSyncDate to API request as updated_since
  4. Track unchangedStreak counter in sync loop
  5. Break out of pagination when streak reaches threshold

Testing

  1. Enable Granola integration with an account that has many meetings
  2. Start the app and observe console logs for sync behavior
  3. On first sync: all documents should be fetched (no early termination)
  4. On subsequent syncs: should see "Early termination: 20 consecutive unchanged docs" log
  5. If a new Granola meeting is created, it should be picked up on next sync

Impact

  • First sync: No change in behavior (all docs fetched)
  • Subsequent syncs: Dramatically faster when no changes (~2-3 API calls vs ~50+)
  • API rate limit consumption significantly reduced

Made with Cursor

The Granola sync was fetching all documents from the API on every sync,
even when most had not changed. This adds two improvements:

1. Pass updated_since parameter to the API (if supported, will reduce
   docs returned; if ignored, fallback kicks in)
2. Early termination after 20 consecutive unchanged documents, stopping
   the pagination loop when we reach the older unchanged portion

This significantly reduces API calls and sync time for users with many
Granola meetings.

Made-with: Cursor
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 18, 2026

@aculich is attempting to deploy a commit to the RowBoat Labs Team on Vercel.

A member of the Team first needs to authorize it.

@Bortlesboat
Copy link
Copy Markdown

This still looks like the right direction for #435. The issue description itself already proposes basically this two-part approach: try updated_since, then fall back to early termination when the API ignores it.

Right now the main blocker seems to be that the branch is conflicted with main, not that the idea is unsound. If the author is still around, a rebase would make this much easier to evaluate without reopening the design discussion from scratch.

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.

Granola sync fetches entire history on every sync instead of incremental updates

2 participants