How’s the Water? shows live storm overflow spills, river levels, rainfall, flood warnings and bathing water results for swimming, paddling and fishing spots, beaches and lakes across England, Scotland and Wales. It reports what the monitors say, never whether the water is safe.

Stack
- Languages: PHP 8.5, JavaScript, SQL
- Frameworks: Laravel 13 with Blade, Tailwind CSS 4, Vite
- Leaflet – every map, switching to canvas past 300 markers
- spatie/simple-excel – reading the water companies’ CSV and XLSX spill logs
- GD – a share card for every place and overflow, drawn on the queue
- Pest and Larastan – tests and static analysis, run in CI on SQLite and MySQL
- Infrastructure: MySQL 8.4, Laravel’s database queue with supervisor-run workers, Deployer from GitHub Actions, Cloudflare edge caching, Rollbar for errors
Data sources and APIs
- Storm overflows: nine English water companies’ live feeds and published spill logs on Stream, Scottish Water‘s near real-time API, Dŵr Cymru Welsh Water‘s storm overflow map, the Environment Agency’s spill start and stop files, and the annual returns as published by The Rivers Trust
- Levels, rain and floods: the Environment Agency flood monitoring API, SEPA’s time series API and Floodline map, and the Natural Resources Wales API
- Bathing waters: the Environment Agency’s register (England and Wales) for classifications, samples and pollution risk forecasts, and SEPA’s bathing water map and results pages
- Rivers, maps and weather: OS Open Rivers for river lines, OpenStreetMap tiles, Natural Earth for the share cards, and Open-Meteo forecasts
How it works
- Scheduled artisan commands poll every source, most every 15 minutes, into MySQL. Pages never call a third-party API.
- Each source has its own reader that maps its records into a shared shape, so a new water company needs only a new reader.
- River lines are built from OS Open Rivers, and every spot, overflow and gauge is projected onto them, so “upstream” follows the water, tributaries included.
- The live feeds only give each overflow’s latest event, so spill history is recorded poll by poll and backfilled to 2024 from the companies’ published logs.
- Ingests mark the regions they touch, and a refresh every 15 minutes rebuilds those regions’ cached conditions in place. Cloudflare keeps each page at the edge for five minutes.
- Offline monitors and data over six hours old show as grey, never as “no spills”.
Features
- Spot, beach and lake pages with the overflows upstream or nearby, the level, rainfall, flood warnings, bathing water results, weather and daylight
- A page for every overflow, with its spill log, uptime and the company’s annual returns
- Spills and levels pages for each region, with rivers and regions compared on their annual returns
- A map of every swimming spot, with “near me” worked out in the browser
- RSS feeds for every spot, river, beach, lake and overflow