kogutdocs

Web apps

Data kogut collects

Stored analytics, visitor ids, retention, and outbound connections.

kogut stores web analytics in SQLite on your server. Use this page for your privacy notice; it is not legal advice.

Browser data

The script does not access cookies, localStorage, sessionStorage, IndexedDB, or Cache Storage. It does not inspect canvas, fonts, plugins, or hardware for fingerprinting.

EventSent whenFields
Page viewPage load, path change, or back/forward cache restorePage URL, referrer on initial load, window width, and automation flag
Web VitalsPage hide, exit, or route changeAvailable LCP, INP, CLS, FCP, and TTFB values
ErrorUncaught exception or unhandled rejectionRedacted message, source, line, column, stack, and fingerprint
Custom eventkogut.track() call or tagged clickName and properties
Outbound linkClick to another hostoutbound event with the destination URL

Events include the page URL, the site domain, and the app version when the tag sets data-version; the version describes the build of your app, not the visitor. Snippets with data-website-id omit the domain, and the server finds the site from the page’s host. Prerendered pages send nothing until activation.

Page URLs lose credentials, fragments, and query parameters except utm_source, utm_medium, utm_campaign, utm_term, and utm_content. Referrers and outbound links lose queries and fragments. Requests use fetch with keepalive, without cookies or a Referer header. Browsers also send request headers such as the user agent and language.

The visitor id

The server computes a separate visitor id for each site: the first 16 bytes of the SHA-256 hash of the salt, the site id, the length of the IP address, the IP address, and the user agent, in that order.

The salt has 32 random bytes and changes daily at 04:00 in the server’s time zone; the previous salt is deleted. The current salt is stored in SQLite so ids survive restarts. Backups exclude it.

The same visitor gets unrelated ids on different sites and days. Visitor totals over several days add the daily counts. A visit ends after 30 idle minutes or at the salt change.

Raw IP addresses and user agents are not stored. The server uses the IP address for rate limits and visitor ids, and the user agent for ids, bot filtering, browser, operating system, and device class.

Stored data

TableFields
hitSite, time, path, referrer host, channel, source, medium, campaign, country, device, browser, operating system, language, app version, visitor id, visit id, and duration
visitId, site, start, last seen, and page view count
vitalSite, time, path, device, app version, and available metric values, without a visitor id
custom_eventSite, time, name, properties, and visitor id
error_groupId, site, fingerprint, message, source, first seen, last seen, count, and state
error_eventGroup, time, path, browser, app version, and stack
hit_bucketDaily totals and counts by dimension, without individual visitor ids
vital_bucketHourly histograms by site, path, and metric
saltCurrent salt day and salt

Daily rollups cover 04:00 to 04:00 in the server’s time zone. Dimensions include paths, referrers, channels, countries, devices, browsers, operating systems, languages, sources, mediums, campaigns, and app versions. Each keeps up to 1,000 values per day, so rare values can disappear from older breakdowns.

The country comes from Cloudflare’s CF-IPCountry header; without Cloudflare in front of kogut, no country is recorded. kogut makes no GeoIP lookups and stores no region or city. Detected bots and automated browsers are dropped before storage.

Errors are redacted in the browser and on the server. Custom event values are redacted on the server, which does not remove all personal data. Event names and property keys are not redacted.

Kept only in memory

These records disappear on restart:

  • Up to 50,000 open visits, with visitor id, visit id, and last event time.
  • Rate counters for up to 10,000 clients, keyed by a hash of the IP and a startup secret.
  • The last 200 page views’ hashed client addresses and visitor ids, for proxy warnings.
  • Up to 20 app versions per site, with the time each was last seen.

Retention

Raw analytics, errors, daily rollups, and hourly histograms have separate settings in [retention]. Error groups remain after their events expire. The salt lasts until the next salt day.

Outbound connections

Browsers load the script from and post events to your kogut only. The server connects to check targets, DNS resolvers, domain registries and IANA’s RDAP list, notification services, configured OIDC providers, kogut edge, and a configured heartbeat URL. With nothing configured, it opens no outbound connection, not even a DNS lookup.

While a check of a public address exists, the server also probes connectivity to the hosts in connectivity_hosts. Agents connect to your server and their assigned check targets.

kogut sends no telemetry and makes no update checks.

MCP and Copy for AI

MCP requires an mcp token. Its tools return totals, breakdowns, Web Vitals, and error groups, not visitor ids, individual page views, or custom event properties.

Copy for AI copies the incident timeline, likely causes, alerts, and log excerpts. Likely causes can include JavaScript error counts.

Whether you need consent depends on your site and visitors; using no browser storage does not decide it. You can load the script after consent.

Do not send personal data in custom events.