About these numbers
How each metric is defined, how Flatlytics differs from Google Analytics, and what our bot filtering does and doesn't do.
Metric definitions
Visitors
Distinct visitor hashes seen in the period. Because the hash rotates daily, a person visiting on two days counts on each. Uniques are per-day by design.
Pageviews
The number of pageview events. Repeat views of the same page all count.
Sessions
A visit. A session ends after 30 minutes of inactivity; the next event starts a new one.
Bounce rate
The share of sessions with a single pageview. Lower is usually better, so we colour its trend inverted.
Avg. session duration
Mean time from a session's first to last event. Single-event sessions contribute zero duration.
Goal conversion rate
Unique converting visitors ÷ unique visitors in the period (the Plausible convention), not conversions ÷ visits.
"Compared to previous period" runs the exact same query shifted back by one window of the same length.
How this differs from Google Analytics
- No sampling. Every query reads the underlying events, so numbers don't wobble between loads.
- Uniques are per-day, not stitched across days or devices. There's no cross-session identity.
- Sessions are a simple 30-minute inactivity window, not a configurable, engagement-weighted model.
- No demographic or interest inference. We measure the visit, not the person.
Bot filtering, honestly
In v1 we filter obvious bots by user-agent denylist, and we ignore automated browsers (navigator.webdriver) unless you opt in. We do not yet filter by IP range or known datacenter networks, so some non-human traffic can still slip through. We'd rather say so than quietly overstate "bot-free" numbers.
Recovering ad-blocked events with a first-party proxy
Some ad-blockers block requests to third-party analytics hosts, so a fraction of events never reach us. You can serve the tracker and receive events from your own domain by proxying two paths to our ingest host (https://flatlytics-ingest.silent-voice-a285.workers.dev), then pointing the tag at them with data-api:
<script defer
src="/js/f.js"
data-site="fl_pub_YOUR_SITE_KEY"
data-api="/api/event"></script>Proxy /js/f.js → /f.js and /api/event → /api/event on the ingest host. Requests are now first-party, so most content blockers leave them alone. This is a mitigation, not a guarantee. It's the honest ceiling on what client-side analytics can capture.