Free Chrome Extension Analytics: What $0 Actually Buys You
6 min readModerok team
What free Chrome extension analytics really gets you, from the Web Store dashboard's limits to the event math that decides whether a free tier fits.
Free Chrome extension analytics comes in three shapes, free in different ways. The Chrome Web Store dashboard you already have counts installations rather than usage. A hosted free tier is free up to an event ceiling. Self-hosting has no license fee but costs servers and time. Before comparing them on price, two questions decide it: can the SDK run inside a Manifest V3 service worker at all, and how many events does your extension generate per month? The second decides whether a free tier fits, and is the easiest to skip.
TL;DR: Your Web Store dashboard is already free and shows installs, uninstalls, impressions and weekly retention, but Chrome's own docs say the Users stats "only captures installations; it doesn't monitor whether users are active or not." Anything past that needs an event you send yourself. To price a free tier, multiply daily actives by 30 by your events-per-user-per-day plus one for the daily ping, then check which term dominates: your own
track()calls, the daily ping, or your release cadence. Check the history window too, since 30 days cannot answer a day-30 retention question.
The three kinds of free Chrome extension analytics
| Route | What is free | What you pay instead |
|---|---|---|
| Web Store dashboard | Everything, as part of your developer account. | Installation counts, not behaviour: no daily actives, no feature usage, no cohorts. |
| A hosted free tier | Ingestion and dashboards up to a monthly event ceiling, plus whatever history it includes. | Headroom. The ceiling means nothing until you know your event rate. |
| Self-hosting | The software license. | A server, a schema, uptime, backups, a retention policy, and the hours. |
What the free Web Store dashboard already gives you
Before paying anyone, read what you already have. Chrome's store listing metrics documentation describes reports for installs and uninstalls, impressions and users. Installs and uninstalls get breakouts by country, language and operating system, weekly user retention is "categorized by country, language, operating system, and item version", and it confirms "You can also export all the reports described below as CSV files."
That is a real free analytics product, and for acquisition questions often enough. The limit is on the same page: the Users stats "only captures installations; it doesn't monitor whether users are active or not." It tells you how many profiles have your extension, but not who opened it yesterday or which features they touched. We covered why those numbers disagree in Chrome Web Store weekly users vs installs.
Three things no store dashboard gives you, because Chrome does not instrument your extension's internals: whether an install is in use today, which features anyone opened, and what threw in the service worker last night. Each needs an event your own code sends, which is where a free tier comes in.
Free is irrelevant if the SDK cannot run in a service worker
A price of $0 does not help if the library never starts. An MV3 service worker is not a web page, and Chrome's service worker documentation is explicit: "Like its web counterpart, an extension service worker cannot access the DOM, though you can use it if needed with offscreen documents." Any snippet reaching for window or document throws on the first line.
The second filter is Chrome's remote code rule. The extension security guidance says all of your extension's logic must be part of the package: "You can no longer load and execute remotely hosted files according to Chrome Web Store policy." A free tier whose documented install is a CDN script tag is not one you can ship, whatever it costs.
Filter on those two before pricing, and check the manifest cost while you are there: for anonymous analytics the honest answer is storage and nothing else, which we broke down in what permissions Chrome extension analytics needs.
The event math that decides whether a free tier fits
Event ceilings are quoted per month, so translate one into your own extension before trusting it. That is just arithmetic:
monthly events ≈ (DAU × 30 × (1 + C)) // daily ping + custom events
+ (new installs × 2) // install + first open
+ (installed × releases) // one update event each, per release
C is the custom events you send per active user per day, and installed is your install base, always larger than DAU. As a worked example with invented inputs, take 6,000 installed profiles of which 2,000 are active daily, 200 new installs that month, one release, and five track() calls per active user per day:
- Daily ping: 2,000 × 30 = 60,000 at most
- Custom events: 2,000 × 5 × 30 = 300,000
- Installs and first opens: 200 × 2 = 400 at most
- Update events: 6,000 × 1 = 6,000
- Total: around 366,400 events, before errors
Two lines are ceilings, not counts: __daily_ping fires at most once per UTC day per profile, and a reinstall that recovers its profile id through browser sync emits no __first_open, so those terms land at or below the figures shown. __error is automatic too and is deliberately missing, because it is the one term you cannot forecast. The shape matters more than the number. Your own track() calls are 300,000 of 366,400, about 82%; the daily ping 60,000, about 16%; and the per-install events (install, update, first open) just 6,400, under 2%. At five track() calls per active user per day the lever is your own events, not the automatic ones. That flips with the inputs: below one custom event per active user per day the ping is the bigger line, and a fast release cadence makes the update term bigger still.
Run it backwards to size a ceiling: for a monthly budget B and D daily actives, the per-user allowance is B / (30 × D) - 1. At a 1,000,000 ceiling and 2,000 daily actives that is just under 16 custom events per active user per day: plenty for a deliberately instrumented extension, nothing for one firing an event per scroll.
One budget line worth checking is errors, since a crash loop is an unbounded source. Moderok caps error capture at 20 events per 60 second window and drops repeats of an identical fingerprint inside it (RATE_LIMIT_MAX_EVENTS, RATE_LIMIT_WINDOW_MS and DEDUPE_WINDOW_MS in src/errors.ts). That counter lives in memory in one service worker instance, so it bounds a burst inside a single wake rather than the month: a restarted worker gets a full allowance again. Ask any tool what its cap is.
Check the retention window, not just the ceiling
The second limit is history length, so check it rather than assuming. A tier keeping only 30 days of data could not answer a day-30 retention question: that cohort needs the install date plus 30 full days after it, so 31 days before the first cohort closes, and more before you can compare two. Seasonality goes the same way: you cannot tell whether October beat September once September is deleted. A short window is a fair trade for $0 if you know which questions it removes.
Four more things to establish from the docs rather than assume:
- What happens at the ceiling. Dropped events, blocked ingestion and a bill are very different.
- Who supplies the identifier. A tool expecting a logged-in user id leaves you inventing one for an extension with no accounts.
- Whether lifecycle events are automatic. Installs, updates and uninstalls are either instrumented for you or they are code you write.
- Whether anything beyond volume is gated. Seats, projects and export can be tiered separately.
Where Moderok sits
Moderok's free plan is $0 for 1,000,000 events a month, and every plan, free included, gets the same Trends, Events and Logs views and two years of history. Install, update, first open, daily ping and error events are sent without you calling track(), the full list being in the automatic events docs. The SDK is 5.7 kB gzipped with zero runtime dependencies, needs only storage, and touches no DOM globals, so it clears both MV3 filters by construction. Setup is three parts: install @moderok/sdk, add the permission, and call Moderok.init(), per the getting started guide.
To see what the reports look like first, take the product tour, then run the arithmetic above against your own daily actives. A free tier is only generous relative to a number you have calculated.