Run tracker MVP

I’ve been interested in running for a few years, and I’ve used a Garmin watch to track my runs for at least the last year. Recently I signed up for a half marathon, and I’ve been looking at the bewildering range of different half marathon plans out there.
One tricky thing about the plans is that they are fairly inflexible. They assume that you’re spending e.g. 12 weeks before a half marathon, and they have quite prescriptive sessions. I often run when it’s nicer weather or if I have more time, and so I might end up doing longer distances and neglecting intervals, or if I’m an intervals craze, maybe overdoing the intervals.
So I’ve been typing my recent runs into gpt-4 and seeing what it suggests, e.g. “On Friday I ran 7k slowly, yesterday I did 12x400m intervals, what should I do today?”. This is quite manual and doesn’t store all my runs and info. So I wondered if I could make a web app to do something similar.
From a personal development point, this was a project to practice a few things:
- CI/CD
- LLM calling and prompt engineering
- Full stack deployment
Getting started
Having played around with LLMs, I thought there’d be two things to figure out as soon as possible. The first was the source for the data. I’d previously used the Strava developer API, but I found that I had to keep authenticating applications, and generally the developer feedback on Strava is quite negative. So I looked for an alternative and found GarminDB which seems pretty good!
The second was a really rapid development process. From previous experience, I know there are lots of small bugs I’d find and tweaks that I’d want to make. I really didn’t want each change to take 20 minutes to run.
So rather than adding lots of features, my first priority was to set up CI/CD!
My goal was to test this locally using a Docker container, using a docker compose command so I could do it in one line, and also to develop an automated CI/CD process that would pick up changes and deploy them in the background.
CI/CD
So I set up this CI/CD process, which would run tests and then deploy to an ECS.

I also set up AWS Codebuild checks on new and modified pull requests in Github.
MVP
I grabbed some of the GarminDB example files to fetch the activities from the past week, and combined them with a call to OpenAI, and then put the response on a Flask front end. Seemed good so far!

Just to spell out what’s happening at this point:
- Load Garmin config
- Connect to Garmin Connect using GarminDB and download activities
- Construct a prompt containing the last week’s activities, and send to gpt-4 (or some other model).
- Get the response and display it in a front end using Flask
And this is all running as one Docker container on ECS.
Separating inferences
However I found after a couple of days that my $5 OpenAI credits had been spent down, as it seems there were lots of requests on the website - I guess various crawlers. Even before this, I’d noticed that obtaining the GarminDB data took about 30 seconds, then a few more seconds to get the response from the LLM, and I thought this probably wasn’t fast enough for a user interface.
At the time I thought of creating a Lambda to download from the database and save to an S3 bucket. But since I was probably going to still have the crawler/frequent requests problem. So I decided that I would create a separate component to both grab the Garmin data, and send the request to an LLM. In this case it doesn’t need to generate a new suggested run every time I visit the homepage, just once or maybe twice a day.
So with a bit of consulting gpt-4, I decided to make this as a separate Lambda, which runs maybe twice a day, then saves the output in S3, so the Flask application can just pick that up easily. And that’s what I’m working on next!
Future ideas
- Prompt improvements: structured outputs, few-shot examples, including a training plan as RAG
- Function calling: checking the weather and my calendar to tell me when to go for a run!
- Improved code quality: Google format docstrings, remove redundant code
Enjoy Reading This Article?
Here are some more articles you might like to read next: