You want to know the instant a message lands in a connected mailbox. The naive fix is a cron job that calls the messages endpoint every minute, but that wastes most requests on inboxes where nothing changed, and it still misses anything that arrives and gets read inside the same window. The architectural choice underneath that problem is push versus pull, and it decides your latency, your request bill, and how often you drop a change.
This guide compares both models for email sync, shows the exact endpoints each one uses, and is honest about when a simple poll loop beats wiring up webhooks.
What is the difference between push-based and pull-based email sync?
Section titled “What is the difference between push-based and pull-based email sync?”Push-based sync means the provider tells you when a mailbox changes: Nylas detects a new message and sends a webhook to your endpoint, usually within a few seconds. Pull-based sync means your code asks on a schedule, calling GET /v3/grants/{grant_id}/messages every minute or so and diffing the result. Push moves work to the source; pull keeps the client in control.
The two models invert who initiates the call. With pull, your server owns the clock and burns one request per poll whether or not anything changed, so 1,000 idle mailboxes polled every 60 seconds cost 1.44 million requests a day for zero new mail. With push, the provider initiates, so an idle mailbox costs nothing and your endpoint only wakes up on a real change. That inversion is the whole tradeoff: pull is dead simple to reason about and debug, while push is cheaper at scale and faster, at the cost of running a public endpoint that has to verify signatures and absorb retries. Most production email integrations end up using both.
What is real-time email sync and how is it different from polling?
Section titled “What is real-time email sync and how is it different from polling?”Real-time email sync delivers a change to your application within seconds of it happening, through a webhook the provider pushes to your server. Polling can’t match that: a 60-second poll interval means an average detection delay of 30 seconds and a worst case of nearly 60. Shrinking the interval multiplies your request count linearly.
Real-time sync through Nylas uses the webhooks endpoint and the message.created trigger. You create one subscription per project, not one per mailbox, and the same subscription covers Google, Microsoft, iCloud, Yahoo, IMAP, and Exchange. Polling, by contrast, scales its cost with both the number of mailboxes and the poll frequency, and it still can’t see short-lived states: if a message arrives and a user reads it between two polls, a pure poll loop may never record that it was unread. Webhooks fire on each transition, so message.created and message.updated both reach you. The honest catch is that webhooks need a reachable HTTPS endpoint and HMAC verification, which a 10-line poll script skips entirely.
What are the advantages of asynchronous email sync design?
Section titled “What are the advantages of asynchronous email sync design?”Asynchronous design decouples the rate at which mailboxes change from the rate at which your servers do work. Instead of a poll loop that fires on a fixed clock regardless of activity, webhooks deliver an event only when something actually happens, so an idle hour costs zero requests and latency often drops under 5 seconds.
The async model also smooths load and survives failures better. The API queues and retries webhook deliveries when your endpoint is briefly down, so a 30-second deploy doesn’t silently lose events the way a skipped poll cron would. Each notification carries the object that changed, up to a 1 MB payload, which means most message.created events arrive with the full message and need no follow-up call. The flip side is operational: you now run an endpoint that must respond fast, return a 2xx quickly, and verify the X-Nylas-Signature HMAC-SHA256 header on every request. You also have to handle duplicates, because at-least-once delivery means the same event can arrive twice. That is real work, but it scales flat while polling cost grows with every mailbox you add.
Push vs pull email sync compared
Section titled “Push vs pull email sync compared”The table below compares the two models on the dimensions that decide an email integration: latency, request cost, missed-change risk, and operational burden. The Nylas push column uses a single message.created subscription across every provider, while pull uses repeated calls to the messages endpoint.
| Dimension | Pull (polling / IMAP IDLE) | Push (Nylas webhooks) |
|---|---|---|
| Latency | Half the poll interval on average (30 s at 60 s polls) | Typically under 5 seconds |
| Request cost | 1 call per mailbox per interval, even when idle | 0 calls when nothing changes |
| Missed-change risk | Misses states that start and end inside one interval | Fires on each transition (message.created, message.updated) |
| Setup | A cron job and a cursor; no public endpoint | One subscription plus a verified HTTPS endpoint |
| Scaling | Cost grows with mailboxes × frequency | Flat: one subscription covers all grants |
| Failure handling | Skipped poll loses the window | Queued retries; truncated payloads re-queryable |
How do I set up push sync with Nylas webhooks?
Section titled “How do I set up push sync with Nylas webhooks?”Create a webhook subscription that lists the trigger types you care about, then point it at a public HTTPS endpoint. The request below registers a subscription against POST /v3/webhooks for new mail. Nylas first sends a challenge to confirm the endpoint, then returns a webhook_secret you use to verify every later delivery’s HMAC-SHA256 signature.
curl --request POST \ --url 'https://api.us.nylas.com/v3/webhooks' \ --header 'Authorization: Bearer <NYLAS_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{ "trigger_types": ["message.created", "message.updated"], "webhook_url": "https://example.com/webhooks/nylas", "description": "New and updated mail", "notification_email_addresses": ["[email protected]"] }'Once the subscription is live, every new message in any connected grant arrives as a message.created notification. Payloads cap at 1 MB; if a message exceeds that, the API strips the body and appends .truncated to the trigger (for example, message.created.truncated), and you re-query the message by ID to fetch the rest. Verify the X-Nylas-Signature header on each request before you trust the body, and design your handler to tolerate the same event twice, since delivery is at-least-once. For the retry and dedupe playbook, see handle duplicate webhooks.
When is pull-based polling the simpler choice?
Section titled “When is pull-based polling the simpler choice?”Polling wins when you don’t run a public endpoint, when near-real-time latency doesn’t matter, or when you’re backfilling history rather than watching for change. A nightly digest, a one-time import, or a batch report has no reason to stand up webhook infrastructure. A single paginated sweep of GET /v3/grants/{grant_id}/messages is easier to write, test, and retry than a signature-verifying server.
The pull call below lists messages for one grant. Use limit to size each page and page_token to walk the rest; Nylas recommends a limit of 20 when listing to stay clear of provider rate limits. This is the same endpoint a webhook handler calls to re-fetch a truncated payload, so the read path is identical either way.
curl --request GET \ --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages?limit=20' \ --header 'Authorization: Bearer <NYLAS_API_KEY>'For first-time syncs, polling is the only sane approach: you can’t webhook your way through ten years of archived mail. Run a paginated backfill once, then switch to webhooks for ongoing change. When you connect an IMAP or Exchange account, Nylas signals that the initial sync finished with the grant.imap_sync_completed trigger, which is a clean handoff point from a one-time pull to live push. The full backfill pattern lives in backfill historical email.
What’s next
Section titled “What’s next”- Webhooks vs polling for a deeper look at the delivery model and retry behavior
- Backfill historical email for the one-time paginated pull before you switch to push
- IMAP vs Email API to compare raw IMAP IDLE against a unified webhook layer
- Sync Gmail, Outlook, and Exchange email for one sync pipeline across providers