How to Track Workouts in Notion

24 August, 2020 | 3 min read

I track religiously using Notion. Recently, I've been working on creating a workout tracker in Notion that I'd actually want to use.

I do cardio, bodyweight exercises, and weight lifting. So it has to be able to track all three. And I don't want to use multiple databases.

Of course, we can't forget important metrics like duration, pace, total weight lifted, total repetitions, and 1 rep maxes.

I keep track of those metrics to really know how I'm progressing. But they're not necessary. Maybe you just want to write down what you did, and that's good too. It works for both things.

Get the template here

Alright. Without further ado: click here to get the template.

How to use it

Cardio Tracking

Let's start with cardio. Both running and walking use the same properties, but I like to divide them using a type filter. But that's all done for you in the template.

My running stats. Yeah I'm not the fastest runner. I'm more of a weight lifter.

Every time you want to track anything, you add it using the template. There are three templates: walks, runs, and workouts.

For walks and runs, there's only a few fields that you have to fill in.

  • Date
  • Distance
  • Hours
  • Minutes
  • Seconds

And the rest is filled out for you automatically — even if you didn't use a template. The templates are just to automatically select the appropriate icon and type.

Time and pace is automatically calculated and shown in a readable format. I'll try not to get too technical, but this was achieved using a few formulas.

Calculating and formatting pace

First, I wanted to grab the pace as a decimal number. This was pretty simple.

prop("Minutes") ? ((prop("Hours") * 60 + prop("Minutes") + prop("Seconds") / 60) / prop("Distance (km)")) : 0

We're just checking if the "Minutes" property is filled out - if not, we'll set the propety to 0.

But formatting in Notion formulas is a bit harder. Especially if you want to handle edge cases.

((prop("decPace") / 60 >= 1) ? ((prop("decPace") / 60 <= 9) ? ("0" + format(floor(prop("decPace") / 60))) : format(floor(prop("decPace") / 60))) : "00") + ":" + ((floor(prop("decPace")) % 60 <= 9) ? ("0" + format(floor(prop("decPace")))) : format(floor(prop("decPace")))) + ":" + ((round((prop("decPace") - floor(prop("decPace"))) * 60) <= 9) ? ("0" + format(round((prop("decPace") - floor(prop("decPace"))) * 60))) : format(round((prop("decPace") - floor(prop("decPace"))) * 60)))

Remember, if you change any property names, you have to change them in the formulas as well.

Formatting time

Time was also just the issue of formatting and handling edge cases. Again, I think I did pretty well, even though it says :: when there isn't any input yet.

((prop("Hours") <= 9) ? ("0" + format(prop("Hours"))) : format(prop("Hours"))) + ":" + ((prop("Minutes") <= 9) ? ("0" + format(prop("Minutes"))) : format(prop("Minutes"))) + ":" + ((prop("Seconds") <= 9) ? ("0" + format(prop("Seconds"))) : format(prop("Seconds")))

Workout Tracking

Tracking our workouts depends on using another database to enter the exercises we do during our workout. But I've done my best to minimize steps and automate as much as possible.

When you create a new workout using the template — which is a must for tracking workouts like this — you're greeted with this screen.

Workout Template screen

Here's the important part.

For exercises, you have to enter these properties

  • Date
  • Type

And that's it.

Ok, not really. There's a bit more.

See that linked database at the bottom? That's where we'll enter which exercises we've done.

For each exercise you do, you:

  • Write what it's called
  • How many sets you did
  • Repetitions you performed in each set
  • Weight lifted (if any)

Then it automatically calculates your one-rep max for that entry.

It also automatically calculates the total amount of weight you lifted and repetitions performed for the whole workout. And displays which exercises you did.

Smart, right?

Maybe. There is a limitation: you can't use different weights for the same exercise.

It's quite popular to do have a rep/set scheme like 5/3/1, which would require lift different amounts of weight for different amounts of reps.

But, we can overcome this. Just add another entry for the same exercise. Like this.

Squats entered in the workout exercises database.

How the Workout Tracker works

Here's a quick explanation.

The exercises we put in the 'Workout Exercises DB' actually get filtered. We're only showing the exercises that have a relation to that workout session. This is a feature that Notion has implemented, which allows us automatically relate a new entry to a database using templates.

See? Our workout entry was automatically added to the filter. We're only showing exercises done for that workout session.

This is also why it's so crucial that you use the template to track new workouts. It wouldn't work automatically if you didn't.


I hope that this helps you. I've tried to make it as accessible and easy to use as I could.

If you have any suggestions or questions, feel free to get in touch. I'm always glad to hear from you.

Liked this post? Join the newsletter