Transaction Sync Windows and Lookback#
Each bank provider (Plaid, Akahu, Enable Banking) uses a distinct strategy to determine the date window for fetching transactions. The Sync model supports dynamic window expansion when multiple syncs queue up while one is still pending.
Plaid#
Plaid uses a cursor-based incremental sync via transactions_sync , so there is no explicit start_date passed per sync call — Plaid's API tracks position via a cursor. The historical window is established at link time: MAX_HISTORY_DAYS is requested when creating a link token , which is 730 days in production, 90 days in development .
Investment transactions use a date-based window and fall back to the same MAX_HISTORY_DAYS constant when no start_date is provided .
Akahu#
The determine_sync_start_date method in AkahuItem::Importer implements a three-level priority:
- Account-level override —
akahu_account.sync_start_dateif set - Item-level override —
akahu_item.sync_start_dateif set - Auto-computed:
- Incremental sync (has existing transactions +
last_synced_atpresent):last_synced_at - 7 days - Initial sync (no stored transactions):
90.days.ago
- Incremental sync (has existing transactions +
Both akahu_items.sync_start_date and akahu_accounts.sync_start_date are stored as date columns in the database , allowing per-item and per-account user overrides.
Enable Banking#
The determine_sync_start_date method in EnableBankingItem::Importer uses a two-level strategy:
- Incremental sync (has stored transactions):
- If
last_synced_atis known:last_synced_at - 7 days - Otherwise:
30.days.ago
- If
- Initial sync (no stored transactions): user-configured
sync_start_dateif set, otherwise3.months.ago
The 7-day overlap on incremental syncs (shared by both Akahu and Enable Banking) guards against late-arriving or modified transactions that may not appear in real-time.
Sync Model: Dynamic Window Expansion#
The Sync model stores an optional window_start_date / window_end_date on each sync record. If a new sync is requested while an existing sync is still pending (not yet started), the expand_window_if_needed method widens the pending sync's window to cover both the old and new request:
- Takes the earlier of the two start dates
- Takes the later of the two end dates
- If either side has a
nildate (unbounded), the result is alsonil/ unbounded - Only applies when the sync is still
pending— once a sync has started (syncing), its window is fixed
The window is validated to ensure window_start_date <= window_end_date .
Summary Table#
| Provider | Initial lookback | Incremental overlap | User override |
|---|---|---|---|
| Plaid | 730d (prod) / 90d (dev) at link time | Cursor-based (no date overlap) | Not applicable |
| Akahu | 90 days | last_synced_at − 7 days | Per-item or per-account sync_start_date |
| Enable Banking | 3 months | last_synced_at − 7 days (fallback: 30 days) | Per-item sync_start_date |