Founder Updates|Jan. 3, 2022, 2:45 a.m. | 26
2021 Year In Review & Trackster By The Numbers
We had a phenomenal year of growth and some tough lessons... check out our reflections on '21!
2021 On Trackster
First of all, thank you. Thank you to all of the wonderful, incredible and super fit community of Trackster users. It's easy to get caught up in the day to day operations of working on Trackster and lose sight of the fact that there are real, actual human beings behind every account. One of the most fun things to do is to stop and remember that with every training post there is a story. Every new post means that someone, somewhere, decided to lace up their running shoes, start their watch and get moving. It really takes courage and guts and without that, Trackster would be nothing. It truly never gets old seeing people use our app but more than anything it's special to see human beings striving to be their best in sport and in life in general. Y'all make Trackster possible and beyond worthwhile!
It's at this transitory time of year that it makes sense to take a step back and reflect on the last 365... and I will start but breaking down the numbers.
2021 TRACKSTER BY THE NUMBERS:
- 1,886,442,122 total METERS or 1,172,431 total MILES (440% increase)
- 148,257 total POSTS (240% increase)
- 342,704,514 total SECONDS or 10.86 YEARS or 566.64 WEEKS or 95k HOURS
- 1 server crash / unplanned downtime
- 1,138.3 miles = my personal total, with my longest run at 24 miles
- 13 major iOS and Android Updates Released
- 4,176 miles = most miles ran, Reid Buchanan
- 365 days = longest daily streak, Nate Kraft
- 1 Major GPS Integrations added (Coros! Wahoo coming Feb 1 👀)
- 60 Boost Beta Subscriptions
We have a ton more planned and coming in the next year. We're just getting started with this mission... the mission to get the world running and to be the best running app ever created!
Right now I feel extreme gratitude and appreciation for our current daily users. But I would be lying if I did not admit that I am also feeling perturbed, hella perturbed in fact. Everyday I see runners post about our competitor's apps and products. And, while there are some fine competitors on the market, I know for a fact that not a single company or app is working and willing to help the running world more than Trackster is. It's only a matter of time until the world at large can see this as undeniable and I all I can do is channel my emotions into work, into progress. If we keep our focus laser sharp on improving the running world and proving value for athletes, coaches and teams, we'll be just fine.
Year In Review Emails
To wrap up 2021, we're sending out '2021 Year In Review' emails to all users. You can see some examples of these below.
It was a pretty fun project to work on and I wanted to share some details on the process and how the emails are crafted. This is going to get a bit nerdy and into the details of our code but I hope it proves pretty cool to at least one person.
We simply loop through all of the active users on Trackster in the last year. Then, once we get their stats, training posts and the like, we start generating GIFs.
All of the GIFs are generated via Python on our worker backend server. Every single frame of every GIF is coded to precision so that the GIFs can be generated seamlessly and quickly.
Here's the code for the very first GIF in the email.
frames =  x = 0 y = 0 offset = 50 sz = (800, 800) fin =  number_of_colors = 1 cl1 = ["#"+''.join([random.choice('0123456789ABCDEF') for j in range(6)]) for i in range(number_of_colors)] tl1 = ["#"+''.join([random.choice('0123456789ABCDEF') for j in range(6)]) for i in range(number_of_colors)] pic_url = "https://trackstermedia.s3.amazonaws.com/media/shoe_images/default-pro-pic_2rUKcAm.png" if 'user_pic' in data: pic_url = data['user_pic'] f1 = urlopen("https://trackstermedia.s3.amazonaws.com/static/fonts/FiraSans-Light.ttf") font1 = ImageFont.truetype(f1, 150) font2 = ImageFont.truetype(urlopen("https://trackstermedia.s3.amazonaws.com/static/fonts/FiraSans-ExtraBoldItalic.ttf"), 120) font3 = ImageFont.truetype(urlopen("https://trackstermedia.s3.amazonaws.com/static/fonts/FiraSans-Medium.ttf"), 55) fontSmall2 = ImageFont.truetype(urlopen("https://trackstermedia.s3.amazonaws.com/static/fonts/FiraSans-Light.ttf"), 32) fontSmall = ImageFont.truetype(urlopen("https://trackstermedia.s3.amazonaws.com/static/fonts/FiraSans-Light.ttf"), 40) fontSmall1 = ImageFont.truetype(urlopen("https://trackstermedia.s3.amazonaws.com/static/fonts/FiraSans-Light.ttf"), 20) fontBig = ImageFont.truetype(urlopen("https://trackstermedia.s3.amazonaws.com/static/fonts/FiraSans-ExtraBoldItalic.ttf"), 60) r = requests.get(pic_url, timeout=4.0) with Image.open(BytesIO(r.content)) as im: for number in range(40): image = Image.new("RGB", sz, cl1) draw = ImageDraw.Draw(image) if number > 15: draw.regular_polygon((600, 650, 700), 3, rotation=90, fill=tl1, outline=None) if number > 5: draw.text((28,0), "2021", fill=(255, 255, 255), font=font1) draw.text((28,145), "This Year On:", fill=(255, 255, 255), font=font3) im.thumbnail((200, 400), Image.ANTIALIAS) image.paste(im, (28, 410)) draw.text((28,510), data['full_name'], fill=(255, 255, 255), font=font3) if number > 9: draw.text((28,540), "TRACKSTER", fill=(255, 255, 255), font=font2) frames.append(image) width = 200 center = sz // 2 color_1 = "brown" color_2 = "yellow" max_radius = int(center * 1.5) step = 20 print(" making gif start 2") r = requests.get("https://trackstermedia.s3.amazonaws.com/media/shoe_images/1024.png", timeout=4.0) with Image.open(BytesIO(r.content)) as im: for number in range(60): image = Image.new("RGB", sz, "#e9e9e9") draw = ImageDraw.Draw(image) draw.regular_polygon((000, 000, 700), 3, rotation=-90, fill=(255, 255, 255, 1), outline=None) im.thumbnail((100, 100), Image.ANTIALIAS) image.paste(im, (10, 10)) draw.text((14,145), "Great job. You achieved: ", fill=(0, 0, 0), font=font3) if number > 9: draw.text((14,510), data["total_distance"], fill=(0, 0, 0), font=font2) if number > 12: draw.text((14,630), data["total_time"], fill=(0, 0, 0), font=font2) draw.line( ( (28,225), (28, min( 505, max(225+(40*number), 225))) ), width=5, fill="#3a3a3a") if number > 29: draw.multiline_text((410,240), str(data["total_posts"]) + " total\nposts", fill=(0, 0, 0), font=fontSmall2) frames.append(image)
Anyway it was a great learning experience to generate dynamic GIFs via code and tie it together with our users' training data. I'm thinking we should use this stuff in other ways on a more regular basis besides just a yearly wrap up email.. but we'll see!
The 2022 Plan
Everybody has a plan until you get hit in the face. It's true. It's really hard, impossible actually, to have a totally comprehensive plan for a business in the software startup realm. I've learned, though, that it is really helpful to plan as much as possible. Then, when things go off track, there's always a north star to find or script to stick to.
Here's where the priorities are going into the new year.
Push out as much running & Trackster content as possible
- In months and years prior, we've had some success with YouTube and Instagram related content. However, without a great app to back our brand up with, people were often confused and disappointed after looking into Trackster further. Now, the app is ready to surprise people and our content is a great trojan horse if you will to introduce people to it.
Concise, small, quick and smart app updates
- Our app is still not perfect. It will never technically be perfect. It's the process and pursuit of perfection that matters... just like running. To me, right now, this means making small and calculated adjustments to improve what we already have. We have some real momentum and a number of users who are, in lack of a better term, 'addicted' to our current product. I don't see the need for a massive overhaul or starting from scratch. One day, maybe. But not in 2022.
Build more relationships with dope people and HAVE FUN
- There's no question that I find building the Trackster app to be a wildly fun endeavor. But, at the same time, it's crucial to get outside and interact with real humans face to face. To get away from the laptop and app is how it can best be improved. It takes discipline and it's been a tough lesson for me. This has been the purpose of the new Building Boost YouTube series and really the reason behind my living in Boulder, CO. There's so many incredible athletes and people there that I'm ready to meet and have some fun training with.
All in all, I'm super confident in what we've got cooking with Trackster these days. It's really a lot like training and running. Our main focus should be on consistency, fundamentals and enjoying the process - not worrying about the results.
Thanks again to all who have been a part of the journey... if you're just discovering Trackster for the first time make sure you use the app and get started training with our community! This year is going to be sick!