Hacking My First 50 Miler Ultra Marathon With Code

My First 50 MilerAfter a fairly good year of running (with no major injuries!), I wanted to see if I could run my first 50 miler in 2014. Googling around, I decided on Lake Sonoma 50 for its incredibly picturesque course. The day after pacing my cousin at the Quarry Lakes Marathon, I loaded up the ultra signup page waiting for the registration to begin at 8am. My boys were watching over while my wife had the ‘you gotta be crazy to do this‘ look. After reloading the page repeatedly, I was lucky to get in at 8:02am. Apparently the race was sold out in 37 minutes and almost crashed the servers!

My First 50 Miler

As soon as I saw the email that said ‘You are now a confirmed entrant’, the butterflies began. 50 miles is a long way to go on feet and by the numbers, this course’s going to be tough: 10,000 feet total elevation gain (and loss), 86% single track and 9% dirt fire roads, 12 creek crossings, relentlessly rolling hills with 3 significant climbs, 10 aid stations and a 14-hour cut off.

Obviously, I ain’t racing. Heck, I just want to make it to the finish line in one piece, hopefully still smiling and not dry heaving at mile 30. The closest I’ve come to running anything remotely like this was the Berkeley Trail Adventure 50K with 6,800 ft elevation gain and the Headwaters Ultra 50K where I was on the course for nearly 7 hours. What I’m looking for is to really maximize the effectiveness of my 20 – 30 miles/week of running. I’m not an elite runner (well, duh!) and will take quality over quantity when it comes to training. So why not use code to figure out the course?

Hacking Strava’s Data

I started with ultra runner Galen Burrell’s Strava Feed and immediately realized that I don’t want to be parsing GPX files. Chrome’s Developer Console to the rescue. Turns out the Strava UI loads a JSON object containing the time, distance and altitude of the run through it’s /streams API. Use the 'Copy As cURL', I could now get at this JSON file.

Hacking my First 50 Miler

Next step was to write a stravit.js script with node.js to parse this JSON and build up information about segments, elevation profile, and gain/loss by mile. And the results were surprising. Here’s the side by side comparison of the local PG&E Trail that I run on, the Berkeley Half Marathon, as well as the Lake Sonoma 50M.

PG&E BH13.1 LS50M
Total Distance 9.72 13.1 50
Min Elevation 339.24ft 2.95ft 345.80ft
Max Elevation 1646.98ft 209.32ft 1204.72ft
Total Elevation Gain 3423.56ft 413.06ft 10786.75ft
Total Elevation Loss -3433.40ft -569.88ft -10752.62ft
Flat Distance 0.88 miles 7.07 miles 29.07 miles

Gain/Loss for My First 50 MilerWait, my first 50 miler has 29 miles of flat running? Now that contradicts with the 10,000 foot elevation gain. Hmm. The phrase relentlessly rolling was described by many that ran the course. Also notice that the min/max elevation doesn’t get very high above the sea level. Let’s see what relentlessly rolling is all about. This becomes obvious when you look at the gain/loss on a mile-by-mile basis. In the screenshot to the right, red’s climbing, green’s downhill. There are 30 up/downs in total with each of the up/down roughly about 300-400 feet in elevation change. Now this is cool!

So in order to train for my first 50 miler, I simply need to pick a smallish hill and do hill repeats like there’s no tomorrow. More importantly if I can figure out a way to power hike the ups and run the downhills to average a 12 minute/mile, I’ll finish the course in 10 hours. Of course this doesn’t include the chaffing, blisters and whatever nightmares I’m going to face in those hours. But it’s nice that I can now quickly summarize any run in a way that I can mentally understand the course. That said, I’ll leave you with this quote from Ephraim Romesberg (respect!):

I always start…with very lofty goals…the goals get evaluated down to… where the best I can hope for is to avoid throwing up on my shoes.

And in case it wasn’t clear, the code’s on GitHub.

How did you train for your first 50 miler?

[sc:follow_me ]