Analytics Installed But Showing Zero Users? Here Are 7 Reasons Why
You deployed the SDK, you're live, and the dashboard is empty. Before you tear out the installation and start over, check these seven things first.

You spent time picking the right analytics tool, reading the docs, wiring up the SDK, deploying to production. And now you're staring at a dashboard that says zero users, zero events, nothing. The counter hasn't moved. The charts are flat. The install looks right on your end, but the data isn't there.
This is one of the most demoralising places to be as a founder or developer. You did the work. The reward should be data. Instead you have silence.
Here is the thing: analytics showing 0 users after install is almost never a sign that the tool is broken or that you fundamentally got it wrong. It is almost always one of a small number of specific, fixable problems, and most of them take under ten minutes to diagnose once you know where to look. I have been through this exact process too many times across too many stacks, and I want to save you the two hours of staring at documentation.
We are going to go through seven reasons your analytics installed zero users situation is happening, in roughly the order you should check them. But first, one quick diagnostic step that cuts the list in half before you even get to the reasons.
Before You Check Anything: Open DevTools First
Before you read any of the seven reasons below, do this: open your site in Chrome or Firefox, press F12 to open DevTools, and look at the Console tab. If your analytics SDK is failing to load, failing to initialize, or being blocked by a Content Security Policy, there will be an error message right there. Red text. It will name the file, the URL that was blocked, or the property that came back undefined. That error message is your diagnosis already.
If the console is clean, switch to the Network tab. Filter the requests for your analytics domain (type "analytics" or "segment" or "gtm" or whatever your tool uses in the filter box). Load a page. Navigate around. You should see requests firing. If you see requests with status 200, your events are reaching the server and you just need to figure out why the dashboard isn't reflecting them yet. If you see no requests at all, the SDK is not executing, and the reasons below will tell you why.
Do this diagnostic step first. It will usually point you directly to the reason, and you can skip the rest. If the console and network tab both look clean and requests are firing normally, the most likely culprit is reason one: a processing delay.
Analytics showing 0 users is almost always one of a small number of specific, fixable problems. Most take under ten minutes to diagnose once you know where to look.
The 7 Reasons Your Analytics Is Showing Zero Users
This is the most common reason for analytics installed zero users situations, and it is also the one people check last because it feels too simple. Standard reports in GA4, Mixpanel, and most major analytics platforms do not update in real time. GA4's standard reports can take 24 to 48 hours to reflect data that has already been received. Mixpanel is generally faster but can lag by hours on cold starts, especially for a brand-new project that hasn't received any events before.
The reason this catches people is that the installation looks identical whether events are flowing correctly or not. You set everything up, you visit your site, and you check the Users report the same day. It says zero. So you assume something is broken, and you start pulling the install apart to find the problem. Meanwhile the data is sitting in a queue, perfectly fine, waiting to be processed.
Most analytics tools with real-time reporting have a Realtime report or a Live view that updates within seconds, not hours. This is specifically designed to let you verify that your installation is working before the standard reports catch up. If you see yourself appear in the Realtime report when you visit your site in another tab, the installation is working correctly and you just need to wait.
uBlock Origin, Brave Shields, Firefox Enhanced Tracking Protection, and Safari Intelligent Tracking Prevention all block major analytics scripts by default. This is not an edge case. Developer and technical audiences, which tend to be exactly who shows up first for a new product, run ad blocker penetration rates of 30 to 50 percent in some studies. If your early adopters are mostly developers or technically sophisticated founders, you could be installing analytics correctly and still missing half your traffic from day one.
The maddening part is that there is no error in your DevTools console when an ad blocker blocks a script via its own rules (as opposed to a CSP block, which does log an error). The script just never loads. No requests appear in the Network tab. No users appear in analytics. It looks identical to a broken installation because, from the browser's perspective, the script never ran.
You cannot fix this from inside your analytics tool. Ad blockers operate at the browser level, and their block lists are maintained independently of what any analytics company does. The structural solutions are server-side event tracking (your server sends events to the analytics platform, not the browser), or a first-party proxy where analytics requests go to your own domain before being forwarded on, so the browser doesn't recognize them as a third-party analytics request. Both require meaningful engineering work.
Single-page applications built with React, Next.js, Vue, Nuxt, or SvelteKit do not reload the page when a user navigates between routes. The user clicks a link, the URL changes, the component updates, but there is no full browser page load. Most analytics tools trigger their pageview event by listening to the browser's page load event, which fires once, on the initial load, and then never again for the rest of the session.
The result is that your analytics sees every user as having visited exactly one page. They land on your homepage, analytics fires one event, and then every subsequent click through your app is invisible. If you are on a plan or viewing a report that counts "active users" based on event count, one event per user with no follow-up activity can sometimes look like zero meaningful engagement, or in some configurations, zero tracked users at all.
This is actually a very common source of the analytics showing 0 users problem, because developers install analytics on a new project, click around the app from their own browser (where they probably also have an ad blocker), and the only session that shows up has one pageview and immediately bounced, which gets filtered out in some default views. The analytics installed zero users diagnosis often ends here once you add router event listeners.
useEffect that fires on location.pathname changes. In Next.js (Pages Router): router.events.on('routeChangeComplete', handleRouteChange). In Next.js App Router: use a layout component with usePathname(). In Nuxt: the page:finish hook. In SvelteKit: subscribe to $page.url. Your analytics SDK almost certainly has framework-specific docs for exactly this pattern — search "[tool name] + [framework name] + SPA pageview" and you will find them.A Content Security Policy (CSP) is a set of HTTP headers your server sends to the browser, telling it which domains are allowed to load scripts, make fetch requests, set cookies, and so on. CSP headers are a legitimate security feature, and if you are using a strict CSP (which you should be), any script not explicitly allowlisted gets silently blocked by the browser before it ever runs.
The word "silently" is the key: a CSP block does not produce a failed network request in the way that a 404 does. The script never loads at all. From your analytics platform's perspective, you simply don't exist. From your browser's perspective, the script was prevented from running. This is exactly what you want from a security standpoint, but it means analytics is dead if you forgot to update your CSP when you added the SDK.
Unlike ad blocker blocks, CSP violations do produce a visible error in the browser console, and this is one reason the DevTools console check at the top of this article is so valuable. The error will read something like "Refused to load the script 'https://cdn.analytics-provider.com/sdk.js' because it violates the following Content Security Policy directive: script-src 'self'." That error message tells you the exact domain you need to allowlist.
script-src and connect-src directives in your CSP header. For GA4, allowlist www.googletagmanager.com and www.google-analytics.com. For Segment: cdn.segment.com and api.segment.io. Check your analytics provider's security docs for the complete list of domains to allowlist.Most analytics SDKs are designed to fail gracefully, which sounds like a good thing until you realize what "fail gracefully" means in practice: they swallow errors, continue executing without throwing, and do not tell you that initialization failed. You call analytics.init('wrong-api-key-here'), the SDK accepts the call without complaint, and then every subsequent analytics.track() call fires into a void. No console errors. No network requests. No data.
The most common causes are a mismatched API key (you copied the key from the wrong project, or you copied the test key instead of the production key), options passed in the wrong order or with a wrong property name (the SDK ignores unknown options silently), or track() and identify() calls being made before init() has finished executing, which can happen in async component trees where execution order isn't guaranteed.
This one looks exactly like an ad blocker: complete silence, no network requests, no errors in console, no data in analytics. The difference is that it affects all browsers equally, including clean profiles with no extensions. If your fresh-browser test from reason 2 also shows zero users, and the console is clean, initialization is a strong candidate.
console.log right after your analytics.init() call to confirm it runs. Then open DevTools → Network and filter for your analytics domain. Load the page. If you see zero requests, initialization failed silently. Double-check your API key or write key against what your analytics dashboard shows under Project Settings. Make sure init() is called before any track() or identify() calls, and that it has finished resolving if it is async.If your application uses SSR through Next.js, Nuxt, Remix, SvelteKit, or any other framework that executes JavaScript on the server, there is a class of bug that trips up even experienced developers: analytics code that runs during server rendering tries to access browser APIs (window, document, navigator) that don't exist in a Node.js environment. The result is either a thrown error that breaks your build, or more commonly, a silent failure where the SDK initializes as a no-op on the server and never actually tracks anything.
This is especially sneaky when you import the analytics library at the top of a file that gets server-rendered. The import succeeds, the SDK loads its module, but when it tries to set up its internal state (which typically involves reading from window.localStorage or accessing document.cookie), it fails silently because those APIs return undefined on the server. Every event call after that point is a no-op.
The tell is that your SSR logs on the server look fine, but the browser never sends analytics requests. A console log inside analytics.init() prints on the server but not in the browser, because the init call is in server-side code, not client-side code.
useEffect hooks, which only run in the browser. In Vue/Nuxt: use onMounted. In any SSR framework: wrap analytics calls behind if (typeof window !== 'undefined'). In Next.js App Router: mark your analytics provider component with 'use client' at the top. The analytics SDK should only initialize once, on the client, after the page has mounted.Development, staging, and production environments almost always have separate analytics projects, because you don't want your own testing activity polluting your production metrics. That means your codebase has at least two analytics API keys or project IDs: one for the dev/staging environment and one for production. The analytics installed zero users problem often turns out to be this: your production deployment is still using the dev key, so real user traffic is going into a dev project you never open.
This happens easily. You set up the SDK during local development, hardcode the dev key to get it working, then deploy to production and forget to update the environment variable. Or you copy a .env.example file that has placeholder values, and one of those placeholders is the analytics key from your dev project. The production app runs, events fire, everything looks fine in DevTools, but the data lands in the wrong bucket.
A related variant is having analytics pointing to the right project but the wrong data view or workspace within a project. Mixpanel has projects inside organisations. Segment has sources and destinations. It is worth confirming the full chain from "where the SDK sends events" to "where you are looking in the dashboard" is actually connected end-to-end, not just partially.
If You're Rebuilding Your Analytics Stack Anyway
If you went through all seven of these and you're now questioning whether you picked the right analytics tool to begin with, that's a reasonable place to land. Most of the issues above exist because traditional client-side analytics tools have a lot of surface area for things to go wrong: CSP headers, ad blockers, SPA routing, SSR hydration, environment variables. Every one of those is a place where the data can silently stop flowing and you won't know until you go hunting for it.
Adtivity is built for founders running subscription products, and one of the design choices we made is to keep the debug path short. The install is an SDK plus an MCP auto-install, so you get it wired up once and both your dashboard and your AI tools (Claude, Cursor) can see your data. The MRR dashboard connects directly to Stripe and Paystack, so your revenue metrics don't depend on client-side event tracking at all. Pulse Alerts tell you when something changes before you have to go check.
And if something does look wrong, the EI (Execution Intelligence) path shortens the debugging loop considerably: instead of opening four browser tabs and reading documentation, you just ask from Claude: "why does my MRR look wrong this week?" and EI queries your actual data to tell you. That's a different class of debugging experience than staring at an empty dashboard wondering which of seven things went wrong.
There is a free tier if you want to see how it works for your product specifically. The point isn't that Adtivity replaces every analytics use case — it's that if you're a founder building a subscription product and you're already frustrated with analytics not showing up, the simpler path is worth trying.
Frequently Asked Questions
The most common causes, in order: a 24-48 hour reporting delay in standard reports, an ad blocker preventing the script from firing, SPA routing not triggering analytics events after the initial load, a wrong API key causing silent failures, or a Content Security Policy header blocking the script. Check browser DevTools → Console for errors first, then the Realtime report to confirm events are reaching your analytics platform.
Open your site in a fresh browser with no extensions. Open DevTools → Network tab and filter for requests to your analytics domain. Navigate around the site. You should see network requests firing on each page or action. Then check your analytics platform's Realtime or Live view: if you appear there within 30 seconds, the installation is working and you're just waiting on standard report processing.
Most major client-side analytics scripts are blocked by uBlock Origin, Brave, Firefox ETP, and Safari ITP. There's no fix within the analytics tool itself. The only reliable solutions are server-side event tracking, a first-party proxy that routes analytics requests through your own domain, or accepting that a portion of your technical audience will never be tracked.
Next.js uses client-side navigation: when a user clicks a link, the page doesn't reload. Most analytics tools only fire a pageview on initial page load, so they see one event per session regardless of how many pages the user visits. Fix: listen to Next.js router events with router.events.on('routeChangeComplete') and call your analytics pageview function on each route change.
Tools that show you real-time event ingestion make debugging much faster than tools where you wait 24 hours to see if an event arrived. PostHog has a live event stream. Mixpanel has event verification. Adtivity shows live event ingestion and, via EI, lets you ask questions about your data directly from Claude or Cursor — which shortens the "why is this number wrong" debugging loop significantly.
Try Adtivity
See your product metrics in minutes.
No developer needed. Connect your app, get your dashboard, and understand your users from day one.
Sign up free →Land in your inbox.
We publish across the week and ship the highlights to Substack. Subscribe and the next piece lands the day it goes live.
GA4 Not Showing Data? Here's Why (And What to Do)
The 9 most common reasons GA4 goes dark — and the exact fixes.
Read nextProductsBest Mixpanel Alternatives for Founders in 2026
Mixpanel is built for product teams with analysts. If you're a founder doing all of this yourself, these are the tools actually made for your situation.
Read nextIdeologyWhat is brand ethos, and where does it live?
Walk into an Apple store with your eyes half-closed and you will still know which store you are in.