What this is
I wanted to build a full data pipeline from scratch, end to end, that pulls data from an API, transforms it, loads it, and visualizes it, and I wanted to do it on something I actually care about, and I am fascinated by rocket launches and their history, so that is what I picked. Once it is running it keeps itself up to date, so I never have to touch it again, and the page rebuilds whenever new launch data comes in.
The numbers below cover orbital and suborbital launches worldwide, from the first Sputnik launch in 1957 to the next one on the schedule. Use the range buttons to switch between all of history and the more recent, much busier years.
Launches in 2026
254
−5 vs this point last year (259)
Success rate, 2026
97.2%
92.7% across all 7,656 launches
Next launch
Long March 4B | Unknown Payload
· Go for Launch
Why launches
Launch counts barely moved for decades, and then they climbed fast in the last few years as reusable rockets and new providers arrived. Success rates tell their own story. The data is also messy in the ways real data is: statuses change, launch times slip, and a “launch” can mean a few different things.
How it works
The whole system is a few files in this repository and one scheduled job. There is no server, no database, and no paid service.
- Fetch. A Python script asks the Launch Library 2 API for launches. The first time through, it loads history oldest-first and remembers where it stopped, and after that it only asks for launches that changed, which includes upcoming launches as their dates move.
- Store. Everything lands in one file with one line per launch. New data updates existing lines instead of adding copies, so a run with nothing new changes nothing.
- Transform. Plain SQL files, run with DuckDBA lightweight database that runs inside a script, so you can query files with SQL without setting up a server., turn that raw file into small outputs: launches by year, by provider, by country, by orbit, success rate over time, and the next launch.
- Update only on change. The job saves the new files only when they differ from what is already there, since every change rebuilds the site.
- Build. The site is static, so the numbers are already in the page when it loads, and a small script draws the charts and runs the live countdown.
Decisions I made along the way
- What counts as a launch. I only count launches that reached a known outcome: success, failure, or partial failure. Scheduled and canceled launches are not counted. A partial failure is not counted as a success, so success rates are a little stricter than some published figures.
- Fair year-over-year comparison. Comparing a half-finished year to a full one is misleading, so the first number compares this year so far to the same stretch of last year.
- Country means the provider’s country. A Russian rocket launched from Kazakhstan counts as Russia, because the operator is the more useful grouping for most questions.
- Free by design. Everything runs on GitHub Actions and static hosting. I kept the update frequency and request counts low enough to stay inside every free tier, including the API’s.
- Being a good API citizen. Anonymous access is rate-limited for a reason, so the script caps its own requests, pauses between them, and credits the source on the page.
What I would do next
I would add per-provider pages and a launch-site map, and track launch cadence for individual rocket families. The pipeline already stores the fields for it.
Credits
Launch data comes from Launch Library 2, provided by The Space Devs. Thank you to them and their community of contributors for keeping it open.