How Much DAU Will This New Feature Bring? (When Carrying Capacity Doesn't Fit)
What's the final user count for new features A and B?
A quick pop quiz before we dive in!
Let's say we have two recently launched features: A and B. Looking at the post-launch data, Feature A brings in 6,700 new users a day with a D1 retention of 7%, while Feature B brings in 600 new users a day with a D1 retention of 35%. So, what DAU will Features A and B respectively converge to? Which feature will secure more users in the end?
New features are new to me, too...
During the product development cycle, we often roll out new features—both big and small—to explore new opportunities. The newer the feature, the harder it is for both POs and DAs to get a feel for the numbers. Figuring out how much a feature can grow, or what we need to do to make it grow even more, is a highly complex question.
Alarmy has been trying out several new features lately, so we're no exception to this dilemma. I'd like to share my thoughts on how to more easily grasp the numbers and extract strategic directions when analyzing these entirely unfamiliar features.
What actually matters?
The process of analyzing a new feature's capacity and setting a direction for its metrics ultimately boils down to being able to answer these two questions:
Which lever can move the total user count, and by how much?
Can these levers act as leading indicators? Does measuring them take so long that it delays taking action?
For example, if doubling new users only increases the actual user base by 10% because retention is too low, but increasing retention by just 20% would boost actual users by 50%, then focusing on retention is obviously the smarter move.
And even if we focus on retention, if we rely on the monthly retention metric rather than daily, the feedback loop for our actions stretches from one day to an entire month, slowing down our subsequent moves.
The formula that shook startups a few years ago
A few years back, Toss cited the concept of "Carrying Capacity," and this framework for estimating a service's capacity drew a lot of attention.
CC = # of new daily(period) customers / % customers you lost each day(period) (Reference)
Using the number of new users and their daily churn along with the standard formula for the sum of a geometric series, you can estimate the service's user base as the sum of daily retained users—a seemingly very simple approach.
However, when you actually try to apply this to a real service, you sometimes can't help but wonder, "Wait, is this right...?"
Taking Feature A as an example, the formula leads to the conclusion that despite 6,700 new users joining every day, the DAU is only 7,200. (Spoiler alert: in reality, it's over 20,000.)
6700 / (1–7%) = 6700 / 0.93 = 7200
The core assumptions of the Carrying Capacity formula are as follows:
Active users are defined as those who have actually experienced the WoW factor.
As a result, it expects a low churn rate and assumes that retention from Day N to Day N+1 remains constant (assuming the exact same r every day).
In practice, if you assume an 80% retention rate and plot the graph of y = 0.8^x, you'll see it converges to almost 0 by day 30. This shows that as the retention metric gets lower, the number of retained users tends to be underestimated more than you'd expect.
In reality, though, most services include regular visitors in their active user count, and the churn rate usually varies day by day rather than dropping at a constant pace. This is where the gap between the formula and actual user numbers emerges.
The universal retention curve of new users
In a typical product, new users show a relatively steep churn rate early on right after onboarding, but as the days pass, the churn slows down, forming a flattened retention curve.
A retention curve that better represents this is a power law function in the format of y = a * x^b. As seen in the image below, rather than simply converging to 0, the curve's slope gradually decreases and converges to a value above 0.
In other words, if we define y as the 'retention rate after x days' and find a (the starting point) and an appropriate b (which determines the shape of the curve) in y = a * x^b, we can estimate the total user count through the cumulative sum of y.
Total user count today
= Today's new users + Retained users from yesterday's new users + Retained users from the day before yesterday's new users + … + Retained users from new users N days ago
= New users * y(0) + New users * y(1) + … + New users * y(N)
= New users * (y(0) + y(1) + … + y(N))
A slightly more 'plug-and-play' formula
It might look a bit complicated, but with some generalization, we can create a formula that is customized for each service yet easy for anyone to use.
Total user count today
= New users * (y(0) + y(1) + … + y(N))
= New users * a * (1^b + 2^b + 3^b + … + N^b)
Here, since a is the starting point, we can use the D1 retention value, and b is the coefficient that determines the overall retention curve.
If we have to wait a month or two to get the retention curve of a real feature, the entire point of doing this calculation largely disappears. So, to make b more universally applicable, the method I came up with is using the retention curve of the service's overall new users.
The assumption here is that a new feature will ultimately be used by newly onboarded users, and if the shape of the retention curve represents user characteristics, then those characteristics shouldn't drastically change within the same service.
As shown in the example code, you can use Python's scipy curve_fit to predict the b value using monthly Day 1 to Day 28 retention, and then take the average.
import pandas as pd
import numpy as np
from scipy.optimize import curve_fit
def func(x, a, b):
return a * (x**b)
df = client.query(query).to_dataframe()
date_list = ["'2025-07-01'", "'2025-08-01'", "'2025-09-01'", "'2025-10-01'", "'2025-11-01'", "'2025-12-01'"]
df_constant = pd.DataFrame([], columns=['basis_month', 'platform', 'a', 'b'])
platforms = ['ios', 'android']
for platform in platforms:
avg_retention= df[df.platform == platform].avg_retention.values
basis_month = df[df.platform == platform].basis_month.values[0]
days = np.arange(1, 29)
popt, pcov = curve_fit(func, days, avg_retention)
retention_days = np.arange(1, 364)
retention_rate = np.concatenate((np.array([1.0]), func(retention_days, *popt)))
print(*popt)
new_row_const = pd.DataFrame([[basis_month, platform, popt[0], popt[1]]], columns=['basis_month', 'platform', 'a', 'b'])
df_constant = pd.concat([df_constant, new_row_const], ignore_index=True)
print("Total b Mean: ", np.mean(df_constant['b']))
print("Total Android b Mean: ", np.mean(df_constant[df_constant.platform == 'ios']['b']))
print("Total iOS b Mean: ", np.mean(df_constant[df_constant.platform == 'android']['b']))Finally, to calculate (1^b + 2^b + 3^b + … + N^b) , we can assume a 1-year period and find the cumulative sum of x^b:
baseline = np.array([x**b_mean for x in range(1, 365)])
print(b_mean, ': ', np.sum(baseline))This brings us to one simple equation. In Alarmy's case, plugging in the average b caused the value to converge to around 63.
The Final Formula
New Feature DAU = New Users * New D1 Retention * 63
Quiz Answers!
Using the formula above, I was able to verify that the predicted DAU and actual DAU for Features A and B were much closer than what the traditional CC method yielded.
Of course, this formula also relies on several assumptions, so it can't predict exact figures. But with a little extra effort, you can easily gauge whether a newly launched feature in your service will hit 10k, 50k, or 100k DAU. I think it makes it much easier to judge which lever you need to pull from the current metrics—and by how much—to achieve your desired DAU.
Also, by utilizing more immediate metrics like new user counts and D1 retention, you can run multiple iterations within a relatively short timeframe.
Summary of Tips
A few tips I picked up while applying this method to a live service:
> Using numbers when metrics have stabilized improves accuracy.
For new features, early metrics tend to fluctuate a lot due to the initial launch effect or rollout rates. Using metrics that have entered a stable zone increased accuracy.
> For older features, the accumulated existing user base makes it hard to reflect reality using only new users & retention.
Add an existing user coefficient to account for the users you've already accumulated.
DAU = New Users * New D1 Retention * Existing Coefficient + Existing User Coefficient
It can't be 100% accurate, but...
If the baseline assumptions are violated, this method will also produce inaccurate predictions. Still, it was highly enjoyable to arrive at a process where a bit of effort and abstraction lets us easily diagnose the product. I look forward to hearing the insightful opinions of those who have read this far! :)