Case study
LateOne: what's on tonight, checked every morning.
LateOne is my nightlife guide. Every morning it reads venues' and organisers' own calendars and lists the gigs, club nights and festivals on across Melbourne, with listings and late-night guides for cities around Australia.
- Started
- 10 October 2026
- Changes merged
- 138, to 30 October 2026
- Melbourne listings
- 766, on 30 October
- Built with
- Cloudflare Workers, D1 and GitHub Actions
The problem
What's on in Melbourne tonight is spread across hundreds of venue websites, ticketing sites and social posts. Guides that copy it by hand go stale within days, and a guide that sends you to a closed door isn't much of a guide.
LateOne started out as a prototype called Last Stop. Its repository was created on 10 October 2026 and the prototype's code was brought into it the same day. Since then, 138 changes have been merged, 119 of them in the first five days.
A feed that never goes blank
LateOne reads more than 50 Melbourne sources every morning. Any of them can break on a given day: a website changes, a server is down, or a page comes back empty. So each source fails on its own, and keeps its last good listings, with the date they were last checked.
- A source that suddenly returns nothing, or less than half of what it had, is treated as broken, not as a quiet night.
- The new data is written to a copy first and swapped in only when it's complete, with the previous version kept.
- A source that fails two days running opens an issue for me to look at.
It works: in the 30 October run, four sources failed, and their listings stayed up.
Polite to every website it reads
Reading them one at a time took about 11 minutes. Now eight sources are read at once, but never two requests to the same website at the same time. It checks each site's robots.txt before reading, and when a site asks it to wait, it waits. The results are applied in a fixed order, so the same inputs always give the same output.
Melbourne time, done properly
A night out doesn't end at midnight, so on LateOne a night runs from 6 am to 6 am: a 1 am set belongs to the night before. Some sources publish their times wrong, like an arena whose local times were labelled as UTC, or a venue with an odd half-hour offset. Each of those is corrected at the source, so listings show the right time.
Pages are built ahead of time, so one opened on a later night hides the events that have already finished.
A page for everything
Every listing, venue, suburb, regular night and festival gets its own page, as does every act that plays more than once, plus pages like tonight, free gigs, after 1 am and Sunday sessions. A build makes more than 2,500 pages, with no broken internal links. The sitemap lists only the pages worth finding in search, with real last-changed dates.
The home page is written into the HTML before it's sent, using the same code as the app, so search engines and link previews see the real content and nothing jumps when the app takes over.
Getting there, and getting home
Each venue shows its nearest train station and tram stops, and the last service on a typical night, from PTV's own timetable data. Tap a heart to add an event to your plan, export it to your calendar, or share the night as a link or a QR code that previews properly in a group chat.
Fast, and watched
Measured with Lighthouse's mobile test on 13 October, the home page scored 97 for performance across three runs, up from a median of 70. First paint went from 1.57 to 0.92 seconds, and the largest element from 4.17 to 1.96 seconds. Those were test runs on one machine, not live visitors.
- Every pull request runs the build, hundreds of unit tests, a browser test and an internal link check.
- A strict Content Security Policy lists a fingerprint for every inline script, and the build fails if anything would break it.
- Every six hours, a check of the live site raises an issue if the data is stale, the number of upcoming events drops or caching headers go missing. A weekly Lighthouse run raises one if scores fall below set minimums.
What it shows
If your business has information that changes, like events, menus, stock or timetables, a site can keep itself current without anyone retyping it. The hard part isn't fetching the data. It's what happens on the day a source breaks, and LateOne is built for that day.