We publish an Instagram growth statistics page built from our own customer data: 164,963 daily follower-count readings from 7,271 Instagram accounts. The headline result is a median gain of +346 followers in the first 30 days across 981 accounts, with 86% of them growing. Below are the five cleaning rules that produced that number, why each one exists, and a SQL sketch of the core query.
1. Measure at "the reading closest to day N", within a window
Daily readings are not perfectly daily. A job fails, an account is private for a day, a request times out. So the gain at day 30 is the reading closest to day 30, as long as it falls within 3 days of it, minus the first reading. Same rule for day 60 and day 90.
Without a window you either lose most accounts (an exact day-30 reading is often missing) or you silently mix day-24 and day-37 readings into one "30-day" number.
2. Only count accounts that are still being measured on that day
An account counts toward the day-30 figure only if it still has a reading on day 30. That is why the sample shrinks over time: 981 accounts at day 30, 577 at day 60, 417 at day 90.
This is a survivor-only number, and the page says so: each figure describes accounts that were still running on that day. Mixing survivors and drop-outs into one denominator would look tidier and mean less.
3. Use medians, not means
A handful of very large accounts would dominate an average. The median of +346 sits next to an interquartile range of +73 to +549 on the page, which tells you more about the spread than a mean ever would. Accounts over 100,000 followers were left out of the size breakdown entirely: too few were measured and their results varied too widely for a reliable median.
4. Drop impossible jumps
394 accounts were excluded because the follower count jumped above 5x or fell below one fifth of the starting count. In practice that is almost always a changed username (the tracker starts reading a different account) or a failed reading that returned a wrong number. A single rule catches both without hand-labelling anything.
5. Cut off data you cannot trust yet
Accounts that started from June 2026 on are not included yet. Too many of their daily readings repeat the previous day's count exactly, which we treat as a stale reading rather than zero growth. Publishing those months would have pulled the median down for a measurement reason, not a growth reason. They will be added once those months can be measured properly.
A SQL sketch of the day-30 query
This is a simplified sketch of the approach in Postgres, not production code. readings holds one row per account per reading.
with first_reading as ( select distinct on (account_id) account_id, read_on as start_day, followers as start_followers from readings order by account_id, read_on ), day30 as ( select distinct on (r.account_id) r.account_id, r.followers from readings r join first_reading f using (account_id) where r.read_on between f.start_day + 27 and f.start_day + 33 -- within 3 days of day 30 order by r.account_id, abs((r.read_on - f.start_day) - 30) -- closest reading wins ), gains as ( select d.account_id, d.followers - f.start_followers as gain, d.followers::numeric / nullif(f.start_followers, 0) as ratio from day30 d join first_reading f using (account_id) ) select count(*) as accounts, percentile_cont(0.5) within group (order by gain) as median_gain, avg((gain > 0)::int) as share_grew from gains where ratio between 0.2 and 5; -- drop impossible jumps (the real filter checks every reading) What the cleaned data showed
- Median gain: +346 at day 30, +483 at day 60, +533 at day 90.
- Growth is front-loaded: the typical account that grew over 90 days had made 62% of that gain by day 30 (264 accounts).
- Starting size changes the percentage far more than the raw number: +341 (+69.4%) for accounts under 1,000 followers, +359 (+12.5%) for 1,000 to 9,999, and +288 (+1.0%) for 10,000 to 99,999.
These are results for one service's customers, not a promise for any single account. The full tables, by starting size and by niche, are on the statistics page.
If you measure growth curves from noisy daily snapshots, the two rules that changed our numbers most were the jump filter and the stale-reading cutoff. Both are cheap to add and easy to explain.
