Counterscale is a simple web analytics tracker and dashboard that you self-host on Cloudflare.
It's designed to be easy to deploy and maintain, and should cost you near-zero to operate – even at high levels of traffic (Cloudflare's free tier could hypothetically support up to 100k hits/day).
NOTE: Counterscale is currently in very early development and shouldn't be used in any actual production setting. We welcome people trying it and giving feedback/contributing, but heads up this project is still super early.
If you don't have one already, create a Cloudflare account here.
Account.Account Analytics
permissions at a minimum (screenshot).npm install
npx wrangler pages project create counterscale
and create a new Pages project.
wrangler
on the terminal, you will be prompted to sign into your Cloudflare account.npx wrangler pages secret put CF_BEARER_TOKEN
→ when prompted, paste the API token you creatednpx wrangler pages secret put CF_ACCOUNT_ID
→ when prompted, paste your Cloudflare Account ID
npm run deploy
– this will do several things:
counterscale
)main
)metricsDataset
https://{subdomain-emitted-from-npm-run-deploy}.pages.dev
.
If the website is not immediately available (e.g. "Secure Connection Failed"), it could be because Cloudflare has not yet activated your subdomain (yoursubdomain.workers.dev). This process can take a minute; you can check in on the progress by visiting the newly created worker in your Cloudflare dashboard (Workers & Pages → counterscale).
The deployment URL can always be changed to go behind a custom domain you own. More here.
When Counterscale is deployed, it makes tracker.js
available at the URL you deployed to:
https://{subdomain-emitted-from-npm-run-deploy}.pages.dev/tracker.js
To start tracking website traffic on your web property, copy/paste the following snippet into your website HTML:
<script>
(function () {
window.counterscale = {
q: [["set", "siteId", "your-unique-site-id"], ["trackPageview"]],
};
})();
</script>
<script
id="counterscale-script"
src="https://{subdomain-emitted-from-npm-run-deploy}.pages.dev/tracker.js"
defer
></script>
Be sure to replace your-unique-site-id
with a unique string/slug representing your web property. Use a unique site ID for each property you place the tracking script on.
To get started, in the project root, copy .dev.vars.example
to .dev.vars
.
Open .dev.vars
and enter the same values for CF_BEARER_TOKEN
and CF_ACCOUNT_ID
you used earlier.
Counterscale is built on Remix and Cloudflare Workers. In development, you have two options:
npm run dev
→ This runs the Vite development server in Node.js. This server will automatically rebuild files when you change them, but it does not best reflect Cloudflare's serverless platform.npm run preview
→ This runs Cloudflare's Miniflare server with a build of the Remix files. This closer matches the deployment environment, but does not (yet) automatically rebuild your app.There is only one "database": the Cloudflare Analytics Engine dataset, which is communicated entirely over HTTP using Cloudflare's API.
Right now there is no local "test" database. This means in local development:
Cloudflare Analytics Engine uses sampling to make high volume data ingestion/querying affordable at scale (this is similar to most other analytics tools, see Google Analytics on Sampling). You can find out more how sampling works with CF AE here.
Counterscale development is 100% volunteer-driven. If you use and like this software and want to see it improve, we encourage you to contribute with Issues or Pull Requests.
The primary goal of Counterscale is to be super easy to self-host and maintain. It should be "set up once and forget".
To achieve that:
users
table, no sites
table, etc.metricsDataset
columns can be added, but old columns cannot be removed or renamed (they can however, be "forgotten").