Privacy & data retention
What MetrikStack stores and for how long, how visitors are counted without cookies, and what is never stored, from IP addresses to user agents.
Retention
| Data | Retention |
|---|---|
| Raw events | 24 months |
| Rollups (hourly/daily aggregates) | 36 months |
| Daily salts | Kept for two days after their own day, to cover late events, then deleted |
The aggregates stay available for a year after the raw events are deleted, so long-range charts keep working.
What is never stored
- Raw IP addresses. An IP is used only to look up country, region and city, to tell cloud and hosting networks from the networks people use, and to compute the visitor hash. It is then discarded within milliseconds. It is never written to storage or to any log. The lookup runs locally against a copy of the DB-IP Lite databases; no address is sent to a third party. When a request claims to be a known crawler, its IP is also compared against the address list that crawler's operator publishes, then discarded like any other IP (see Verified bots).
- Full user agents. Only derived, low-cardinality fields are kept:
device_type,browser+browser_version,os. - Cookies,
localStorageorsessionStoragevalues. The tracker script writes none of these, so nothing it sends can identify a returning visitor beyond the current day's hash. - Form data or request bodies, beyond the small set of fields each source's documentation lists (see Sources).
- Full query strings. Only
utm_*parameters andrefare kept; every other query parameter is stripped before the event is recorded. - A stable, long-lived visitor identifier of any kind.
- Anything more precise than a city. No coordinates, postal codes or network names are kept.
Visitor and session hashing
A visitor is identified by a hash of their IP address and user agent, together with the site id and a salt that changes every day. A session is the visitor hash plus a 30-minute rolling window, worked out at ingest. Only the hashes are stored, never the values they were made from.
The salt rotates at 00:00 UTC. Each day's salt is kept for 2 more days to cover events that arrive late, then permanently deleted. After that, hashes made with it are unlinkable: they can't be recomputed or reversed, and there is no way to tell that two hashes from different days belong to the same visitor.
Server and edge sources send the visitor's IP with each event and let MetrikStack hash it. The IP is discarded within milliseconds of arrival.
Log sources (access logs, log drains, Bunny Log Forwarding) carry the IP inside each log line. Those lines are only accepted over an encrypted connection and are handled the same way: the IP is used for the location and the hash, then discarded. A line that can't be read is counted and dropped, without being kept or written to a log.
For log sources that see every request, the lines for a page's scripts, styles, fonts and images are read as well, to tell whether a browser loaded the page (how). Such a line is not stored. What remains of it is the fact that the visitor hash fetched a file of that kind at that time, kept in memory for at most 30 minutes after the visitor's last request.
Global Privacy Control (GPC)
A pageview that carries navigator.globalPrivacyControl is still
counted, with the flag recorded. No personal data is kept in the first
place, so dropping the pageview would not protect the visitor any further.
The flag is stored so you can see how many visitors sent it.
Error reports
Error tracking follows the same rules as events, with one
exception: error text and stack traces are stored as your own code
produced them, minus a denylist. Values whose key looks like a credential
(password, token, secret, authorization and similar), card numbers
and IP addresses are filtered at ingest, but free text is not scanned for
e-mail addresses, IBANs or other personal data.
- Request headers are kept with sensitive ones filtered. Server errors carry HTTP
method, status code and headers;
cookie,set-cookie,authorization,proxy-authorizationand any*-api-key/*-token-style header are always replaced with[Filtered], in the SDK before it leaves your process and again at ingest. - Free text is sent as your code wrote it. An error message or stack trace that contains something sensitive because your own logging put it there will reach us as written, past the denylist above.
beforeSendlets you clean reports yourself. The Node SDK'sbeforeSend(report)hook runs last, before anything is queued, so you can scrub or drop a report before it leaves your server.
Everything else on this page applies to errors too. Request bodies, cookies, raw IPs and user identities are not stored, and browser, OS and country are derived the same way as for pageviews.
Bots
Bots, AI assistants and AI crawlers are stored like any other event (see AI crawlers and bots). The dashboard keeps them apart from people, and because they are stored you can see which crawlers and assistants read your site.
Hosting
MetrikStack is hosted in the Netherlands. Visitor data is processed and stored in the EU and does not leave it as part of the standard pipeline.