Map and analysis of Russ Cook (Hardest Geezer) running across Africa

Article publication date: 13th December 2024.

An image of Russ Cook taken from one of his Instagram videos filmed during day 337 of his journey. The shot is of Cook’s face and bushy ginger beard. Cook is grimacing and wearing swimming goggles as he is running through a Saharan dust storm. An image of Russ Cook from one of his Instagram videos, from day 337 of his journey. He wore swimming goggles to allow him to keep running during a dust storm in the Sahara. On 7th April 2024, Russ Cook finished his “Project Africa” run between Africa’s southernmost and northernmost mainland points. Cook, also known as Hardest Geezer, ran about 16,300 kilometres (10,100 miles) in 352 days, supported by a crew who travelled by motor vehicle. He is the first person known to have completed this route on foot. In this blog post, I have analysed his GPS recordings and other data, in order to better understand how he did it.

Contents

The route

A map of Africa showing Russ Cook’s running route as a wiggly line between Africa’s southern and northern extremes. Days of the route are shown in alternating red and black, with day numbers and rest days labelled. The Natural Earth base map shows physical colours with shaded relief, along with lakes and rivers. Countries, eco-regions and some major cities are labelled. There is a link to a higher-resolution version. A map of Cook’s running route across Africa. Days of the route are shown in alternating colour, with day numbers and rest days labelled, as indicated in the legend. Click here to view the high-resolution version. The map shows the route that Russ Cook and his team took across Africa. The team had some idea of the route at the start, but they adapted it during the expedition to avoid high-risk areas and closed borders. The more direct route across the Sahara was considered too dangerous due to political instability. Cook started his run in April, which allowed him to avoid the summer heat in both the southern and northern hemispheres.

Route data and analysis

Key numbers and statistics

Here are some summary numbers for the run:

Start time 07:24 UTC+2 on 22nd April 2023
End date 16:43 UTC+1 on 7th April 2024
Start point Cape Agulhas (-34.833222 °N, 20.000000 °E)
End point Cape Angela (37.346944 °N, 9.742222 °E)
Duration 351 days, 10 hours, 19 minutes
Number of ‘rest’ days 43
Distance 16,256.1 km (10,101.1 miles)
Mean daily distance 46.18 km (28.70 miles)
(excluding rest days) 52.61 km (32.69 miles)
Longest day 109.95 km (68.32 miles)
Countries visited 16

The straight-line distance between the start and end points is only 8,061.3 km (5,009.0 miles), less than half of Cook’s route. However, such a route would be impossible to run, for example because it crosses the Gulf of Gabès off the coast of Tunisia.


Notes on distance measurements: There are two main sources of uncertainty in the stated distance totals. The first is that data is missing for a few days during the Sahara segment (specifically, days 309, 310, 312, 315, 318). I don’t know what caused this. (If you know, please contact me. For these missing segments, I assume straight-line distances, which is probably quite accurate based on Cook’s general pattern in the Sahara, but it is certainly an under-estimate. These missing days are shown differently in the distance histograms. Their total distance is 266.1 km.

The second source of uncertainty is that GPS recordings do not provide a perfect measure of distance. For example, the length of a jittery recording of a path is longer than the true path. The recording interval also affects the total distance, with a shorter recording interval leading to a greater total distance (related to the coastline paradox). Cook’s recordings mostly have the same recording interval of 1 second, but a significant minority use a longer interval (usually several seconds). Overall, though, this second uncertainty should be quite small. Note this can also affect the estimates of his running pace, shown in the activity log below.

It is very likely that there are small differences between my method for calculating distance and Strava’s (for example, choice of projected coordinates), so the totals might not agree perfectly with those shown on the Strava website for daily tracks.

Running activity log

A figure showing Russ Cook’s running activity throughout Project Africa. The figure has two panels. The left panel is an ‘activity grid’, with axes of ‘Day of trip’ and ‘Time of day’. Each pixel in the grid represents a 10-minute interval. Darker pixels indicate faster running. There are two black curves which show the local sunset and sunrise times. The right panel shows the daily total distance as a bar plot. Specific intervals are labelled with letters that indicate events (A, B, …) which are described in the text. Russ Cook’s running log. Left panel: The activity grid, which shows when he was active on each day of the trip. Each pixel represents a 10-minute interval. Darker pixels indicate faster running. The black curves show the local sunset and sunrise times. Right panel: The daily total distance. Grey columns are estimated distance (rather than recorded). The labelled events (A, B, …) are described in the text. The activity log shows when Cook was active during each day of his trip. For most of the trip, he didn’t start running until 1–3 hours after dawn. To begin with, he experimented with continuing to run after sunset, but after some security incidents, he settled with stopping at sunset. Towards the end of his run, he returned to running after dark. He ran nocturnally for much of the Sahara section, and then in Algeria and Tunisia he was comfortable with running in the evening darkness.

A histogram of Russ Cook’s daily running distance. The distance has as roughly normal distribution centred on 52 km per day, except for a number of zero days. A histogram of Cook’s daily running distance. Grey bars show days that were not recorded and were estimated as straight-line paths. When not disrupted, he typically ran 50–60 km per day, as also shown in daily distance summary histogram. He usually spread this distance over three sessions. His consistency was very impressive. For example, during the last 20 weeks, he had only three days off (and even these were not for rest). Throughout the trip, almost all of his ‘rest days’ can be explained by incidents. He described these incidents in exuberant and colourful Instagram updates, which I used to make this summary table:

Event Day(s) Description
S 322 Visiting Sahrawi refugee camp
R 302–318 Crossing Sahara, night running, no updates, some data missing
Q 291–292 Food poisoning and visits to Nouakchott embassy
P 215–216 Struggling with injuries
O 200–206 Lower back injury
N 194 Van accidentally filled with petrol instead of diesel
M 181–185 Steep, muddy roads (avoiding conflict zones)
L 167–169 Food poisoning
K 136–142 Support van breaks down, then crashes during towing
J 125 Returned to Cabinda to fix Congo visa issue
I 111–121 Logistics in Cabinda
H 104–106 Separated from team and held captive (twice) deep in jungle
G 75–88 Return to Windhoek for new visas due to passport theft
F 64 Whole team robbed at gunpoint in van
E 45–46 Rest and doctor visit due to blood in urine
D 39 Visa day including return drive to Windhoek
C 35 Support crew evade armed men
B 26–28 Stomach illness
A 17–18 Crossed border without van and ran solo overnight

My methods

If you are not interested in technical details, I suggest that you skip to the final section. It’s nice to note that all the tools I used are free and open source.

Getting the GPS recordings

The most difficult part was obtaining the dataset. Russ Cook uploaded his GPS recordings to Strava. You might think that the easiest approach would be to use the Strava API, but this requires Russ Cook himself to authenticate—even though his account is public! I didn’t want to bother Mr Cook, and I thought it was unlikely he would even notice my request, so I looked for another way.

I discovered that a Reddit user, u/hangglidingcrow, had downloaded Cook’s files, one by one. They said it took a few hours, while watching television. They generously uploaded the files for anybody to download here.

Unfortunately, the files have no time-stamp information. It seems that Strava removes this information from the GPX files before serving them up. This makes it impossible to analyse pace or activity time. I’m not certain why Strava does this, but it might be to reduce file size, for user privacy reasons, or to obstruct hobbyist map-coders. Since Russ Cook was on a publicised mission, it does not seem like an invasion of privacy to reconstruct the full dataset with time-stamps. This is possible because Strava allows GET requests like this: https://www.strava.com/activities/11075843853/streams?stream_types[]=latlng&stream_types[]=time where 11075843853 is the activity ID. You have to be logged in, and it will only work if it is an activity for which you have viewing access to. You can request other bits of information, such as heart rate, as indicated in the API reference. The request will return JSON with arrays of coordinates and time. The times are given in integer seconds relative to the start time of the activity. I did not work out how to request the starting time-stamp, but this time-stamp is also written on the activity page (in this example, that would be here). I assumed the time zone for each track was defined by the time zone of the starting point.

This process could be automated, but that would be a violation of Strava’s terms of service, and I would never do that to such a benevolent corporation.

Processing

Using the method above, I gathered a JSON file for each of the 372 recordings, which contained coordinates and elapsed time. I also had the starting time stamps. In Python, I processed this information into a GeoPandas GeoDataFrame (GDF) with a LineString geometry, with one row per recording. I applied time zone information. I calculated the “day of trip” for each recording (some recordings continue through midnight, but these still belong to the preceding day). I saved the GDF as a GeoPackage, and used that to make the map in QGIS.

For the activity grid, I also needed distance information. I used pyproj to re-project each track into a local coordinate system and calculate the distance between each point. The JSON file has a ‘moving’ flag, so I ignored any distance from non-moving time steps (for example, if the recording device was paused and then restarted in a different location). To create the grid, I binned all the distance information onto a grid of day and time, using the functions digitize and bincount (with weights) from NumPy. It was necessary to first split any time steps that crossed over a grid line.

I calculated sunrise and sunset times with the using the Astral Python library. I used Cook’s most recent position for a fixed morning and evening time.

Sharing code and data

I like to share code and data, but it takes some work, and I’m not sure anybody would like to see it anyway. Until I find time to tidy things up and post them here, please contact me if you are interested. Please explain what you want and what you plan to do with it.

Future steps and conclusions

It would be possible to analyse more aspects of Cook’s journey, for example weather, elevation gain, road surface, heart rate, cadence, and moving time. If this is something you’d like to see, please let me know in the comments section below or via my contact details (where you can also follow me for future updates). I would also love suggestions for other amazing journeys to look into, as well as other comments and corrections.

Running the length of Africa is obviously an impressive feat. I am even more impressed after doing this analysis, and seeing how consistent Cook’s effort was. He also overcame significant personal challenges relating to mental health and addiction. I find this inspiring and I hope you do to! If you do, please consider donating to his charity appeal.