Or just add to each user record the time of their last action if their last action is more than a day old (or what ever interval.) Given that you usually have the user record already in memory, this can be moderately efficient. Then you can pass through your user records linearly with no memory usage to figure out MAU, DAU, YAU, etc.