Learn

WebSub, explained for publishers

A feed reader finds a new post at its next check, which can be an hour away. With WebSub the hub pushes the post to every subscribed reader the moment it is published. This page says how to declare a hub, how to ping it and how to see whether it delivers.

Check a feed

How WebSub works

WebSub, once called PubSubHubbub, has three parties: the publisher, a hub and the subscribers. The feed declares a hub. A reader that supports WebSub subscribes at the hub for that feed, and the hub verifies the subscription by calling the reader back. When the publisher posts, it pings the hub; the hub fetches the feed once and pushes the new items to every subscriber. Readers get the post within seconds, and the publisher's server serves one fetch instead of one per reader.

Nothing about the feed itself changes. Readers that do not support WebSub keep checking the feed as before.

Declaring a hub

The feed names its hub with a link element, next to its self link. In RSS 2.0, inside channel:

<atom:link href="https://northline.news/feed/" rel="self" type="application/rss+xml"/>
<atom:link href="https://pubsubhubbub.appspot.com/" rel="hub"/>

In Atom, inside feed:

<link href="https://northline.news/atom/" rel="self"/>
<link href="https://pubsubhubbub.appspot.com/" rel="hub"/>

In JSON Feed, a hubs array at the top level:

"hubs": [{"type": "WebSub", "url": "https://pubsubhubbub.appspot.com/"}]

The self link matters here: the hub delivers the topic named in it, so a feed that declares a hub without a self link, or with a self link that differs from the address readers subscribe to, delivers to nobody. The Link HTTP header is the other way to declare both, and some hubs read it in preference to the document.

Pinging the hub

Declaring a hub is half the work. The hub only fetches the feed when the publisher tells it to, with one HTTP request on every publish:

POST https://pubsubhubbub.appspot.com/
Content-Type: application/x-www-form-urlencoded

hub.mode=publish&hub.url=https://northline.news/feed/

hub.url is the feed's self link, exactly as written in the feed. Send the ping after the feed has been updated, not before: the hub fetches the feed on the ping, and a ping sent before the cache is refreshed delivers the old feed. WordPress sends it from the WebSub plugin; most other platforms have a setting or a hook for it.

A hub that is declared but never pinged delivers nothing. Measured over Inoreader's subscriptions, the hubs that are pinged on every publish deliver 95 to 99 percent of a feed's items by push; feeds whose publishers declare a hub and never ping it get a few percent, from the hub's own occasional fetches.

Which hub to use

Google's hub at https://pubsubhubbub.appspot.com/ is free, accepts any feed and is what most publishers use. Superfeedr runs a commercial hub with the same protocol. A site can run its own hub, and the WordPress WebSub plugin does so by default; a self-hosted hub works as well as any other as long as it is reachable from outside and stays up.

Whichever hub, the subscription leases are short, ten days at Google, and readers renew them on their own. Nothing on the publisher's side expires.

Checking that it works

Google's hub shows what it knows about any feed. The topic page lists the last ping it received and the last time it fetched the feed:

https://pubsubhubbub.appspot.com/topic-details?hub.url=https://northline.news/feed/

If the last ping is old, the site is not pinging. If the ping is recent but the fetch failed, the hub could not read the feed, for the same reasons a reader could not. The RSS feed validator reports both halves: whether the feed declares a hub, and, for feeds Inoreader follows, whether Inoreader holds a subscription at the hub and what share of the recent items arrived by push.

What Inoreader does with a hub

Inoreader subscribes at the hub of every feed that declares one and that at least one reader follows, renews the lease before it expires, and verifies each push against the secret it gave the hub. A feed whose items arrive by push is marked real-time in the reader, and its readers get posts within seconds of publishing. Inoreader keeps checking the feed on its regular schedule too, so a hub that stops delivering does not stop the feed; the checks are just less frequent for a feed that pushes.