Sync functions replicate records from an external API to your system continuously. To do this reliably, Nango uses a records cache โ an intermediate store that sits between the external API and your application. Every time you callDocumentation Index
Fetch the complete documentation index at: https://nango.dev/docs/llms.txt
Use this file to discover all available pages before exploring further.
nango.batchSave() or nango.batchDelete() inside a sync function, you are writing to this cache. Your application then reads from the cache using the GET /records endpoint or the Node SDK.
What the cache does
The records cache fulfils three roles: Change detection โ By tracking every record that has been synced, Nango can tell you which records are new, which have been updated, and which have been deleted. Your application only needs to fetch the delta, reducing bandwidth and processing on your side. Reliable data availability โ Fetching from external APIs is inherently unreliable: rate limits, timeouts, and transient errors are common. The cache decouples this unreliable step from your application. Once data lands in the cache, you can fetch it quickly and reliably. Observability โ The cache gives you visibility into the state of synced data directly from the Nango dashboard and API, including record counts, last sync times, and change history.How records are identified and compared
Each record in the cache is uniquely identified by two things:- Record ID โ The
idfield you set on each record in your sync function. This should match the unique identifier of the record in the external system (e.g. the external APIโs primary key). - Payload hash โ Nango computes a hash of the full record payload. When a record with the same ID is saved again, Nango compares hashes to determine whether the record has actually changed.
Be careful with fields that change on every fetch but donโt represent a meaningful change to the record, such as a
fetched_at timestamp. Including such fields in the payload will cause Nango to report spurious updates on every sync run. If possible, exclude or normalize these fields before calling batchSave().How records are stored
The cache only keeps the latest version of each record โ there is no versioning or history of payloads. When you callbatchSave() with an existing ID, the previous payload is overwritten.
When you call batchDelete(), you only need to pass the recordโs id. This does not remove the record from the cache. Instead, it marks the record as deleted (a soft delete), so your application can react to the deletion event. The last-known payload is preserved.
Fetching records: the change stream
The GET /records endpoint returns a chronologically ordered stream of record changes. Each entry in the stream includes:- The full record payload
- Metadata indicating whether the record was
ADDED,UPDATED, orDELETED - A cursor for tracking your sync progress
last_action (added, updated, or deleted) using the filter query parameter.
Cursors and sync progress
Every record change in the cache has a cursor attached to it. Cursors are opaque, ordered strings that let you:- Track how far youโve synced โ After fetching records, persist the cursor of the last record you processed. On the next fetch, pass it back to only receive changes that happened after that point.
- Paginate through large result sets โ The same cursor is used for pagination when there are more records than the page
limit.
- Node
- cURL
Re-syncing: preserve vs. clear the cache
See Re-syncing: resetting checkpoints and the cache in the Checkpoints guide for thereset / emptyCache options and their implications.
Cache summary
| Concept | Details |
|---|---|
| Writing to the cache | nango.batchSave() and nango.batchDelete() in sync functions |
| Reading from the cache | GET /records endpoint or nango.listRecords() SDK method |
| Record identity | Determined by the id field you set on each record |
| Change detection | Based on comparing payload hashes for the same id |
| Versioning | None โ only the latest payload is kept |
| Deletions | Soft delete โ record is marked as deleted, payload is preserved |
| Cursor | Opaque ordered string for tracking sync progress and pagination |
| Payload TTL | 30 days without update โ payload pruned |
| Full record TTL | 60 days without sync execution โ all records hard-deleted |
Related guides
- Sync functions - write records into the cache.
- Sync efficiency - keep records small and consume changes promptly.
- Deletion detection - mark records deleted in the cache.
- Get records API - fetch changed records from your app.