howbadisthetrain.com is a small, independent project that scores every NYC subway line from 0 to 10 based on what's actually happening right now — delays, crowding, planned work, the lot. It's built for riders who want a quick honest read before they head to the platform.
Why
The MTA's own service status pages are accurate but unfriendly to skim — they were designed for commuters with spare time on the platform, not for someone deciding between the F and an Uber at 11pm on a Wednesday. We built the version we wanted to use: one screen, every line, ranked, with the numbers that actually matter at a glance.
There is also a narrower reason this site exists. Most transit information is published per-disruption: a notice that one stretch of track is rerouted, an alert about a signal problem somewhere in the Bronx. That format answers the question "what is wrong right now" and leaves the more useful one — "is my line having a normal week, or a bad one?" — for you to assemble yourself from a pile of notices. A score is a compression. It takes a hundred scattered facts about a line's week and turns them into one number you can compare against twenty-three other lines before you leave the house.
How to read a score
A 10 is not a promise and a 4 is not a warning to stay home. The number is a vibe score on a fixed scale, intended to be read relatively: an 8.4 next to a 5.7 tells you where to put your attention, not whether a train will physically arrive. Above roughly 7, a line is doing what riders expect of it. In the 5s and 6s, expect to build in slack — a missed connection, a slower crawl through a work zone, a platform that fills faster than the trains clear it. Below that, plan around the line rather than through it.
The one-line label under each score is deliberately plain language rather than a status code. "Slow into Manhattan from the Rockaways" is more useful at 7am than "Minor Delays," because it tells you which end of the line is carrying the problem and roughly how long it will follow you.
What we get wrong
Scores are computed from public MTA data and curated inputs, which means they inherit every limitation of both. A delay that clears between our last update and your arrival will still show on the page. A work zone that the MTA posts late will enter the number late. Lines with fewer riders generate less signal, so their scores move less and are, in a quiet way, less trustworthy than the busy lines'. We would rather say that plainly than pretend the number is more precise than it is — the methodology page goes further into exactly where the seams are.
What you get
- Every NYC subway line, ranked worst-to-best, on a single page.
- A per-line page with the current score, the one-line label, and a rough "vs. driving" cost/time comparison.
- Honest copy. The labels are written by a person (us), not generated — dry, occasionally snarky, and firmly on the side of public transit.
- A methodology page that names exactly what's real, what data is stub, and where the line is between signal and satire. Read it before you assume any number is gospel.
What we don't do
- We don't require an account. There is no signup, no login, no profile.
- We don't sell or share any data. The site sets no first-party cookies. Cloudflare's privacy-first analytics may be enabled server-side at some point; nothing user-identifying ever leaves your browser.
- We don't editorialize on the lines themselves beyond the tone of the labels — no safe/dangerous coding, no neighborhood commentary, no culture-war bait.
- We don't run sponsored posts or paid rankings. Ads come from Google AdSense only, and they only appear in the slots between content blocks, never on top of the score itself.
Who
One person, working on this in the open. The site is hosted on a small VPS, fronts the MTA's GTFS-realtime feeds (or stub data, until the live integration ships — see the methodology page for the scoring math), and earns revenue through Google AdSense. There is no team, no funding, no growth targets, and no roadmap beyond making the score honest and the page fast.
How it's built
- Next.js (app router) on Node 20.
- TypeScript end-to-end. Tailwind for styling, with a small custom palette that borrows from the MTA line colors but stays distinct from any single roundel.
- Docker + Caddy + Cloudflare for the serving stack.
- ISR + edge caching to keep the homepage snappy without hammering the MTA feed.
- No client-side analytics beyond Cloudflare's privacy-friendly web analytics (when enabled). No third-party tracking scripts beyond what Google AdSense sets.
Line colors
The colored ring around each line badge is the MTA-published line color, used here in a thin outline and matching text so it stays visually distinct from the official MTA roundel (which is filled solid). This site is not affiliated with, endorsed by, or sponsored by the MTA — the colors are publicly documented reference values, used to help riders identify their line at a glance.
What's coming
- Live MTA GTFS-realtime integration. The current scores are hand-curated; the goal is to recompute every line against the live feed every minute or so.
- Saved lines — bookmark the lines you ride, get a shorter list on the home page.
- Station-level detail for the lines that need it (lookin' at you, Times Square).
- Service-change lookahead for planned weekend work.
Open-source pieces
The site itself isn't open source (yet). The pieces that could be useful to other transit-data hackers — the MTA feed parser, the scoring math, the lineup of static assets — are something we'd consider releasing if there's interest. Email us if you'd find them useful.
Get in touch
Bug reports, scoring disagreements, line-color corrections, and methodology questions all welcome. Email [email protected] — we read every email.
See also: Methodology, Privacy, Terms.