Building Smooth: a turbulence forecast you can text, for someone I love
These posts are live but still drafts — I'm figuring out how to write well with AI, and the tone and structure may shift as I go.
My partner Em wants to know exactly one thing about a flight, and it isn’t the departure gate. It’s whether the air will be rough. Fear of flying is one of the most human fears there is, and it does not care how many aviation-safety statistics you quote at it. What helps is knowing. Bumps you expected are turbulence; bumps you didn’t are terror.
There’s a site for this: Turbli, a turbulence forecaster I genuinely like, use constantly, and, as far as I can tell, trust. You enter a flight and it draws a chart of expected bumpiness across the whole route. Let me be clear up front: this post is not a complaint about Turbli. It’s closer to a love letter. I liked the site enough that I wanted to understand how it worked, and the fastest way I know to understand something is to try to build it. Then a second question tagged along, the product question: how simple could this get? The person in seat 23C doesn’t want a chart with an EDR axis. She wants a sentence, ideally one that arrives where she already is, which is her phone. Text a flight number, get back something calm.
So this project was an experiment, in the honest sense of the word. I started building to answer two questions. One: can a solo builder reproduce a respected turbulence forecast from public data? Two: can the whole product be compressed into one calm sentence, delivered as a text? And I should be precise about what “building” means here, because it’s the part that still amazes me. I never wrote a line of Smooth’s code. Claude wrote all of it. My job was the plan and the taste: deciding what to test, defining what “accurate” meant, choosing which problems were worth chasing, and refusing to move on until the numbers held up.
The first discovery reframed everything: the turbulence number on these sites isn’t computed by the sites. It comes from NOAA, which publishes a forecast called GTG (Graphical Turbulence Guidance) every hour: a 3-kilometer grid over the continental US where every cell holds an EDR value. EDR, eddy dissipation rate, is aviation’s standard measure of how churned-up the air itself is, independent of the aircraft flying through it; it’s the same number pilots and dispatchers use. Public domain. Free. Anyone can download it; I did, about 340 MB per hourly cycle.
Which means a turbulence site is a presentation layer over a government file. I say that with admiration, because presentation turns out to be the entire product. One caveat matters, though: the free high-resolution feed stops at the US border. A global turbulence forecast does exist (the same science now feeds the worldwide system airlines use), but it’s a coarser grid, and the raw data sits behind accounts and licensing built for the industry, not for someone with a laptop. I checked NOAA’s servers, the cloud mirrors, and several buckets that turned out to be empty. The data isn’t the moat. The global data is the moat. And there’s a second thing the grid can’t tell you: anything about your flight. It knows the air over Kansas at 34,000 feet will be churned up at 6pm; it has no idea your plane intends to be exactly there, exactly then. Closing that gap is the entire product.
Which is the actual hard part, and it has nothing to do with meteorology. A forecast for a flight needs two things: what the atmosphere is doing, and where the plane will be in it. Those come from two sources that were never designed to meet.
NOAA tells you the weather. FlightAware tells you the flight: the route the airline actually filed, waypoint by waypoint. Marrying them means answering, for every minute of the flight, “where is the plane, at what altitude, at what time?” and then asking the weather grid what the air looks like in exactly that spot. So the engine models climb, cruise, and descent to estimate altitude along the path, samples the grid at each point at the time the plane will pass through it, pads everything with a band for where the plane might really fly (±2,000 feet, ±65 kilometers, because dispatch and pilots adjust), and finally translates EDR values into words a human uses.
Here’s the whole idea in motion, with real numbers from one of Smooth’s actual forecasts (Denver to San Francisco, June 12 cycle):
Two wrinkles made this harder than it sounds. The first is timing: the route the airline actually files shows up late. FlightAware says flight plans can arrive anywhere from a day to half an hour before departure; for the flights I tested, the filed route I could pull reliably appeared only about 90 minutes out. Until it lands, nobody, including the paid services, knows your actual route; everything earlier is an educated guess along the great-circle path. That constraint shaped the whole project, including how it could be tested.
The second wrinkle was self-inflicted. My NOAA downloads kept failing with 403 Forbidden, and I spent days convinced I’d been rate-limited into exile, politely waiting out cooldowns that never helped. The truth was dumber: I was requesting files that didn’t exist. NOAA’s directory layout wasn’t what I’d assumed, and the moment I listed what the server actually had instead of theorizing about why it hated me, the whole thing worked on the next try. The server was never angry. It was confused. I keep relearning this lesson: go look at the actual data before you build a story about it.
Verifying a turbulence forecast is genuinely hard. The plane only flies once, the forecast is probabilistic, and I don’t have a fleet of instrumented aircraft. What I can do is compare against the incumbent, and I personally think Turbli is quite accurate, which is exactly why I used it as the reference truth.
If you’re going to claim you match the incumbent, you have to define “match” before you measure; otherwise you will grade yourself on a curve and never notice. I wrote the pass bar first: same severity category, peak within ±5 points on Turbli’s 0–60 scale (which, it turns out, is simply EDR times 100; I worked that out from two screenshots), and the bumps in the same phase of flight.
The test itself had to be one coordinated session, because of that 90-minute wrinkle: the filed routes, NOAA’s hourly cycle, and Turbli’s own refresh all have to line up. So one afternoon in June: five real flights, captured from Turbli at the same moment, same weather cycle, real filed routes.
Three of five passed. The calm flights matched within a couple of points; the Atlanta–Miami curve missed by an average of 2.4 on a 60-point scale. The bumpy flights matched in the middle of the flight and failed at the ends, and every failure had the same signature: my bumps arrived too early.
The bug wasn’t in the weather. It was in the clock. I had computed flight duration as distance divided by cruise speed, which is how physics works and not how airlines work. Real flights crawl at both ends: taxi out, climb slowly, descend early, taxi in. My virtual LAX→Vegas landed in 40 minutes; the real one blocks 1 hour 15. Turbli stretches its curve across the real scheduled gate-to-gate time, taxi included; the little takeoff icon on their chart sits about ten minutes in, right where pushback-plus-taxi ends. Once I wired the airline’s actual schedule times into the clock, the too-early signature disappeared: the calm flights passed cleanly and every cruise-phase anchor landed within a few points on every flight. The error that remained traced back to me reading reference values off compressed screenshots, and to Turbli modeling the taxi segments I don’t, not to the weather. I set out to reverse-engineer turbulence physics, and the hardest-won discovery was about the flight schedule.
One more confession, because it’s my favorite. Chasing a leftover accuracy gap, I spent two days having Claude build a second pipeline to model convective turbulence: thermals, storms, the stuff that shakes a summer climb. It computed its own numbers from NOAA surface data, and it even seemed to help. Then, before hardening it, I finally asked the question I should have asked on day one: is this already solved? It was. NOAA had shipped a new version of the forecast that folds convective turbulence in. Three months earlier. Into the exact files I was already downloading. I demanded proof the paranoid way: Claude decoded 1,905,141 grid points and checked whether the published number equals the max of its component parts in every single cell. It does. Exactly.
My two-day pipeline had been double-counting weather that was already in the data. So I deleted it, all of it, about 900 lines. Fewer moving parts, less download, NOAA’s calibrated science instead of my hand-tuned proxy. The best pull request of this whole project was −900 lines, and I mean that sincerely. “Earn the number” cuts both ways: sometimes you earn it by proving your own cleverness was redundant.
The product was never a website. It was a text. Everything Smooth says has to pass one test: would this sentence sound right coming from the captain, over the PA, in that unhurried pilot voice? Specific, brief, zero jargon, zero drama. “Light bumps climbing out for the first 18 minutes, then smooth” passes. “Moderate EDR 0.24 at FL340” does not. The first machine-generated summaries flunked: robotic, repetitive, three clauses about light bumps in a row. Most of the copywriting work was merging phases and deleting words until a nervous person could read it once and exhale.
Then delivery got its own plot twist. The first real text: Twilio accepted it, and the US carriers refused to deliver it. Error 30034. In 2026 you cannot send a text message in America, even to your own verified phone, without registering your business with the carriers first. The workaround took ten lines of code and a different app: WhatsApp, where carrier rules don’t apply. Minutes after the carriers said no, a real forecast for a real flight (UA1545, Cleveland to Houston, departing about eighty minutes later) landed on a phone, and the delivery receipt flipped to the one status every builder wants: read.
Is it a business? Honestly, the willingness to pay looks low. Turbli is free. Even turbulenceforecast.com, the incumbent I’d been eyeing, now gives away an automated forecast; its subscriptions ($8.99 to $39.99 a month) mostly buy volume and a longer forecast window, and the famous $129 price is for a handcrafted, human-written forecast of a single one-way flight, a different product for a different customer. It’s hard to charge for something the incumbents hand out free.
What keeps the question open anyway: my marginal cost per forecast is a couple of cents, a nervous flyer inside 24 hours of departure is about as motivated as buyers get, and nobody in the field delivers the thing Smooth actually is, one calm sentence arriving as a text, no app, no chart, no login. If there’s a business here, it isn’t in the forecast. It’s in an experience good enough, and different enough, that someone tells their nervous sister about it. The open question is distribution, whether the people who need this ever find it.
I haven’t answered that, and I’m not going to pretend otherwise. The POC did everything I asked of it: same data as the incumbent, same curve where it counts, one calm sentence on a real phone. Figuring out what that’s worth is the next project. Verdict pending, cheerfully.
What I keep either way is this: one person, in spare evenings, using free government data and AI coding tools, built a working thing for someone he loves. Not long ago that sentence required a team and a seed round. Now it’s a hobby with a pytest suite.
The forecast window is about eighteen hours. Somewhere inside the next eighteen, someone you love is boarding a flight and quietly dreading it. The data that would calm them down has been public all along; it just needed translating into one calm sentence. Now, when Em flies, she gets one.
Smooth is live as a proof of concept. Try it with your next flight at smooth.tylergray.app, or see the project page.