An integration has to answer a basic question before it can move any data: how will it know something changed?
Polling asks the source system on a schedule. A webhook lets the source system call your integration when an event happens. Webhooks usually win on speed and API efficiency. Polling usually wins on setup simplicity and recovery. A reliable design starts with the business requirement, not a blanket rule that one method is better.
How the two patterns work
With polling, a job might ask a CRM every five minutes for contacts updated since its last successful run. The job stores a cursor or timestamp, processes each page, and advances its checkpoint only after the records are safely handled.
With webhooks, the CRM sends an HTTPS request when a contact changes. Your endpoint verifies the request, records the event, returns a success response quickly, and processes the work asynchronously. GitHub's official webhook guidance recommends secrets, HTTPS, unique delivery identifiers, and redelivery handling. Those are production requirements, not optional polish.
Some providers send a complete changed object. Others send only a notification that something changed. Google Calendar, for example, says its push notification has no message body, so the receiver must call the API to retrieve the change details. Its documentation also warns that a small percentage of messages can be dropped under normal conditions. That is why “we use webhooks” does not mean “we can never miss an update.” See Google's push notification guidance.
Choose webhooks when delay matters
Webhooks fit events that should start work within seconds: a paid invoice granting access, a new lead entering a response queue, or an appointment cancellation stopping scheduled reminders. Polling every minute could approximate that speed, but it creates requests even when nothing has changed and can collide with API rate limits.
The tradeoff is operational complexity. Your endpoint must be publicly reachable, authenticate the sender, tolerate bursts, and handle retries. It also cannot assume events arrive once or in order. Stripe explicitly says webhook events may be delivered more than once and are not guaranteed to arrive in generation order. Its webhook documentation recommends logging processed event IDs, handling work asynchronously, and retrieving missing objects through the API when necessary.
A safe webhook path normally does this:
- Verify the signature or shared secret before trusting the payload.
- Store the provider's event ID and reject duplicate work without rejecting the delivery.
- Put accepted work on a durable queue, then respond before the provider times out.
- Fetch the current source record when event ordering could make the payload stale.
- Retry transient failures with backoff and send exhausted failures to an operator-visible queue.
The business failure mode is not simply “the webhook endpoint went down.” It is a retry that creates a second invoice, an older event that overwrites a newer status, or a slow downstream API that causes a delivery storm. Idempotency and ordering rules prevent those failures.
Choose polling when simplicity and catch-up matter more
Polling is often the practical choice when the source has no webhook, when updates can be several minutes old, or when a periodic batch is easier to audit. Nightly invoice reconciliation, hourly inventory imports, and daily reporting feeds rarely need an event-driven receiver.
A good poller does not repeatedly download every record. It requests incremental changes using a durable cursor, sync token, update timestamp, or monotonically increasing ID. Microsoft Graph's delta query documentation shows the pattern: perform an initial sync, save the returned link or token, then request only later changes. It also documents replays and expired tokens, so the client still needs deduplication and a path back to a full sync.
Polling has its own failure modes:
- A timestamp window can miss records when clocks differ or several updates share the same timestamp.
- Advancing the checkpoint before processing finishes can turn a temporary error into permanent data loss.
- Large result sets can be incomplete if pagination is ignored.
- Deleted records disappear unless the API exposes tombstones or a change feed.
- Aggressive intervals can trigger throttling; GitHub's REST API rate-limit guidance requires clients to respect reset and retry headers.
Use an overlap window when timestamps are the only available cursor, then deduplicate by a stable source ID and version. Persist the checkpoint after the batch commits, not when the request starts. Treat a failed page as unfinished work rather than skipping forward.
The most reliable answer is often hybrid
For an important workflow, use webhooks to start work quickly and an incremental poller to reconcile what the webhook path missed. The webhook says “check now.” The source API remains the authority. A scheduled job checks from the last durable cursor and repairs gaps.
This is especially useful when notification subscriptions expire. Google Calendar channels have expiration behavior and its sync tokens can become invalid, requiring a new full synchronization. The official incremental sync guide documents the required reset after a 410 response. Renewal, reconciliation, and full-resync procedures belong in the design from day one.
A decision checklist for your integration
Ask these questions before choosing the trigger:
- How stale can the destination be before the delay affects customers, cash, or staff work?
- Does the provider offer the event types, payload fields, signatures, and redelivery tools you need?
- Can the API return incremental changes, deletions, and stable record IDs?
- What happens if the integration is unavailable for an hour or a day?
- Can repeating the same event safely produce the same result?
- Who sees and resolves records that still fail after retries?
If a five-minute delay is harmless and the API has a clean change cursor, polling may be the cheaper system to operate. If the event starts a time-sensitive process, use webhooks. If missing one update would create a material business problem, add reconciliation regardless of the primary trigger.
The trigger is only one layer. A production integration also needs record mapping, authentication renewal, rate-limit handling, observability, replay controls, and a repair procedure. Our systems integration service covers that full path, including webhook receivers, incremental sync jobs, and exception handling. When the integration needs a purpose-built operator interface or workflow, custom development can put the controls and failure queue in one internal application.
