← All posts Insights 5 min read

Webhooks vs Polling for NetSuite to Shopify and WooCommerce Inventory Sync in 2026

Webhooks vs polling for NetSuite-to-Shopify and WooCommerce inventory sync in 2026 — strengths, failure modes, and the hybrid pattern we ship in production.

“Real-time” is the word stores use; “sub-five-second” is the engineering meaning. To get from NetSuite to a Shopify or WooCommerce storefront in under five seconds, you have exactly two patterns: webhooks pushing changes, or polling pulling them. Most production integrations end up using both, in different places, for different reasons.

Who this is for: teams designing or refactoring a NetSuite ↔ storefront inventory sync where stockouts and oversells are starting to cost real money.

The honest definition of “real time”

Neither NetSuite nor Shopify nor WooCommerce will give you true millisecond-level synchronisation, and you don’t need it. What matters is the worst-case staleness during your peak hour — the moment you’re most likely to oversell. If the sync converges within 5–10 seconds during peak, you’re “real time” for any commerce purpose. Anything tighter is engineering for its own sake.

Webhooks: low latency, fragile in failure modes

Webhooks are push-based. A change in NetSuite fires an HTTP POST at your sync service, which transforms the payload and writes it to Shopify or WooCommerce. When everything works, latency is sub-second.

  • Strengths: minimal latency, lower API consumption (you only fetch when something changed), naturally scales with the rate of change.
  • Weaknesses: if your receiver is down for two minutes during a deploy, you miss every event in that window. NetSuite’s webhook retry is best-effort, not guaranteed. Lost events become silent stock divergence.
  • Where it fails in practice: spikey load (Black Friday sees 50× normal events, your queue worker falls behind, customers see oversells); webhook configuration drift (someone disables a webhook in the UI for “testing” and forgets); payload schema changes between NetSuite releases (covered the 2026.1 case in our authentication migration post).

Polling: predictable, wasteful, robust

Polling is pull-based. Your sync service asks NetSuite, every N seconds, “what’s changed since my last cursor?” It fetches the delta and writes it forward. Latency is determined by your polling interval.

  • Strengths: simple to reason about, self-healing (a missed poll catches up on the next one), no event loss as long as the cursor is durable, easy to test.
  • Weaknesses: high API consumption when nothing’s changing (each poll still costs you a quota unit), polling interval is a floor on latency, hard to tune well across products with very different change rates.
  • Where it fails in practice: the cursor gets corrupted and you replay six hours of changes onto the storefront; the interval is set conservatively because someone was worried about API limits, and now inventory lags 90 seconds during checkout.

The pattern most production integrations end up with

Webhooks as the fast path, polling as the safety net. The webhook updates the storefront within seconds; a polling job runs every five minutes and reconciles anything the webhook missed. The polling job runs against a saved search of “items modified in the last 10 minutes” — a small window, so the API cost stays low.

// Pseudocode for the hybrid pattern
async function reconcile(cursor) {
  const changed = await netsuite.search({
    savedSearch: 'items_modified_since',
    bind: { since: cursor },
  });
  for (const item of changed) {
    const local = await storefront.getInventory(item.sku);
    if (local.quantity !== item.qtyAvailable) {
      await storefront.setInventory(item.sku, item.qtyAvailable);
      log.info('drift_corrected', { sku: item.sku, was: local.quantity, now: item.qtyAvailable });
    }
  }
  return now();
}
// Webhook handler writes immediately, then the cron reconciles every 5 min

The drift_corrected log line is the canary. Healthy day-to-day, it should fire zero times — every webhook is landing. When it fires, it means your webhook pipeline missed an event. Alert on it crossing a threshold (e.g. more than 1% of polled items showed drift in 24 hours) and you’ll catch a webhook outage before customers do.

The Shopify-specific wrinkle

Shopify has a strict API call budget. A naive polling loop against a 10,000-SKU catalog will eat your daily budget before lunch. Two practical mitigations: use Shopify’s bulk operations API for the reconciliation pass (one operation, one call, results delivered via webhook), and keep your webhook-driven fast path doing single-SKU writes. We unpacked the sync direction question in one-way vs two-way, and the early-stage breakage patterns in Shopify-NetSuite month two.

FAQ

Can I just use webhooks and skip polling entirely?

You can — and many integrations do for the first six months. The problem is that you have no way to detect that something has gone wrong until a customer reports an oversold order. The reconciliation poll exists to give you observability, not just redundancy.

What’s a reasonable polling interval?

For the reconciliation pass: every 5 minutes for most stores, every 15 for low-volume ones. If you’re polling as your only sync mechanism, every 30–60 seconds during business hours is the floor before API quota hurts.

How do I make webhook handlers idempotent?

Two patterns. Either dedupe by event ID (NetSuite includes one in the payload) — store the last 24h of IDs and reject duplicates — or write inventory using a compare-and-set (“update to X only if current value is Y”). The latter is more robust because it handles webhook re-ordering, not just duplication.

Does the hybrid pattern double my API costs?

No. The reconciliation poll uses a single saved-search call returning only items modified in the last few minutes — usually a small set. On a typical day, the polling overhead is well under 5% of total API calls. It’s a cheap insurance policy.

If you’re starting from scratch

Build the polling pass first. It’s simpler, easier to test, and gets you to “the inventory is converging” with a small amount of code. Add webhooks later, as the fast path, once the polling-only version is proven in production. The reverse order — webhooks first, polling later — leaves you exposed during the period when webhooks work most of the time but not always.

If you’d rather not build either, we run fixed-scope Shopify + NetSuite and WooCommerce + NetSuite implementations that ship the hybrid pattern as the default. Or our NetSuite Integration plugin for WooCommerce if you’d prefer a productised option.


Ship it

Need this in your stack?

We build, integrate, and ship — no calls, just delivery.

Start a project →