Product analytics · 4 min read · Updated 2026-09-21

Privacy and consent

Analytics is the part of observability most likely to end up in a privacy review. Here is exactly what Talaria stores, and what it refuses to.

Error tracking is easy to justify to a privacy officer: you are recording your own software failing. Analytics is harder, because you are recording people. The honest answer is not “we are anonymous, do not worry” — it is a specific list of what is collected, where it is stored, who can turn it on, and how to delete it.

Project settings, then consent

Analytics stays off until you turn it on for the project. The SDK still waits for the visitor:

  • Project settings → Analytics enabled. Off until you turn it on.
  • The SDK sends analytics only after optIn(). optOut() stops it again.

If the project is off, ingest is rejected server-side.

Typescript
// Errors and replay start immediately.
Talaria.init({ dsn, apiKey, release: '1.4.2' });

// Analytics waits for the visitor to agree.
onConsent((granted) => {
  if (granted) Talaria.analytics.optIn();
  else Talaria.analytics.optOut();
});

optOut() stops sending and discards anything queued. disable() is a harder kill switch for the rest of the page session.

First-party storage, not cookies

The browser SDK keeps the visitor and session ids in first-party localStorage under keys prefixed talaria.. Flutter uses shared preferences. Node and PHP hold nothing at all — you pass identity per call.

There are no analytics cookies, no third-party domains, and no cross-site identity graph. Talaria cannot follow anyone from your site to someone else's, because it never had the mechanism to.

Be precise when you write this up: it is first-party storage, not “cookieless”. A visitor id in localStorage is still a persistent identifier, and in most jurisdictions that means it belongs behind the same consent gate a cookie would.

What is stored, and what is not

An analytics event holds the fields described in Events and properties: identity ids, the event name and kind, page context, first-touch UTM, parsed browser/OS/device, country and region, traffic class, build context, correlation ids, and your properties.

Some things you might expect are simply absent from the schema:

  • No IP address. The ingest request IP is used in memory for a GeoIP lookup, then discarded. It is not a column.
  • No city, latitude, longitude, or postal code. Country (ISO 3166-1 alpha-2), region (ISO 3166-2), and continent are as far as location goes.
  • No raw User-Agent string. We store the parsed browser name and major version, OS, device class, and in-app WebView host.
  • No screen pixels, canvas or TLS fingerprints, or connection type.
  • No click or form autocapture. Nothing is recorded unless your code names it, or it is a route change.

Default uniques, pageviews, and top-page counts exclude crawlers, AI crawlers, and automation (HeadlessChrome, Playwright, navigator.webdriver). Known AI operators such as ChatGPT-User stay in those numbers and appear in a traffic breakdown, so you can see when an agent is using the product without letting Googlebot inflate DAU.

Redaction on both sides

URLs are cleaned twice. Before sending, the browser replaces anything matching a secret or click-id pattern — token, secret, api_key, access_token, gclid, fbclid, msclkid and friends — and drops the fragment entirely. On arrival, the server redacts secret query parameters again.

Property keys are filtered server-side against a denylist that includes password, token, authorization, cookie, email, credit_card, and ssn. Those keys never reach storage, whatever the SDK sends.

This is a safety net, not a policy. It catches the accidental email property; it will not catch a personal name you deliberately put in a property called customer. Decide what belongs in an event before you send it.

Deletion and retention

Raw analytics events are kept for 90 days and then deleted by the storage engine. The daily and hourly rollups expire on the same schedule. There is no longer-retention tier for analytics.

For an erasure request, an organization admin can delete everything for a user id, an anonymous id, or both — the rows are removed from ClickHouse rather than flagged. If the person in question was never identified, the anonymous id from their event detail is enough to erase them.

None of this is legal advice. It is a description of the mechanism, so that you and your own advisors can decide what your consent flow needs to say.

Related guides

  • Product analytics · 3 min

    Visitors, sessions, and identify

    Three ids doing three different jobs. Get them straight and every number downstream makes sense.

  • Product analytics · 3 min

    Events and properties

    Four kinds of call, one envelope, and a property bag you control. Naming is the only hard part.

  • Product analytics · 4 min

    What product analytics actually is

    Error tracking tells you what broke. Product analytics tells you what people were trying to do — and how many of them gave up.

Turn analytics on

Enable analytics on a project, opt in from an official SDK, and your first funnel is minutes away.