> ## Documentation Index
> Fetch the complete documentation index at: https://nango.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Real-time syncs with webhooks

> Combine webhooks from external APIs with periodic polling for a reliable, real-time stream of changes.

Nango supports real-time syncs using [webhook functions](/guides/functions/webhook-functions). You can rely entirely on webhooks or combine them with polling to ensure you never miss data.

## What is a real-time sync

Real-time sync involves receiving webhooks from external APIs and processing them inside a sync function. By default, sync functions poll data at a set frequency, but they can also be configured to handle webhooks for real-time updates.

When processed in a sync:

* The webhook triggers the execution of a Nango sync script
* The script extracts data from the webhook and optionally fetches additional data from the external API
* The modified data is stored in the Nango cache

Whenever the cache is updated, Nango sends a [sync completion webhook](/guides/platform/webhooks-from-nango#sync-webhooks) to notify your application of new data. This entire process happens in real-time.

### Webhooks & periodic polling

Webhooks can fail due to external API outages or unordered events. Periodic polling ensures data consistency by reconciling any missed updates.

If you use webhooks for real-time syncs, we recommend always combining them with a polling sync function.

### Near real-time syncing

As an alternative to real-time syncing, consider **near**-real-time syncing by polling at a higher frequency, which is simpler. Sync functions can run as frequently as every 30 seconds.

This is more resource intensive, but can be a good compromise if you are only syncing data for a handful of [Connections](/guides/auth/auth-guide#overview).

## Implement a real-time sync

### Step 1 — Setup prerequisites

To create a real-time sync, you need:

* Webhooks from the external API enabled. Follow [Webhook functions](/guides/functions/webhook-functions).
* A sync function for the object you want to sync. See [Sync functions](/guides/functions/syncs/sync-functions).

### Step 2 — Enable webhooks processing

To enable the real-time sync, define `webhookSubscriptions` and `onWebhook` in your sync function:

```typescript theme={null}
export default createSync({
  exec: async (nango) => {
        // Use for periodic polling.
  },

  webhookSubscriptions: ['contact.propertyChange'], // Webhook event type to listen to

  // Webhook handler
  onWebhook: async (nango, payload) => {
    if (payload.subscriptionType === 'contact.propertyChange') {
      const updatedObject = {
        id: payload.objectId,
        [payload.propertyName]: payload.propertyValue
      };

      // Use nango.batchSave() or nango.batchUpdate() to save/update records.
    }
  }
});
```

To check if a sync supports webhooks, navigate to the *Integrations* tab > select an integration > *Endpoints* sub-tab > check the function settings for webhook subscriptions.

## Sync concurrency considerations

When a polling run and a webhook race to update the same record, the later write wins by default — which can clobber a fresher webhook update with stale polled data. To prevent that, set a merging strategy at the start of your function:

```typescript theme={null}
export default createSync({
  exec: async (nango) => {
    // Don't overwrite records that were modified after this batch was fetched
    await nango.setMergingStrategy({ strategy: 'ignore_if_modified_after' }, 'Contact');

    const contacts: Contact[] = [];
    await nango.batchSave(contacts, 'Contact');
  }
});
```

Two strategies are available:

* **`override`** (default) — applies updates regardless of last modification time. May overwrite real-time webhook updates with older polled data.
* **`ignore_if_modified_after`** — preserves records that were modified after the current batch was fetched. **Recommended** when you combine polling with webhooks.

Run `batchSave` / `batchUpdate` / `batchDelete` calls sequentially (not in parallel), and persist data promptly after fetching — concurrent batch operations can race against each other.

## Related guides

* [Webhook functions](/guides/functions/webhook-functions) - process external API webhooks in Nango.
* [Webhook forwarding](/guides/platform/webhook-forwarding) - forward provider webhooks to your app.
* [Sync functions](/guides/functions/syncs/sync-functions) - keep a polling sync as reconciliation.
* [Webhooks from Nango](/guides/platform/webhooks-from-nango) - consume sync completion notifications.
