Product Manager Interviews Module 4 – Estimation and product strategy
Usage, revenue and capacity estimates
Estimate usage and its peak, the people in a service at once with Little's law, storage and yearly revenue, and check revenue against a public filing.
What you will learn
- Estimate daily usage and peak load from a user base and its usage pattern
- Estimate revenue from users, the share who pay and revenue per paying user
- Use Little's law to estimate how many people use a service at once
Before you start
What you’ll learn · Before you start
What you will learn
- Estimate daily usage and peak load from a user base and its usage pattern
- Estimate revenue from users, the share who pay and revenue per paying user
- Use Little's law to estimate how many people use a service at once
Before you start
On this page
An expense app’s users upload 1,000,000 receipts a day. Is that 11.6 uploads a second or 34.7? Both: the first is the day’s average and the second its busiest hour, and only the second says what the app must handle when people use it most.
Below, you estimate usage and its peak for that invented app, see why the peak decides how long uploads wait, count the people in the app at once with Little’s law, and estimate its yearly revenue with a check against a public filing.
Usage times a peak factor gives the load to plan for
Usage estimates start from people and what they do: 250,000 daily users who upload 4 receipts each make 1,000,000 uploads a day, an average of 11.6 a second. People do not spread their uploads evenly over 86,400 seconds, so the average is multiplied by a peak factor: How many times the busiest period's rate exceeds the average rate, such as a busiest hour at 3 times the day's average. It is an assumption, so it is stated and then checked against the pattern of real use., an assumption you state and check. At 3, the busiest hour runs at 34.7 a second. Google’s SRE book makes the same point about averages: a system that serves 200 requests a second in even-numbered seconds and none in the others averages 100, while its load in those seconds is twice that (SRE book, chapter 4). The program works out every estimate of this lesson for the app:
"""Usage, peak load, people at once, a year of storage and a year of revenue for an invented expense app.
Every input is an assumption about the invented app, written down so that it can be argued with. Money is in US
dollars; in any other currency the arithmetic is the same. Storage uses decimal units: 1 GB = 1,000,000 KB.
"""
SECONDS_A_DAY = 24 * 60 * 60
# Usage: who uploads receipts, and how often.
DAILY_USERS = 250_000
RECEIPTS_EACH = 4 # receipts a daily user uploads on a day
PEAK_FACTOR = 3 # the busiest hour runs at three times the day's average rate (an assumption to check)
# People at once (Little's law): in the busiest hour, how many open the app and how long each stays.
OPENS_IN_BUSY_HOUR = 30_000
MINUTES_EACH = 4
# Storage: the size of one receipt photo after the app compresses it.
KB_A_RECEIPT = 250
# Revenue: who pays, and how much.
MONTHLY_USERS = 400_000
SHARE_WHO_PAY = 0.06
DOLLARS_A_MONTH = 5
uploads = DAILY_USERS * RECEIPTS_EACH
average = uploads / SECONDS_A_DAY
print(f"Uploads a day: {uploads:,}")
print(f"Average a second: {average:.1f}")
print(f"Peak a second: {average * PEAK_FACTOR:.1f}")
arrivals_a_minute = OPENS_IN_BUSY_HOUR / 60
print(f"People in the app at once, busy hour: {arrivals_a_minute * MINUTES_EACH:,.0f}")
gb_a_day = uploads * KB_A_RECEIPT / 1_000_000
print(f"Storage a day: {gb_a_day:,.0f} GB")
print(f"Storage a year: {gb_a_day * 365 / 1_000:,.2f} TB")
payers = MONTHLY_USERS * SHARE_WHO_PAY
print(f"Paying users: {payers:,.0f}")
print(f"Revenue a year: ${payers * DOLLARS_A_MONTH * 12:,.0f}") Output
Uploads a day: 1,000,000 Average a second: 11.6 Peak a second: 34.7 People in the app at once, busy hour: 2,000 Storage a day: 250 GB Storage a year: 91.25 TB Paying users: 24,000 Revenue a year: $1,440,000
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 peak_load.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
Storage follows usage too: at 250 KB a receipt, the uploads add 250 GB a day and 91.25 TB a year. Unlike the load, storage adds up: every receipt stays, so each year’s total comes on top of the last.
Capacity estimates show how close the peak runs to the limit
A product manager’s capacity estimates exist to judge whether a plan is feasible and what it costs, not to size the servers, which the system design track does in depth. One number decides most of it: how close the peak runs to what the service can finish. Say one upload server finishes 40 uploads a second. Set the arrivals to the peak, 35 a second, and then drag them towards the average of 12:
At 88 % utilisation a request spends 200 ms in the system on average, 8 times its 25 ms of service: the rest is waiting. Little's law: L = λW = 7 requests in the system.
The numbers as a table
| Utilisation | Mean time in the system |
|---|---|
| 50 % | 50 ms |
| 70 % | 83.3 ms |
| 80 % | 125 ms |
| 90 % | 250 ms |
| 95 % | 500 ms |
| 99 % | 2,500 ms |
At 35 a second an upload spends 200.0 ms in the service, eight times its 25 ms of work; at 12 a second, 35.7 ms. Past 40 a second, the queue grows without limit. The peak, not the average, decides whether the feature feels fast.
Checkpoint
Check: Usage and the peak factor · How close the peak runs to the limit
Little’s law counts the people in a service at once
Little's law: The average number of people or requests in a system equals the rate at which they arrive times the average time each one stays, L = λW: 500 arrivals a minute staying 4 minutes each means 2,000 in the system at once. links three averages: L, how many people are inside a system at once, is λ, how many arrive in a unit of time, multiplied by W, how long one of them stays: L = λW. John Little’s proof shows that it holds for a system in a steady state whatever the pattern of arrivals and of service (Little’s proof). Put the rate and the time in the same unit first, then multiply:
| Arrivals | Time each | People at once |
|---|---|---|
| 30,000 an hour, 500 a minute | 4 minutes | 2,000 |
| 3,000 an hour, 50 a minute | 6 minutes | 300 |
The first row is the expense app’s busiest hour, the number the program printed; the second is a shop whose orders each take 6 minutes to place.
Revenue: users, times the share who pay, times what each pays
Revenue estimates multiply the users by the share who pay and by what each payer brings in over the period. The expense app’s 400,000 monthly users, 6 % of whom pay $5 a month, give 24,000 payers and $1,440,000 a year. Check the share against a public filing where one exists, such as Duolingo’s shareholder letter for one quarter (Duolingo, SEC filing):
| Monthly users | Paying | Share who pay | |
|---|---|---|---|
| The expense app, assumed | 400,000 | 24,000 | 6 % |
| The filing, one quarter | 140.6 million | 12.7 million at its end | About 9 % |
The filing’s two counts are measured differently, so the ratio is a rough check, and it says that 6 % is plausible.
Checkpoint
Check: Little's law · Revenue from users who pay
Practise: people at once, then check yourself
Write the function that applies Little’s law, then run the sample tests:
Exercise · Easy · Python
Count the people in a service at once with Little's law
Little's law says that the average number of people in a system equals the rate at which they arrive times the average time each one stays. Write concurrent_users(arrivals_per_hour, minutes_each):
arrivals_per_houris how many people start using the service in an hour;minutes_eachis how long each of them stays, on average, in minutes;- it returns the average number of people in the service at once, as a number (a whole number when the inputs give one);
- it raises
ValueErrorwhen either input is negative.
Mind the units: the rate is per hour and the time is in minutes.
concurrent_users(3000, 6) # 300.0: 50 arrive a minute and each stays 6 minutes
concurrent_users(30000, 4) # 2000.0: the expense app's busiest hour
The sample tests also check a stay of half a minute, an hour with no arrivals, a negative rate and a negative time.
Starter code · concurrency.py
def concurrent_users(arrivals_per_hour, minutes_each):
"""Return the average number of people in a service at once (Little's law: L = arrival rate x time each).
arrivals_per_hour: people who start using the service in an hour
minutes_each: the average time each one stays, in minutes
Raises ValueError when either input is negative.
"""
# Your code here.
return 0 The sample tests · test_concurrency.py
from concurrency import concurrent_users
def test_orders_example():
"""3,000 an hour is 50 a minute; staying 6 minutes each, 300 are in at once"""
assert concurrent_users(3000, 6) == 300
def test_expense_app_busy_hour():
"""the lesson's expense app: 30,000 opens in the busiest hour, 4 minutes each"""
assert concurrent_users(30000, 4) == 2000
def test_half_a_minute():
"""720 an hour is 12 a minute; half a minute each leaves 6 in at once"""
assert abs(concurrent_users(720, 0.5) - 6) < 1e-9
def test_no_arrivals():
"""nobody arrives, nobody is in"""
assert concurrent_users(0, 10) == 0
def test_negative_input():
"""a negative rate or time is a mistake, not an estimate"""
try:
concurrent_users(-100, 5)
except ValueError:
pass
else:
assert False, "expected a ValueError for a negative rate"
try:
concurrent_users(100, -5)
except ValueError:
pass
else:
assert False, "expected a ValueError for a negative time" A hint
Put both inputs in the same unit before you multiply: divide the arrivals in an hour by 60 to get the arrivals in a minute, then multiply by the minutes each person stays. Check the signs of the inputs first.
Results of the sample tests
| Test | Result | Details |
|---|
What your code printed
The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.
The self-check that follows starts from the concept you have missed most and adapts as you answer.
Practice that adapts to you
Practise this lesson
8 questions about 6 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Three estimates worked with ranges and checks Pro: opens with a Pro, Premium or Ultimate pass
Three invented products, three kinds of estimate: a ticket sale’s first minute, a year of listing photos and a subscription’s yearly revenue. Each comes with low, base and high values from one program and a sanity check of its own.
In this part:
- A ticket sale’s first minute, worked from buyers and requests
- A year of listing photos, worked from listings and sizes
- A subscription’s yearly revenue, worked and checked against a filing
- Saying an estimate in the round, level by level
1 runnable example (Python) · about 5 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
What to ask engineering after the estimate Pro: opens with a Pro, Premium or Ultimate pass
An estimate earns its place when it changes a decision. This part turns each estimate into the questions a product manager takes to engineering, about limits, cost and risk, and shows how the queueing model reads those answers.
In this part:
- Questions about limits, cost and risk, estimate by estimate
- Reading an engineer’s answer with the queueing model, worked
- A failure drill: the average that hid the peak
- When the estimate says no
1 diagram · about 5 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
Interview questions
Work each of these aloud, with a range and a check, before you read its first step and follow-ups:
-
Fresher to senior
A shopping app expects ten times its normal orders in the first hour of a festival sale. Estimate the peak orders a second and say what you would ask engineering.
-
Fresher to mid
Estimate the storage a photo-sharing feature needs in its first year if 2 million users each upload a few photos a week.
-
Fresher to senior
Estimate the yearly revenue of a meditation app with 5 million monthly users. Which assumption matters most, and how would you check it?
Flashcards · 6 cards
Recall it, then check
Say the answer to yourself before you look: recalling it is what makes it stick.
-
Why multiply average usage by a peak factor?
Use is uneven through the day. A million uploads a day average 11.6 a second, but with a stated peak factor of 3 the busiest hour runs at 34.7 a second, and that is the load the service must carry.
-
How does storage differ from load in a usage estimate?
Load comes and goes, but storage builds up: at 250 KB a receipt, a million uploads add 250 GB a day and about 91 TB a year, on top of every earlier year.
-
Why does the peak, not the average, decide whether a feature feels fast?
Waiting climbs steeply near capacity. With a server that finishes 40 uploads a second, an upload spends 200 ms in the service at 35 a second, eight times its 25 ms of work, against about 36 ms at 12 a second; above 40 the queue grows without limit.
-
What does Little's law say, and how do you use it?
L = λW: the people in a system at once equal the arrival rate times how long each stays, for a system in a steady state. Put both in the same unit first: 500 arrivals a minute staying 4 minutes gives 2,000 people at once.
-
How do you estimate the yearly revenue of a subscription app?
Users × share who pay × what each payer brings in over the period: 400,000 monthly users with 6 % paying $5 a month give 24,000 payers and $1,440,000 a year. Check the paying share against a public filing where one exists.
-
What is a product manager's capacity estimate for?
To judge whether a plan is feasible and what it costs, by showing how close the peak runs to what the service can finish. Sizing the servers is engineering's depth.
Key takeaways
- Usage is users times actions; the load to plan for is the average times a stated peak factor, here 34.7 uploads a second against 11.6.
- Capacity estimates show how close the peak runs to the limit: at 35 of 40 a second an upload spent 200 ms, eight times its work.
- Little’s law counts the people in a service at once: 500 arrivals a minute staying 4 minutes is 2,000 people.
- Revenue is users times the share who pay times what each pays, checked against a public filing where one exists.
Terms in this lesson
- Little's law
- The average number of people or requests in a system equals the rate at which they arrive times the average time each one stays, L = λW: 500 arrivals a minute staying 4 minutes each means 2,000 in the system at once.
- peak factor
- How many times the busiest period's rate exceeds the average rate, such as a busiest hour at 3 times the day's average. It is an assumption, so it is stated and then checked against the pattern of real use.
References
- A Proof for the Queuing Formula: L = λW (Operations Research (John D. C. Little))
- Site Reliability Engineering, chapter 4: Service Level Objectives (Google (O'Reilly Media))
- Duolingo shareholder letter, second quarter (filed with the US SEC) (Duolingo, Inc. (SEC EDGAR))
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress