Polling is a dependable baseline for feeds, but it is inefficient when updates are rare and immediacy matters. A subscriber either checks frequently and wastes requests or checks slowly and accepts delay. WebSub adds a push layer to feed distribution. Publishers advertise a hub, subscribers register callback URLs with that hub, and the hub sends notifications when the topic changes. The feed remains the durable content representation; push acts as the signal that tells subscribers when to fetch or process it.

This separation is important. WebSub is not “send arbitrary JSON to a webhook.” It is a protocol with discovery, subscription verification, leases, signatures, and topic identity. A production implementation should also keep polling as a safety net because subscriptions expire, hubs fail, and publishers can be misconfigured. The strongest design combines event-driven delivery with periodic reconciliation.

Understand the three roles

The publisher owns a topic URL, commonly an RSS or Atom feed, and indicates one or more hub URLs. The hub accepts subscription requests and distributes content notifications. The subscriber exposes a callback endpoint and proves that it controls that endpoint during a verification exchange. One service can play multiple roles, but keeping the responsibilities conceptually separate makes security and observability clearer.

The W3C WebSub Recommendation describes the protocol and its security considerations. Read the discovery and verification sections carefully. The topic URL is the subscription identity; the hub URL is infrastructure used to manage the subscription. A redirect or feed migration can therefore affect discovery and renewals even when the publisher's home page is unchanged.

Discovery belongs in the feed workflow

A consumer can discover hub and topic links in HTTP headers or feed markup. Store the declared topic, resolved feed URL, and hub URL separately. Do not subscribe to an arbitrary hub supplied by a client without applying the same outbound network controls used for feed fetching. Validate schemes, block unsafe addresses, cap redirects, and record the final destination. A malicious hub is still an untrusted remote service.

Discovery should be repeatable because publishers can change hubs. On each successful feed refresh, compare the currently advertised hub and topic links with the active subscription. If they differ, plan a controlled migration rather than immediately deleting the old lease. Keep the old path alive until the new subscription is verified and producing notifications. This avoids blind spots during publisher changes.

Implement callback verification exactly

When a subscriber requests a lease, the hub sends a verification request to the callback URL. The callback must validate the mode, topic, challenge, and any lease information, then echo the challenge as required. Only mark the subscription active after verification succeeds. Treat unexpected verification requests as untrusted input, and bind the expected topic and hub to a pending subscription record with an expiration time.

Use a random, unguessable callback token in the URL or an equivalent lookup key. That token identifies the pending subscription without exposing a sequential database ID. Still validate every parameter; possession of the callback URL is not sufficient authorization. Limit request size, require HTTPS for public deployments, and log verification transitions. A lease that cannot be tied to an explicit pending request should not become active.

Verify delivery authenticity and replay safety

When the hub supports authenticated content distribution, verify the signature over the raw request body before parsing it. The shared secret should be unique per subscription or tenant, encrypted at rest, and rotated through a controlled resubscription. Compare signatures using a constant-time function. Reject unsupported algorithms and malformed headers. Do not reconstruct the body from parsed fields because any transformation changes the signed bytes.

Authentication does not prevent duplicates. Hubs may retry after timeouts, subscribers may lose a response, and the same changed feed can be sent more than once. Deduplicate using entry identities and content fingerprints after parsing. Also generate an internal delivery-event ID from the subscription and raw payload hash so repeated requests can be recognized before expensive downstream work. Return success only after durable acceptance, not after every final consumer has completed.

Decide whether the payload is a signal or content

Some hubs send the updated feed representation in the notification body. Others may provide enough information to prompt a fetch. Your architecture should handle both by normalizing the event into a source-refresh job. If the payload is a supported feed document and passes size and authenticity checks, it can be parsed directly. Otherwise, schedule a guarded fetch of the topic URL. This keeps hub-specific behavior out of the rest of the pipeline.

Even when the full feed arrives, retain conditional validators and periodic polling. A push notification can be dropped, delivered out of order, or contain a truncated representation. A later reconciliation fetch should discover any missing entries without producing duplicates. The feed monitoring system should display both the last push and the last successful reconciliation so operators can distinguish a quiet source from a broken lease.

Manage leases as scheduled state

Subscriptions commonly have finite leases. Store the granted expiration time rather than assuming the requested duration. Schedule renewal with a safety margin and jitter, and keep renewal idempotent. If a renewal fails, continue polling and retry according to policy. Do not wait until the exact expiration second; clock differences and network delays can create gaps. A lease state machine is easier to reason about than scattered timestamps.

Useful states include pending verification, active, renewal due, renewal pending, expired, unsubscribing, and failed. Record the hub response and recent transitions. A customer-facing status can simplify these to active, degraded, or inactive, while the operator view keeps the protocol detail. If a customer deletes a source, send an unsubscribe request when appropriate, revoke secrets, stop renewals, and apply retention policy to historical events.

Protect the callback service

A public callback endpoint will receive scans and malformed requests. Put strict limits on method, content type, body size, processing time, and concurrent work. Parse only after authentication checks that depend on the raw body. Queue accepted events quickly and return a bounded response. The endpoint should not call customer destinations synchronously or perform long feed parsing while the hub waits.

Rate limiting is nuanced because blocking a legitimate hub can create retries that increase load. Apply per-subscription and per-source controls, detect repeated identical payloads, and maintain an emergency global ceiling. Use observability that preserves privacy: request ID, subscription ID, hub host, body size, signature result, queue result, and response time. Avoid logging full feed content by default.

When ordinary webhooks are the better choice

WebSub is ideal when a publisher already exposes a feed and wants interoperable subscription behavior. A direct webhook API may be simpler when one product controls the event schema, authentication, retry policy, and subscriber lifecycle. Direct webhooks can carry small domain events such as “release published” with a stable event ID and a URL for details. They do not need to pretend to be a general syndication protocol.

A platform can support both. WebSub connects to open publishing ecosystems, while signed product webhooks serve customers who want a contractual event schema. Normalize both into the same internal event bus and use the same idempotent delivery machinery. The webhook subscription architecture should make the transport visible so clients know whether an event came from a hub notification, a poll reconciliation, or a first-party publisher webhook.

Operational checklist

  • Discover and store topic and hub URLs separately from the submitted feed URL.
  • Apply guarded outbound HTTP rules to hubs as well as feeds.
  • Bind verification challenges to short-lived pending subscription records.
  • Use HTTPS callbacks, unique secrets, raw-body signature verification, and constant-time comparison.
  • Accept events durably before returning success and deduplicate at both event and entry levels.
  • Renew leases early with jitter and keep polling active as a reconciliation channel.
  • Expose lease state, last push, last reconciliation, and recent failures to operators.
  • Disable callbacks and rotate secrets promptly when a tenant or source is removed.

Push should improve latency, not weaken correctness

WebSub can reduce update delay and unnecessary polling while preserving feeds as the portable record. The protocol works best when implemented as a stateful subscription system, not as a generic endpoint that accepts whatever arrives. Verification, lease management, signatures, idempotency, and reconciliation are all part of the feature.

Keep correctness anchored in the feed. A notification says that a topic changed; the canonical entry identities and links determine what changed. With that model, missed or duplicate pushes become recoverable operational events instead of data-loss incidents.