In a productivity app I’m currently working on I wanted to incorporate the idea of a streak feature.
Streaks are nothing new in the world of productivity. Famously popularized by Jerry Seinfeld’s productivity secret.
In Mr. Seinfeld’s case, he used a calendar to mark each day he sat down to write. Eventually the marks create a chain and keeping the chain going (or not breaking the chain) was pressure enough for him to sit down and write every day.
I’ve iterated a few times on my solution for streaks in my app. And before I share where I landed I wanted to work a little backwards.
What I mean by this is there are multiple ways to implementing a streak. The most common one as seen in apps like Snapchat, is to award users with an unbroken streak as long as they interact with the application in some way every 24 hours.
And so before sharing my solution, I’d like to challenge you. If you’re reading this and also implementing a streak, first think about what you would like the people using your application to do on a regular basis in order to keep the streak going.
Once you’ve determined that, I also challenge you to think about both the positive and negative effects of the streak. While a streak is motivating is it your intention to have them show up to your application for the sake of keeping the streak going?
My first iteration of the streak in the system was pretty straightforward, determine whether the person had completed a task within the past 24 hours. If they did, then keep their streak going.
But then as I was participating in the streak function—while motivating—I noticed something that didn’t fit my life style. My weekends are less regimented. I enjoy spending time with my wife and kids and often times that means time away from my computer.
While this fits my use case, I think it will also have benefits for others as well that aren’t like me. While I’m definitely for productivity, I’m also strongly for a healthy mental well-being. For this reason my next iteration will likely have the ability to set up a schedule to not count against the streak. Like a pause button. To allow for more mindful productivity.
Implementing a pause is still aspirational at the time of writing this article, but I thought I’d share my solution.
In my application there are two models which work together to achieve the streak.
user model which is used to represent a person using the application and then a
task model used to represent tasks.
user model contains three specific fields that are used for the streak function. Those fields are
streak field is a numerical field that is used to keep track of the active streak.
last_streak is used to keep track of the last streak. If there is only a single streak, then the
last_streak are the same. The reason I have two fields is that if for some reason a user had lost their streak, I want a way to recover their hard earned streak for them.
streak_updated_at field is a timestamp field which gets updated when the streak gets updated. This is then used to determine whether the person has completed a task within the past 24 hours.
task model contains two fields which are used for the streak function. Those fields are
completed_at is a timestamp which updates the moment a person marks a task as completed.
streaked field is a boolean which also gets updated the moment a person marks a task as completed but only the first time. By default this field is set to
false. But when completed, it gets marked as
true. I did this because sometimes you mark a task as completed but it might not be true. I also didn’t want a person to game the app, so
streaked acts as a way to determine if a task has already been accounted for towards a streak.
When a person marks a task as complete for the first time, the application will determine if the last task was completed within 24 hours by checking the
streak_updated_at task of the
user model. If it is within the 24 hours, then the
The task also then gets marked as
streaked by having this field marked as
true. With the
completed_at set to the current timestamp.
When a person marks a task that has been marked
true then the application will just update the
completed_at with the current timestamp but the streak won’t be updated.
How is 24 hours determined?
The last piece to the streak is that every person using the application has a common time to complete a task. That time is coordinated universal time (UTC) a time is commonly known amongst computer servers.
When a task is completed, the application checks to make sure that it is completed in the current UTC day. Then it checks to make sure the
streak_updated_at time was completed within the last UTC day. If both criteria are met, then the streak is incremented.
The purpose of this article wasn’t to provide a streak solution in a particular programming language but it was more as a strategy based around rules for what the streak should enforce.
I hope with what I’ve shared it’ll give you ideas on how you can implement your own streak feature in an application you might be involved in.