Why I built carbsperhour
If you do any endurance sport for more than a couple of hours, fueling is half the game. You need somewhere between 60 and 120 grams of carbs per hour to not fall apart late in a session. The easy way to get there is commercial gels and drink mixes, which work fine and cost about two euros a pop. Do that across a long training week and it adds up fast.
So a lot of people mix their own from bulk ingredients: plain table sugar, maltodextrin, a bit of fructose. Pennies per gram instead of euros. The catch is that doing it well means juggling three things at once, and that's the part I wanted to make easy.
What it actually does
Most fueling calculators stop at a number. "You need 80 grams an hour." That number is the easy part. The hard part is the split: which gram of which ingredient goes in which bottle, what concentration that lands you at, and whether your stomach will forgive you two hours in.
So carbsperhour starts from the other end. You tell it what you already have, and it hands back a per-bottle recipe. Here's the kind of answer it gives, for an 80 g/h, 3-hour ride with table sugar, maltodextrin, two 500 ml bottles and a soft flask:
Target: 80 g/h × 3 h = 240 g carbs
Blend at this rate: 2:1 glucose:fructose
→ ~160 g table sugar + ~80 g maltodextrin
Bottle 1 (500 ml): ~90 g → ~18% (maltodextrin-heavy, stays drinkable)
Bottle 2 (500 ml): ~90 g → ~18%
Soft flask (250 ml): ~60 g → concentrate, sip and chase with water
Sodium: ~300–500 mg / L, dosed separately
That carrier split is the part I couldn't find done well anywhere else.
The science it runs on
I'm a skeptical, numbers-driven athlete, and I didn't want a black box telling people what to drink. So every number in it is real and cited in the code. A few of the load-bearing ones:
The carb ratio depends on how much you're taking, which is a two-line rule in the engine:
// calculator.js, recommendRatio()
if (gPerHour <= 90) return "2:1"; // glucose : fructose
else return "1:0.8"; // recruit more fructose transport
The reason: glucose rides the SGLT1 transporter, which saturates around 60 g/h. Fructose uses a different door (GLUT5), so adding it lets you absorb more total. Below 60 g/h, single-carb is completely fine and multi-carb buys you nothing.
Maltodextrin is the trick for concentrated bottles. It's a glucose polymer, so each molecule carries many glucose units, which means far lower osmolarity than plain sugar (roughly 0.5 vs 2.9 per gram of carb). That's why you can pack 15 to 18 percent carbs into a bottle with maltodextrin and stay near isotonic, where straight sugar would turn it into syrup.
The whole ingredient dataset carries source citations, and I open-sourced it. That's the one signal that matters to the kind of person who'd use this: it's the actual chemistry, and you can check it. I even ran into the ratio confusion myself while building the brand-comparison page, and left the question in the notes as I worked it out:
Maurten states "0.8:1 fructose:glucose" = ~1:1.25 glucose:fructose. Isnt that just 1:0.8? I dont get it.
How I built it
The core went up in essentially one day. The calculation engine is dependency-free JavaScript, open-sourced under MIT, and mirrored one-to-one in PHP so the server and the browser produce byte-identical numbers.
One habit worth sharing: before most product decisions, I'd have Claude spin up a handful of agents role-playing different experts and argue it out. Sometimes founders, sometimes actual sports-nutrition and gut-training specialists. It caught me being wrong more than once (I'd assumed 120 g/h is simply better than 90, and the research doesn't support that).
There's also a very on-topic example of me fighting the AI tone. At one point I told it:
Always when referring to our research building this page we have written "We". This sounds very AI to me.
The commit that followed was literally refactor(copy): drop the editorial "we". Which, yes, is the same thing I'm still doing today.
The honest part
Here's the thing I have to admit in the same breath. carbsperhour is genuinely good, it's polished, it's live, and for a long time it got about two visits a month. Because I built it and never told anyone it existed.
If that sounds familiar, it's the same story as everything else I've made. The calculator works fine. What I keep getting wrong is the bit after shipping, where I go quiet instead of telling anyone. Posting it to r/triathlon and writing this are me trying to fix that.
If you fuel your own long sessions, go try it at carbsperhour.com. It's free, there's no signup, and I'd genuinely love to hear if the numbers match what works for you :)