Honest Analytics counts your traffic and shows it in the WordPress admin. Nothing is sent anywhere, and nothing is stored that could identify a visitor later.
Click around a live dashboard with a year of seeded traffic before you install anything – one-click sign-in, no account needed: demo.honest-analytics.com.
?token=… never reaches disk.A visitor is a short hash of a random daily salt, the address, the user agent and the site. The salt is overwritten in place every 24 hours, so yesterday’s hashes cannot be recomputed by anybody – including somebody holding your database.
Uniqueness is estimated from a fixed-size sketch stored on the rollup row, accurate to about ±1.6%. It holds no identifiers and cannot be asked whether it contains a particular person.
This is why unique visitors are daily estimates, not people, and why the plugin says so on every screen that shows the number. The same person visiting on three days counts three times. There is no honest way to produce a cross-day or lifetime unique-visitor figure from this model, so the plugin does not offer one.
The server counts the requests it sees. A 1.9 KB first-party script confirms the rest from the browser. A nonce reconciles the two – consumed once per visitor, not once per nonce – so one piece of cached HTML served to a thousand people counts a thousand times.
No cache exclusions. No hole punching. No cache-plugin add-on. Tested with WP Rocket, W3 Total Cache, LiteSpeed, WP Super Cache, Cache Enabler, SG Optimizer, NitroPack and Cloudflare.
A request carrying Sec-GPC: 1 is not counted, not queued, and is sent no tracker at all. On by default. Do Not Track is supported the same way, off by default.
Storage grows with dimensions × time, not pageviews × time. A site with a hundred thousand views a day uses roughly the same disk as one with a hundred. Hourly detail is kept for a week, then compacted to daily; everything is deleted at 36 months at the latest.
There are no artificial limits. No row caps, no retention caps, no date-range caps, no nag screens and no countdowns. The free edition is a product, not a trial.
Campaigns, locations, events, goals, funnels, crawler reporting, client-shareable report links, Search Console query data, scheduled email summaries, and integrations with Contact Form 7, Gravity Forms, WooCommerce, WPForms and Ninja Forms. Details are at the plugin’s homepage. It is a one-off payment with no subscription, and it reads the same tables this edition writes – upgrading moves no data and loses no history.
None of it is in this plugin. The paid edition is a separate download, and the code for those reports is removed when this one is packaged rather than switched off – so there is no key to enter here, nothing to unlock, and nothing that stops working.
This plugin is cookieless by default and is designed not to require an analytics consent banner in its default configuration. Whether that is true of your site depends on your site, your jurisdiction and what else you run, and this plugin cannot tell you that – nobody’s plugin can. What it can do is tell you exactly what it stores, which the Privacy screen does, in plain words, so that the person advising you has something factual to work from.
The free edition’s full source and every release are on GitHub: github.com/Coysh-Digital/wp-honest-analytics.
This plugin makes no outbound request in the course of measuring your traffic. Nothing about your site or your visitors is sent to us or to anybody else, and there is no telemetry, licence check or update check in the free edition.
One feature contacts somewhere else, and one more answers a request from somewhere else. Both are optional, both are started by an administrator, and neither runs unless you use it.
If you choose to bring your history over from Google Analytics, the plugin talks to Google on your behalf, using a Google Cloud client that belongs to you and credentials you enter yourself. Nothing happens until you connect an account on the Import screen, and disconnecting revokes the token.
What it contacts:
accounts.google.com – to send you to Google’s own sign-in screen so you can grant access.oauth2.googleapis.com – to exchange that grant for an access token, and to revoke it when you disconnect.analyticsadmin.googleapis.com – to list the Analytics properties your account can see, so you can pick one.analyticsdata.googleapis.com – to read the historical figures for the property and date range you choose.What is sent: your own OAuth credentials, the property identifier you picked, and the date range and metrics being requested. No data about your WordPress site, its visitors or its content is sent. The access is read-only – the plugin asks for the analytics.readonly scope and nothing more.
This is Google’s service, governed by Google’s terms and privacy policy, not ours: terms, privacy policy. The API is documented at Google Analytics Data API.
The plugin can let an external reporting tool read this site’s figures. It is off until an administrator pastes a connection code into Analytics -> Reporting API, and clearing that code switches it off again.
This one runs the other way round from the one above: the plugin makes no request, it answers one. A tool holding the code can ask for the same aggregate figures the dashboard already shows – pageviews, sessions, bounce rate, top pages, sources, devices – for a date range it names. Requests are signed with the code rather than carrying it, are refused if the signature is older than a few minutes or is replayed, and are read-only. There is no visitor-level data in the reply because there is none in the tables.
Which tool that is, and whose terms govern it, is your choice: the plugin has no service of its own at the other end and no address built into it. Nothing is sent anywhere until you save a code.
Once a day the plugin asks your own site two questions: whether the collection endpoint still answers, and whether the write spool is readable over the web. Those are HTTP requests, so they show up in a search for wp_remote_get, but they go to your own address and nowhere else. They exist because neither fact can be settled any other way – a security plugin can disable the REST API without saying so, and the rule written at activation does nothing on nginx.