Each of the 900 simulated users carries a fixed daily activation propensity pi, drawn from a two-component mixture so a slider controls the split between casual and power users:
p_i = 0.04 + 0.06·U (casual, prob = 1 - mix)
p_i = 0.35 + 0.55·U (power user, prob = mix)
U ~ Uniform(0,1)
Every simulated day, each still-active user fires a Bernoulli trial with probability pi plus the push-notification boost (applied only to users who were inactive yesterday, modelling a re-engagement nudge). A separate Bernoulli trial with the churn probability permanently removes a user from the pool; a same-sized cohort of fresh users (drawn from the same mixture) is acquired each day to keep the population size constant — this is what lets MAU shrink even while acquisition continues, exactly as in a real leaky-bucket retention model.
DAU(t) = |{ i : active on day t }|
MAU(t) = |{ i : active at least once in days [t-29, t] }|
Stickiness(t) = DAU(t) / MAU(t)
- Power-user mix — shifts the population toward habitual daily users, raising both DAU and stickiness.
- Daily churn probability — the fraction of the pool permanently lost each day; higher churn drags MAU down toward DAU, which paradoxically pushes the stickiness ratio up even as the app is dying.
- Push-notification boost — a flat probability added only for users who skipped yesterday, the classic re-engagement lever; it raises DAU without changing the underlying MAU pool, so stickiness rises.
- Cohort still active — tracks the original 900 day-0 users specifically (ignoring replacements), a simple retention curve for that single cohort.
Real-world relevance: DAU/MAU stickiness is the standard mobile-analytics KPI product teams watch after every release or campaign — this model shows why it must always be read next to churn and acquisition, since the ratio alone cannot distinguish a healthy habit-forming app from a shrinking one.