REST API vs Webhook: Choosing the Right Architecture
for WordPress User Sync
The decision between REST API polling and webhook-driven delivery is the single most consequential architectural choice in a WordPress user sync implementation. It determines your sync latency, your server load, your failure handling, and your ability to scale. This guide makes the tradeoffs concrete and gives you the framework to choose correctly for your specific network.
Updated 2026
Technical Architecture Deep-Dive

Every WordPress user sync implementation rests on a communication architecture that most documentation describes in one sentence and moves on. “The plugin uses the WordPress REST API to sync users.” Or: “Events trigger webhooks to connected sites.” These descriptions tell you the mechanism but not the implications — and the implications are the part that matters when you are deciding how to build or evaluate a sync system for your specific network.
REST API polling and webhook delivery are not simply two ways of accomplishing the same thing. They have fundamentally different performance profiles, failure modes, scaling characteristics, and operational requirements. A network that performs well under one architecture may perform poorly under the other, and the choice of architecture determines what kinds of problems you will encounter when traffic spikes, sub-sites go offline, or the event volume exceeds what the implementation expected.
This guide provides the technical framework for making this architectural decision correctly. It covers how each approach works at the implementation level, the performance and reliability tradeoffs each one makes, the specific scenarios where each excels and each fails, and how the two can be combined in a hybrid architecture that leverages the strengths of both. We cover this in the context of WordPress multi-site user sync architecture specifically — the constraints and capabilities of the WordPress environment shape the tradeoffs in ways that general distributed systems theory does not fully capture.
This is a technical guide. It assumes familiarity with HTTP, basic distributed systems concepts, and WordPress development patterns. It is written for developers, architects, and senior administrators who are building or evaluating user sync implementations and need to understand the architectural choices beneath the surface.
The two architectures: how each one actually works
Before comparing them, we need precise definitions of what each architecture means in the WordPress user sync context specifically — not the general distributed systems definitions, but the concrete implementation patterns used in WordPress plugin environments.
In a pull-based architecture, sub-sites initiate the sync by making periodic HTTP requests to the master site’s REST API endpoint, asking for user records that have changed since their last sync. The master site responds with the delta — the set of user records that have been created or modified since the timestamp the sub-site provided. The sub-site processes the response and updates its local database.
// Sub-site WP Cron fires every N minutes // Sub-site requests changes from master since last_sync_timestamp GET https://master.com/wp-json/user-sync/v1/changes ?since=2026-04-10T14:32:00Z &page=1 &per_page=100 Authorization: Bearer [connection_key] // Master responds with delta { "users": [...], // Changed user records "total": 847, "next_page": 2, "server_time": "2026-04-11T09:15:22Z" // New timestamp for next poll }
- Sub-site controls the timing — master does not need to know sub-sites exist until a pull occurs
- No data is lost if sub-site is down — it polls when it recovers
- Simple to implement on the master side — a read-only API endpoint
- Works well for batch recovery after extended downtime
- Latency equals the polling interval — a 5-minute interval means up to 5 minutes of desync
- Unnecessary load on master even when no changes have occurred
- N×M scaling problem: every sub-site polls master regardless of whether updates exist
- Depends on WP Cron firing reliably on sub-sites — unreliable on low-traffic sites
In a push-based architecture, the master site fires an HTTP POST request to each sub-site’s webhook endpoint whenever a user event occurs — registration, profile update, password change, role modification. The sub-site receives the event payload and processes it immediately. The master does not wait for sub-sites to ask; it delivers the event as soon as it happens.
// Master site: user profile updated // WordPress action hook fires: do_action('profile_update', $user_id) // Sync plugin intercepts, creates event, enqueues for delivery // Background queue processes event, POSTs to each sub-site POST https://subsite.com/wp-json/user-sync/v1/receive Content-Type: application/json X-Sync-Signature: sha256=abc123... // HMAC verification X-Sync-Timestamp: 1744362922 // Origin timestamp for ordering { "event": "user.updated", "user_id": 4821, "data": { ... }, // User fields and meta "origin_time": 1744362918 } // Sub-site acknowledges HTTP/1.1 200 OK { "status": "accepted", "processed_at": "2026-04-11T09:15:22Z" }
- Near-zero latency — event delivered within seconds of occurrence
- Efficient: no requests when no events have occurred
- Event payload contains exactly what changed — no delta computation on the master
- Scales with event volume, not sub-site count × polling frequency
- Events delivered while sub-site is down are lost unless a retry mechanism exists
- Master must know sub-site webhook endpoints — harder to add new sub-sites dynamically
- Requires idempotent handlers on sub-sites — duplicate delivery must be safe
- High event volumes generate high outbound request load on master
Seven dimensions where the architectures diverge: a detailed comparison
The choice between polling and webhooks is not binary in practice — it is a set of tradeoffs across multiple dimensions, each of which may weight differently for your specific network. The following analysis covers the seven most consequential dimensions for WordPress user sync specifically.
Webhooks win decisively
Polling latency is bounded by the polling interval — a 5-minute interval means a user can register on the master site and wait up to 5 minutes before their account appears on any sub-site. Webhook delivery latency is bounded by network round-trip time and the time to process the event on the sub-site — typically measured in seconds rather than minutes.
For most consumer-facing WordPress networks, this difference is decisive. A user who registers, clicks “Continue to Course” immediately, and encounters a non-existent account on the LMS is a support ticket. The polling architecture’s latency window is the interval during which this failure is guaranteed to occur for every new registration. With webhook delivery, that window collapses to near zero. The tradeoff only becomes relevant when sub-site downtime makes webhook delivery fail — which is where the retry mechanism and fallback become critical.
Webhooks win on active networks
In a polling architecture, every sub-site makes a request to the master on every polling cycle regardless of whether any changes have occurred. If you have 10 sub-sites polling every 5 minutes, the master receives 120 API requests per hour even during periods of zero user activity — pure waste. This scales linearly with sub-site count and inversely with polling interval: more sub-sites or more frequent polling means more unnecessary load.
In a webhook architecture, requests only occur when events occur. During idle periods, no requests are made. During high-activity periods — a marketing campaign that drives 1,000 registrations in an hour — the request volume scales with the event count, not the product of sub-site count and polling frequency. For networks with bursty traffic patterns, webhooks are significantly more efficient. The exception is networks with uniformly high event rates where the constant webhook delivery approaches or exceeds the cost of periodic polling — an unusual scenario in most WordPress deployments.
Polling wins inherently; webhooks need retry
This is polling’s strongest advantage. When a sub-site is down, polling simply fails to produce results — but the sub-site will attempt to poll again on its next cycle. When the sub-site recovers, it polls the master and receives all changes that occurred during the downtime, reconstructing consistency by requesting the delta from its last successful sync timestamp. The downtime creates a gap in sync but not a permanent data loss.
Webhooks face a more serious problem during sub-site downtime. When a webhook delivery fails — because the sub-site returns a non-2xx response or does not respond at all — the event must either be retried by the master or dropped. Without a robust retry mechanism with bounded retry windows, sub-site downtime creates permanent event loss. The industry standard for webhook delivery is exponential backoff retry: first retry after 30 seconds, second after 2 minutes, third after 10 minutes, subsequent retries with increasing intervals up to a maximum retention window. Events that exceed the retention window must be recovered through a fallback mechanism, typically a catch-up pull that the recovering sub-site performs on reconnection.
Webhooks better in theory; both require timestamps
Event ordering matters when a user makes multiple updates in rapid succession. If a user updates their email at T1 and their password at T2, the sub-site must process these events in order — applying T1 first, then T2 — to arrive at the correct final state. Processing T2 before T1 is benign in this specific case. But consider: user registers at T1, then immediately requests account deletion at T2. Processing T2 before T1 creates an account on the sub-site that was supposed to never exist there.
Webhook delivery preserves event order within a single delivery stream, but parallel delivery to multiple sub-sites or network variability can cause out-of-order arrival. Polling delivery is batch-ordered — the delta response contains events in the order they occurred, which the sub-site processes sequentially. Both architectures require the same fundamental solution: origin timestamps on events and timestamp-aware processing on the receiving end that discards stale events. The mechanism differs but the requirement is identical.
Different scaling curves — depends on event vs site count
Polling scales as O(S × 1/P) where S is the number of sub-sites and P is the polling interval. Adding sub-sites adds linear cost to the master regardless of event volume. Adding more frequent polling multiplies cost by all sub-sites. For networks with many sub-sites and low event volumes, polling becomes progressively wasteful.
Webhook delivery scales as O(E × S) where E is the event rate and S is the number of sub-sites per event. In the worst case — a high event rate with many sub-sites — this exceeds polling cost. But for typical WordPress networks where user events are bursty (concentrated during business hours or campaign launches), webhook delivery’s scaling is far more favorable. A franchise network with 50 location sites but moderate daily user activity produces far fewer total webhook requests than the 50 × polling_frequency requests that polling would generate.
Polling disadvantaged by WP Cron; webhooks favor master-side queue
WordPress’s pseudo-cron system — which only fires when the site receives a visitor — creates a fundamental reliability problem for polling architectures. A sub-site that receives low traffic (a niche department site, a low-volume regional store) may go hours without a visitor, meaning its cron never fires and its polling never occurs. The polling interval is only an upper bound on latency in theory; in practice it can be much longer on low-traffic sub-sites.
Webhook delivery in a WordPress context is typically implemented with the master site’s queue processor as the dispatcher. The queue processor on the master — which runs as part of the master site’s cron — fires outbound delivery requests to sub-sites. This concentrates the cron reliability problem on a single site (the master), where it can be addressed directly by configuring system-level cron to trigger WP Cron reliably. Sub-sites only need to handle incoming webhook requests (which happen when a visitor hits the sub-site endpoint at the moment of delivery) — they do not need their own cron to be reliable for sync to work.
Different attack surfaces — both require careful implementation
Polling architecture requires sub-sites to hold API credentials for the master site — a secret that authenticates their polling requests. The attack surface is: compromise of these credentials allows an attacker to pull all user data from the master. The credentials are held on sub-sites (which may have lower security posture than the master) and used repeatedly in outbound requests.
Webhook delivery requires sub-sites to expose an endpoint that accepts inbound POST requests, and requires payload signature verification to ensure the request genuinely came from the master. The attack surface is: a sub-site that does not verify webhook signatures can have arbitrary data injected by any party that knows or guesses the endpoint URL. Both architectures require the same fundamental security primitives — authenticated, encrypted channels with proper key management — but they apply them to different directions of data flow.
The hybrid queue architecture: why production-grade implementations use both
The real-world answer to “REST API or webhook?” is almost always: both, in a hybrid architecture that uses each for what it does best. This is not a compromise — it is the architecture that eliminates the weaknesses of each approach while preserving their strengths. Understanding this hybrid model explains why well-designed user sync plugins do not make you choose between the two.
┌──────────────────────────────────────────────────────────────┐ │ MASTER SITE │ │ │ │ User Event │ │ (register/update) ──► Event Queue ──► Queue Processor │ │ (wp_usermeta) (WP Cron + system │ │ cron fallback) │ └─────────────────────────────────┬────────────────────────────┘ │ Primary path: Webhook POST │ ┌─────────────▼─────────────┐ │ SUB-SITE │ │ │ │ /wp-json/sync/v1/receive │ │ │ │ ✓ Validates signature │ │ ✓ Checks timestamp │ │ ✓ Writes to DB │ │ ✓ Returns 200 OK │ └─────────────┬─────────────┘ │ Sub-site down? Webhook fails? │ Queue retries with exponential backoff 30s → 2min → 10min → 1hr → 6hr → 24hr │ Retry window exceeded? Sub-site reconnects? │ Fallback: Sub-site performs catch-up pull GET /wp-json/sync/v1/changes?since=[last_success]
The hybrid architecture operates as follows. Under normal conditions, the master site’s queue processor delivers events to sub-sites via webhook POST. This provides near-zero latency and efficient resource use. When a webhook delivery fails — sub-site is down, network timeout, authentication error — the queue marks the delivery as failed and schedules a retry with exponential backoff. The retry mechanism handles transient failures (brief downtime, temporary network blips) without data loss.
When a sub-site recovers from extended downtime that exhausted the webhook retry window, the catch-up pull mechanism activates. The sub-site detects that its last successful sync timestamp is older than a threshold, and performs a REST API poll to retrieve all events it missed during the downtime window. This may produce duplicate events — events that were eventually successfully delivered by webhook retry AND included in the catch-up pull. The sub-site’s event handler must be idempotent: processing the same event twice must produce the same result as processing it once.
function handle_incoming_sync_event( $event ) { // Check origin timestamp against current record modification time $current_user = get_userdata( $event['user_id'] ); if ( $current_user ) { $current_modified = strtotime( $current_user->user_modified ); $event_origin = $event['origin_time']; // Discard stale events — idempotency via timestamp comparison if ( $event_origin <= $current_modified ) { return [ 'status' => 'skipped', 'reason' => 'stale_event' ]; } } // Process the event — safe to apply because it is newer than current state apply_sync_event( $event ); return [ 'status' => 'applied' ]; }

WordPress REST API specifics that affect sync architecture
The WordPress REST API — introduced as a core feature in WordPress 4.7 — is the foundation for both polling and webhook delivery in the WordPress sync context. Several WordPress-specific aspects of the REST API affect the architectural tradeoffs in ways that general distributed systems analysis does not capture.
WordPress 5.6 introduced Application Passwords as a first-class authentication mechanism for REST API access. These are per-application credential pairs that can be revoked independently without changing the user’s main password. For sync implementations, application passwords provide a clean way to establish connection credentials for each sub-site connection without requiring a custom token scheme. However, application passwords authenticate as a specific user — typically an administrator — which means the sync API endpoint must carefully validate the scope of operations this credential is authorized to perform.
Security plugins — Wordfence, iThemes Security, All In One WP Security — commonly include options to disable the WordPress REST API for unauthenticated requests or to restrict it to specific user roles. Both polling and webhook delivery use the REST API, meaning a security plugin that blocks REST API access will silently break sync. Any sync architecture built on the WordPress REST API must account for security plugin configuration as a potential failure point and include monitoring that detects when REST API calls are being blocked.
WordPress REST API requests bootstrap a full WordPress initialization — loading all active plugins, executing all initialization hooks, and going through the full authentication and routing stack. On shared hosting environments where PHP execution time is limited and memory per process is constrained, a REST API request that triggers a complex plugin ecosystem’s initialization hooks can be significantly slower than on a dedicated server. Webhook delivery from a master on dedicated hosting to a sub-site on shared hosting may encounter these performance limitations. Profiling the REST API response time on each sub-site’s hosting environment is worthwhile before assuming sub-second delivery.
Decision framework: which architecture is right for your network
With the full comparison mapped, the decision framework follows from the specific characteristics of your network. The following matrix covers the most common scenarios.
The architectural decision is ultimately a function of your network’s latency tolerance, reliability requirements, and operational characteristics. For the vast majority of WordPress multi-site user sync deployments, the hybrid queue architecture — webhook delivery as the primary path with REST API catch-up as the recovery mechanism — provides the best combination of low latency, efficient resource use, and resilience to sub-site downtime. The cases where pure polling is preferable are rare and typically reflect constraints (no outbound HTTP from the master, strict security policies on sub-site webhook endpoints) rather than architectural preference.
Nexu User Sync’s WordPress REST API and webhook hybrid architecture implements the production-grade pattern described in this guide: webhook-primary delivery from the master queue, exponential backoff retry, catch-up pull for recovering sub-sites, idempotent event handlers with timestamp-based stale-event detection, and the HMAC signature verification that makes webhook delivery secure. The architecture choices are made correctly in the implementation so you do not have to make them in configuration.
Production-grade WordPress user sync architecture. Both delivery paths. Zero data loss.
Nexu User Sync implements the hybrid queue architecture — webhook-primary delivery with exponential backoff retry, REST API catch-up for recovering sub-sites, and timestamp-aware idempotent event handlers — as a production-ready implementation you do not have to build from scratch.

I grabbed this guide thinking it'd help me figure out the basics for a small nonprofit site with barely any traffic. But wow 15 pages on scaling for huge enterprise setups?
Honestly, the webhook setup seemed perfect for my multi site network with unpredictable traffic spikes. event driven syncs instead of constant polling made total sense, and I was stoked to cut down on server load. But here's the catch: if a sub site goes down even for a minute, you will end up with sync gaps. Yeah, the guide says it's not permanent data loss which is true but catching up on missed events isn't as automatic as I thought
This guide actually explains HMAC verification and timestamps pretty well helped me track down a sync delay issue. took some trial and error to nail the ordering when multiple updates hit at once, though