Community. Driven. Weather. Data. | Always Ad-Free | Developer FriendlyChecking statusDiscord
WxAlerts.org, Community Driven Weather Data
Support us
Sign in
How it works

How an alert reaches you

Three independent feeds out of the National Weather Service, one deduplicated pipeline, and a broker that pushes the warning to you about forty seconds after the office issued it.


A tornado warning starts as a few hundred bytes of text typed at a Weather Forecast Office. Everything after that is plumbing, and the plumbing is where most of the delay in getting it to you comes from.

WxAlerts exists to make that plumbing short. We take the product from three independent feeds at once, keep whichever copy arrives first, and push it straight to subscribers. Median time from the office pressing send to the alert being on the broker is about 40 seconds.

Where warnings come from

Every hazard product is issued by one of 122 Weather Forecast Offices. The office writes the text, the polygon and the VTEC line: the machine-readable code that says which office, what phenomenon, watch or warning, which event number, what year. That VTEC key is what makes an alert trackable: the initial warning, the severe weather statement ten minutes later and the cancellation are all the same event.

From the office, the product enters national dissemination, and that is where the paths fork.

                         ┌──▶ NWWS-OI  (XMPP push)  ──┐
WFO issues product ──────┼──▶ api.weather.gov (poll) ─┼──▶ WxAlerts ingest ──▶ you
                         └──▶ EMWIN via GOES-19 ──────┘     parse · dedupe ·
                                                            geometry · publish

Three feeds, on purpose

Any one of these can go down, and over a long enough season all of them will. None of them is a fallback: all three run continuously, and the pipeline keeps whichever copy of a product shows up first.

Feed Transport Median from issuance Fails when
NWWS-OI XMPP push from NOAA 41 s NOAA’s XMPP service or our network path
EMWIN GOES-19 satellite broadcast 52 s The dish, or the spacecraft
api.weather.gov HTTPS poll, 60 s interval 105 s NWS API outage or rate limiting

Warnings alone run a little faster than the all-products figures above: 37 s on NWWS, 50 s on EMWIN, 95 s on the API.

NWWS-OI is the NOAA Weather Wire Service, the same push feed broadcasters and emergency managers run on. It is the primary because it is a push: the product is handed to us, we do not go looking for it.

EMWIN arrives over GOES-19: the product is broadcast from geostationary orbit and received off a dish, with no internet between the satellite and the receiver. Head to head on identical products, EMWIN trails NWWS by a median of 7.5 seconds and wins outright 3% of the time. It is a genuine second primary, not a consolation prize, and it is the only feed that survives an internet-side failure.

api.weather.gov is the slowest because polling always is: a 60-second poll interval alone averages 30 seconds of waiting. It stays in the mix because it carries non-VTEC products the text feeds handle differently, and because it fails for entirely different reasons than the other two.

One alert, however many copies

A warning arriving on three feeds must not become three warnings. Deduplication happens twice, on two different keys.

Products are keyed on a hash of their normalised text. The first copy to arrive is stored; the losing copies only append to the alert’s sources array. That array is the evidence for which feed is actually fastest: the latency table above is measured from it, not estimated.

Alerts are keyed on VTEC. Every follow-up statement for the life of a hazard updates one row instead of piling up beside it, so what you subscribe to is the current state of the hazard rather than a transcript of everything said about it.

Geometry comes from the storm-based LAT...LON polygon when the product has one. When it does not, the UGC zone codes are resolved against cached NWS zone boundaries and unioned into a single shape, so every alert has a polygon, not just the storm-based ones. A cancellation naming some counties subtracts those and leaves the alert live in the rest.

Getting it out

Two routes out, one pipeline behind them.

MQTT, pushed

The broker is the fast path: no polling, no API in the middle, and the same feed the live map draws from.

wss://mqtt.wxalerts.org/mqtt        username: wxalerts   password: wxalerts

The credentials are published on purpose. The account is subscribe-only and the broker’s ACL denies publishing.

Alerts are published on two trees, with an identical payload on both:

Topic
wxalerts/nws/v1/alert/{office}/{phen}/{sig}/{etn} by issuing office
wxalerts/nws/v1/same/{same_code}/{etn} by county, weather-radio style

{same_code} is the six-digit SAME/FIPS code a NOAA weather radio is programmed with, so subscribing to your county is the same act as programming a radio:

mosquitto_sub -t 'wxalerts/nws/v1/same/012113/#' -v   # Santa Rosa County, FL

Wildcard however you like: alert/+/TO/W/+ is every tornado warning in the country, alert/+/+/W/+ is warnings with no watches or advisories.

Two behaviours matter:

  • Alert messages are retained. Subscribing hands you every live hazard immediately, before any new one is issued. That opening burst is state, not news, so do not notify on it.
  • An empty payload is a tombstone. When a hazard ends, a zero-length retained message clears every topic it appeared on. Treat it as “this alert is over” and drop it.

REST, when you would rather ask

Not everything wants a persistent connection. https://api.wxalerts.org serves active alerts, polygons in GeoJSON and location search over plain unauthenticated HTTP; see the REST API reference. It reads the same database the broker publishes from, so the two never disagree; it is just a step behind by however long you wait between requests.

About that 40 seconds

The number usually quoted for a warning reaching a phone through a commercial weather app is around 470 seconds, a little under eight minutes from the office pressing send.

Almost none of that is the National Weather Service. It accumulates downstream: a vendor polling an API on a multi-minute interval, a batch job matching alerts against saved locations, a push notification queue fanning out to millions of devices, and a mobile OS deciding when to wake the app.

Issuance to delivery
Typical commercial weather app ~470 s
WxAlerts, on the broker ~40 s

We are faster for boring structural reasons, not clever ones:

  • Push, not poll. Two of the three feeds hand us the product. There is no interval to wait out.
  • No batching. A product is parsed and published as it lands. There is no queue to drain and no fan-out job to wait for.
  • The topic tree does the geofencing. Filtering by county or by office happens in the broker’s subscription matching, not in a service that has to walk a list of users first.
  • The broker is the last hop. Publish to delivery is well under a second on a connected subscriber.

Where to go next

  • MQTT lightning feed: the second, independent feed, carrying GOES-19 satellite lightning, geohashed.
  • REST API: endpoints, shapes and how to colour by severity.
  • Home Assistant: all of the above, already written, as entities you can automate against.