← back to the beaches

Swim Hastings publishes estimates based on public discharge and environmental data. It is not water quality testing. Nobody involved takes samples. Swim at your own judgment. This page is the complete rule set, rendered from the same file that ships with the code, so anyone can check the reasoning and tell us where it is wrong.

How Swim Hastings decides what to tell you

This document describes every rule the service uses, with the exact numbers. It exists so that anyone can check our reasoning, disagree with it, and tell us why. The rules are implemented in src/swimhastings/rules.py and the numbers live in config/rules_config.yaml; if the code and this document ever disagree, that is a bug and we want to hear about it. This file is published as is at swimhastings.uk/heuristics/.

What this service is, and is not

Swim Hastings estimates when swimming at each beach along the Hastings and St Leonards frontage is more likely than usual to mean swimming in diluted sewage. It works entirely from public data: Southern Water's published storm overflow activity, Environment Agency rainfall and bathing-water data, tide predictions, and the rain forecast.

We do not test water quality. Nobody involved takes samples. A green verdict means "none of our data sources shows a problem", not "the water is clean". A red verdict means "the public data shows something we think you would want to know about", not "the water is proven contaminated". The Environment Agency's official classifications remain the only regulated assessment of these waters. Swim at your own judgment.

The numbers below are published, versioned guesses. They are informed by the general literature on bacterial die-off and by local knowledge of the frontage, but they have not been validated against water samples, because we have none. During the shadow period we compare our verdicts against Southern Water's beach warnings, the EA's forecasts, and reports from swimmers, and we tune the numbers in public, in this file's changelog.

The verdicts

When several rules fire, the worst one sets the colour and every reason is shown. Every alert and every status page entry lists the rules that fired, so you are never asked to trust a bare colour.

The zones and the outfall map

We divide the frontage into five zones, west to east: Glyne Gap, Bulverhythe, St Leonards (Marina to Warrior Square), Hastings Pelham (pier to harbour arm), and Rock-a-Nore with the Fairlight end. For each storm overflow outfall we recorded, by hand, which zones it discharges into directly and which zones a plume could plausibly reach while the tide is flooding (running broadly eastward along this coast) or ebbing (westward).

This mapping is local judgment, and we say so plainly: it is not a hydrodynamic model. It is written down in config/beaches.yaml, one entry per outfall, so anyone who knows this coast can challenge a specific line. The outfall positions and identifiers come from Southern Water's published data; the names are our own labels, because the public feed does not include names. The feed does say which watercourse each outfall discharges into, and we show that, verbatim and attributed, next to every outfall on the status page, so that a local reader can test our mapping against it. Most overflows on this coast are inland: they spill into a stream or drain, and reach a beach only if that watercourse does. Where a watercourse drains is checked against Ordnance Survey's flow-directed Open Rivers network (scripts/trace_outfall_drainage.py, run over every outfall on 2026-09-05); an overflow whose watercourse leaves the frontage, like the Pett Level marsh sewers that reach the sea at Rye, carries no zones, and an inland overflow carries the map of the sea outlet its water reaches, not of the beach nearest its own position. That network knows seven outlets on this coast: two Pevensey Levels sluices at Norman's Bay, the Combe Haven sluice at Bulverhythe, the culverted town streams at Hastings, and the Ecclesbourne and Fairlight glens.

The rules

R1 — active discharge into a zone → red

If Southern Water's data shows an outfall releasing right now, every zone that outfall discharges into directly goes red, and stays red until the release stops. This is the simplest and least arguable rule.

R2 — recent discharge → red, then amber, decaying over time

Contamination does not vanish when a release stops, so an ended release keeps a zone red for a while and then amber for a while longer. The windows are:

Release length Red after it ends Amber until
longer than 1 hour 24 hours 48 hours after the end
1 hour or shorter 24 hours 24 hours after the end

(For a short release the red window covers the whole decay period, so in practice a short release means red for 24 hours and no amber tail.)

Tides change how quickly the sea disperses a plume, so the windows are scaled by the tidal phase at evaluation time: on spring tides (stronger streams, faster dispersion) every window is multiplied by 0.75, and on neap tides by 1.25. Between the two, the windows apply as written.

These decay times are the most uncertain numbers in the system. Real die-off depends on sunlight, temperature, and sea state, none of which we currently model. We chose 24 and 48 hours because they bracket the advice most UK bathing-water bodies give after a discharge, and we expect to tune them.

R3 — active discharge nearby, carried by the tide → amber, or red if long

If an outfall is releasing now and the current tide direction can carry the plume into a zone (per the hand-set map above), that zone goes amber. If the release has already been running for more than 3 hours, the zone goes red instead, on the reasoning that a long release puts enough into the water that adjacency stops being a comfort.

This rule needs tide data. When we have none, R3 does not fire at all, which is the less cautious direction; the status page says when we are running without tide data.

Travel time for inland overflows

Most overflows on this coast are not on the beach. They spill into a stream some way inland, and the stream takes time to reach the sea: the Powdermill Stream CSO at Battle is about 11 km of river from the Bulverhythe sluice, the Cole Stream CSO at Cooden 2.5 km from the sluice its water reaches. So for an inland outfall, rules R1 to R3 do not judge the release as the feed reports it; they judge it shifted later by the time the water takes to arrive. That time is the outfall's river distance (travel_km in config/beaches.yaml, measured on Ordnance Survey's Open Rivers network) divided by an assumed stream speed (travel_delay.stream_speed_km_h in config/rules_config.yaml, 2 km/h). Until the first of the water is due, the beach keeps whatever colour its other inputs give it and carries an advisory note saying the release has happened, how far upstream, and when to expect it. From then on R1 applies while water is still arriving, R2's decay runs from when the last of it arrived, and R3's 3-hour escalation clock starts when the water reaches the sea.

The speed is a published guess and deliberately a fast one: a small Wealden stream in spate runs at roughly half a metre a second. If the real water is slower than that, the beach goes red a little before it needs to, which is the right way to be wrong. Sea outfalls, and the one 300 m beach ditch at Bexhill, have no delay.

R4 — heavy rain but no reported discharge → amber

If any of the rain gauges in the catchments that drive local overflows records more than 10 mm in 6 hours, we treat the silence of the discharge feed as suspicious rather than reassuring, and every zone with no discharge signal of its own goes amber. Storm overflows exist to spill in exactly this weather, event monitors are not perfectly reliable, and reporting can lag. This rule is our answer to the known weaknesses of EDM (event duration monitoring) data.

R4 only fires when no discharge rule (R1, R2, R3) has already fired for the zone, because in that case the discharge data is evidently flowing and the rain adds nothing.

R5 — heavy rain forecast → advisory note only

If more than 15 mm of rain is forecast in the next 24 hours, every verdict carries a note saying overflows are likely and it is worth checking again before swimming. R5 never changes a colour; forecast rain is a reason to re-check, not evidence of contamination.

R6 — Environment Agency warnings → at least amber

Two EA signals each set a floor of amber for a designated bathing water: an active pollution risk forecast for the site, or a latest in-season sample exceeding our screening thresholds (E. coli above 500 or intestinal enterococci above 200 cfu/100 ml, which are the boundaries of the "good" class in the Bathing Water Regulations' coastal standards, used here as single-sample screening levels; the EA itself classifies annually, not per sample).

Only Hastings Pelham Beach, St Leonards and Bexhill are designated bathing waters, so only they can receive R6 input. Glyne Gap, Bulverhythe, and Rock-a-Nore are not sampled by the EA at all, which is itself worth knowing.

The verdict is decided by the two boolean signals alone, but the displayed reason carries the detail behind them: for a pollution risk warning, the EA's risk level and the forecast's expiry time, plus a reminder that this is the EA's daily rainfall/tide/wind prediction of reduced water quality and not a recorded storm overflow release (so no outfall will show a release when only R6 is active); for a poor sample, the sample date and the raw E. coli / intestinal enterococci counts. Each beach panel also links to the EA's own profile page for the site.

R7 — manual override

We can set a zone's verdict by hand, in either direction, and the verdict says a person set it and why. This exists for situations the rules cannot see, such as a pollution incident reported by another route. An override beats every other rule while it is active.

Staleness

The most dangerous failure for a service like this is a dead data feed silently showing a fresh-looking green. Freshness is checked per source, not just overall: each source that can raise a verdict has its own age limit (Southern Water discharge data 45 minutes, EA rainfall 45 minutes), and if any of them is over its limit — or has never delivered data at all, as on a fresh install — every verdict is flagged as delayed and the status page shows a warning banner naming the delayed source. A recent weather poll can never mask a dead discharge feed.

The rainfall feed reads three gauges in one poll, and the EA's server answers slowly and unevenly. A poll counts as fresh when at least one gauge answers: a gauge that times out or errors is skipped for that poll and named in the poll log, and R4 reads whichever gauges did answer. Only a poll in which no gauge answers is a failed poll — that one still flags every verdict and wakes the operator.

EA bathing-water status is judged differently, because we cannot fetch it ourselves: the EA's bathing-water service refuses our server's requests, so that one source is relayed to us hourly from a machine on a home connection. How long ago we fetched it therefore measures that machine's uptime, not whether what we are showing is current. The EA's pollution risk forecast carries its own expiry — typically the following morning — so we treat the source as current while the forecast we hold is still inside it, and fall back to a one-day limit when we hold no usable expiry. A relay that stops for good is still caught: once the forecast we hold expires, the verdicts are flagged and the operator is alarmed as before. Our own monitoring separately wakes the operator, and the status page also checks its own age in your browser, so a page our systems stopped regenerating warns you about itself.

The under-cliff walk verdict (cliff_walk)

A separate verdict, same discipline, different question: is there enough tide window to walk the foreshore under the cliffs from Rock-a-Nore past Fairlight Glen to Pett Level? People are cut off on this route every season and there are no exits between Ecclesbourne Glen and Pett Level.

The rule (src/swimhastings/cliffwalk.py, constants under cliff_walk in config/rules_config.yaml): the route is treated as passable while the predicted tide height at the Hastings station is below 3.0 m. From the predicted high and low waters we compute the passable windows, then:

Heights between high and low water are the same sinusoidal interpolation the status page uses — an approximation, and labelled as one. All three numbers are published guesses to be tuned against ground truth (the 3.0 m threshold in particular), and this verdict is about tide only: swell, surge and weather can close the route much earlier than the tide alone suggests. The verdict says so on every surface, and no verdict is ever shown from tide data more than 12 hours old — a missing verdict is shown as missing, never defaulted to green.

About Southern Water's own classifications

Southern Water publishes its own view of whether a release is affecting bathing waters. Where we have that classification we store it and can show it, always attributed. It never contributes to a verdict. Our reasons are structural: their classification methodology is not published in a form we can check, and an assessment of impact made by the party doing the discharging should be corroborated rather than inherited. Where we criticise their data we will do it specifically and with citations, not by assertion.

The release data itself (which outfall, when it started, when it stopped) is theirs, published under CC BY 4.0, and we depend on it gratefully. Two known limits of that feed: it reports only the most recent event per outfall, so two short releases in quick succession can appear to us as one; and while a release is in progress the feed's end-time field still shows the previous event, which we detect and treat as "still discharging".

Data sources and attribution

Changelog


Contains data from Southern Water Storm Overflow Activity, © Southern Water, licensed under CC BY 4.0; Environment Agency data under the Open Government Licence v3; forecast and conditions by Open-Meteo. Contains ADMIRALTY ® tidal data: © Crown copyright and database right. This service reports and interprets that public data; it does not measure water quality. Privacy.