Pacing & arrival times
Grade-adjusted effort
The route is walked segment by segment and each segment's distance is weighted by the energy cost of its gradient: flat ground costs 1.0, climbing costs more (about +3% per percent of grade, growing faster as it steepens), and gentle descents give a little back until about −12%, where braking starts costing you again. Your total time is then distributed across the course in proportion to that effort — so a mile with 800 ft of climb gets far more clock than a flat one. The pacing splits, the aid-station arrivals, the crew sheet and the printout all flow through this one model, so they always agree.
The curve is the Run Planner’s own function, read from the same file the planner loads — this page can’t drift from the product.
The fade
Distributing time by effort alone assumes you run even effort all day. Real finishers don't — they bank early miles and slow late. We validated against real checkpoint splits from five runners at The Bear 100 and HURT 100: even-effort landed 45–185 minutes wrong through the middle of a 100. So the plan lets effort-pace drift upward linearly through the day, fitted at +1.8% per hour of running — which cut the mean checkpoint error from 66 to 34 minutes on those splits. The fade is on by default and the pacing card tells you exactly what it did; you can switch to even effort any time. And 1.8%/hr is a default, not a verdict on you — the Race fade slider takes it anywhere from 0 to 4%/hr, so a runner who holds form late can say so and one who cooks early can too. Whatever you set drives the splits, the aid arrivals, the crew sheet and the printout together.
Your Run Planner has the fade switched off, so this is even effort — a flat line. Switch it back on in the Pacing card.
Same finish time either way: the fade moves time off the early miles and onto the late ones. Computed by the planner’s own pacing function.
Night and heat
Two more things measurably slow a runner, and the plan already knows both: it computes the civil-twilight windows the moon icons mark, and it holds an hourly temperature and humidity forecast. Night fade (default 10%) slows effort-pace only inside the dark stretches this plan actually crosses. That 10% is the price on technical trail, not a flat charge on every dark mile: running at night is roughly paying your terrain penalty a second time, which for our trail factor (1.10×) is about 10%. So each stretch is charged its share of that penalty, taken straight from the surface factors below: pavement is nearly free, gravel costs about a third, trail the whole thing. Where a course has no OSM surface data — or a stretch of it is unmapped — the full price applies, because absence of evidence is not evidence of pavement. The fade also ramps in across civil twilight rather than switching on at dusk, so an arrival half an hour after sunset is charged a fraction of full dark. Heat fade (default 4%) works off the NOAA heat index computed from that forecast — nothing below 65°F, your setting at 90°F, and continuing on the same slope above it, capped at twice your setting so one freak hour cannot run away with the plan. Each row only appears when it applies. Neither changes your finish time: they move time between your miles, not onto the end. Because how fast you run decides when you arrive, and when you arrive decides how fast you run, the plan is solved by iterating until no checkpoint moves by more than a minute — so the same inputs always produce the same plan.
Surface (beta)
Per-surface effort multipliers (gravel ≈ 1.03×, trail ≈ 1.10× vs pavement) exist behind a beta toggle in the Pacing card. They're off by default because on the same real splits the fade was fitted to, they moved checkpoint arrivals by only 0–3 minutes against errors of 43–97 — real, but not where the error lives. When a factor hasn't earned its keep, it doesn't touch your plan.
Altitude
Thin air costs effort, so each stretch is weighted by ~4% per 1,000 m above 1,000 m — mid-range of the exercise literature (VO₂max falls ~6–7%/1,000 m up high; race-pace cost at ultra intensity rises about half that). Here's the honest part: we swept that coefficient against our own split data and it was a wash — The Bear tops out at 2,750 m, below where thin air really bites, and HURT is at sea level, an exact no-op at every coefficient. The physiology is real; our validation data just doesn't go high enough yet, so the number rests on the literature. Where thin air starts to cost effort is not sharply defined — onsets anywhere from 750 m to 1,500 m are defensible — and we charge from 1,000 m, the middle of that band. It is on by default on courses that climb above 2,000 m, where the control appears and you can switch it off; a Leadville plan that ignored altitude entirely was the worse default. Below that the adjustment is not applied at all. The slope stays linear until real high-altitude splits arrive to shape it.
Altitude, shown
Separately from pacing, high courses wear their altitude on the elevation profile — zone bands at the wilderness-medicine thresholds (thin air from ~3,300 ft, high from ~8,200 ft, very high from ~11,500 ft) — and an effective oxygen stat: the standard barometric formula for how much oxygen the air holds versus sea level (Leadville's Hope Pass: ~62%). That number is a fact about the air, not a prediction about your body — acclimatization, sleep altitude and individual response are yours; we just refuse to let "12,500 ft" hide what it means. The display zones start at 1,000 m on purpose: exactly where the pacing factor above starts charging effort. A band that read as sea level while the model was already billing for thin air would be the plan contradicting itself.
Hydration
The fluid target starts from a baseline of 460 mL/hr for a 70 kg (154 lb) runner in moderate conditions — adequate hydration, deliberately not the maximum a gut can absorb, because over-drinking risks hyponatremia. From there it scales by:
- Your body weight — sweat loss scales roughly with mass, so the target is anchored per-kg around the 70 kg reference. (Set it in the About-you panel; without it, you get the reference runner.)
- Your sweat rate — the 1–10 slider spans 0.75× to 1.6×, and the planner now shows what that means: for a 70 kg runner at ~70 °F (~21 °C) it is a sweat loss of 0.75 to 1.6 L/hr, with 5/10 = 1.0 L/hr. If you have done a sweat test, type the number under the slider and it snaps to the nearest step. The companion saltiness slider is a sodium concentration on the same 1–10 scale, spanning 300 to 2000 mg/L (5/10 = 900 mg/L).
- Heat & humidity — the target rises with temperature above ~60 °F, with a bump for humid air (less evaporative cooling), capped at 1.7× combined.
- Duration — very long efforts taper the hourly rate slightly (down to 0.85× past 24 h); nobody drinks hour-one volumes in hour thirty.
The result is clamped between 350 mL/hr and a ceiling set by your experience level (800–1500 mL/hr) — fluid absorption is trainable, and a beginner's plan shouldn't assume an elite gut. Per-leg carries in the plan then use the temperature forecast for the hours you'll actually be on each leg, not a day-wide average.
Your drinking target is deliberately below your sweat loss. Those are two different numbers and the planner shows both — but read the slider's figure for what it is: a reference, what a 70 kg runner on that step loses in an hour at ~70 °F. Your own loss climbs with your body size and with the day's heat, and the drinking target climbs with them too. So a big runner on a hot day can be told to drink more than that reference figure while still drinking less than they are losing, which is the rule that actually matters. Finishing a long day a little down on fluid is normal and safe; trying to match litre for litre is how people end up hyponatremic.
Sodium
Sodium is derived from your fluid volume times a concentration set by the how-salty-do-you-sweat slider — from ~300 mg/L (barely a crust) to ~2000 mg/L (white shorts by mile ten). We then take 70% of that as the replacement target: you don't need to replace every milligram, just enough to keep the system happy. Heat-acclimated athletes conserve sodium, so answering yes trims another 15%.
Carbs & calories
Carb targets are a range set by how long you'll be out and how trained your gut is. Eating on the run is a skill: roughly 60 g/hr is the ceiling on glucose alone, 60–90 g/hr needs a glucose-and-fructose mix and a gut used to it, and the 120 g/hr figures from the literature come from athletes who have deliberately practised intake. So the Gut training setting — not your experience level — drives the numbers:
Under 90 minutes stored glycogen covers it and fueling is optional; past 12 hours eating becomes the job, and real food counts as much as gels. A trained gut does not keep climbing on a multi-day effort — sustained intake is gut-limited, which is why the top band stops at 60–90 g/hr. The range then scales modestly with total vert and body weight, up to the ceiling for your level. Calories are carbs × 4. A calorie deficit over a long day is normal and expected: the plan fuels the effort, it doesn't try to replace it.
Weather: forecast vs typical
Weather comes from Open-Meteo, fetched for the course's own coordinates. Two honest modes, always labeled:
- Live forecast — when your date is within the ~16-day forecast window, you get the real hourly forecast.
- "Typical for the date" — beyond that window, we average the same calendar date over recent years at that location. It's climatology, not prophecy: the right way to plan clothing and fluids in March for a July race, and clearly marked so you never mistake it for a forecast.
As race day enters the forecast window, the plan (and your crew sheet, which fetches weather live each time it's opened) switches to the real forecast automatically.
Course data
Catalog courses come from the races' own published GPX files, imported weekly and run through validation gates: distance is checked against the advertised race distance, GPX waypoints are classified so turn markers and mile posts don't masquerade as aid stations, and courses with no elevation data get real terrain elevation from a DEM instead of showing zeros. Surface mix (trail / gravel / paved) comes from OpenStreetMap. When something fails a gate, we'd rather show less than show wrong.
Cutoffs
Aid-station cutoffs are stored as time after the gun, because that's how races enforce them (gun time, not chip time), and it's what keeps them honest when a start gets held for weather — re-base the start on the crew sheet and every cutoff moves with it, the way race officials move them.
The buffer you see is plain subtraction: the cutoff minus the arrival we currently expect. In the planner that's your planned arrival; on a live crew sheet it's the re-forecast arrival, updated every time your crew marks you through a stop — so "+45 min in hand at Twin Lakes" tightens or relaxes with how the day is actually going. Under an hour of margin shows amber; a projected miss shows red. Cutoffs come from the race's published schedule and are editable per stop in the planner — always confirm against the race's official numbers, which can change race week.
The fine print
Models are maps, not territory. TrailGoat's numbers are honest starting points built from your course and your inputs — but your gut, your training, and the day's surprises are the tiebreaker, and general guidance is not medical advice. Train your fueling like you train your legs, and adjust on the day. When the model and your body disagree, your body has seniority.
Try it on your race