---
copyright: "© 2026 DSR Corporation"
title: "See who reads the docs"
slug: reader-analytics
order: 45
type: doc
description: "Built-in reader analytics: views, visits, top pages, readers, countries and traffic sources — self-hosted, with no IP address stored anywhere."
seoTitle: "Self-hosted documentation analytics: page views without third-party trackers"
seoDescription: "Built-in analytics for your documentation: views over time, top pages, signed-in and anonymous readers, and reader countries. Self-hosted in your own database, with no IP address stored and no third-party tracker."
icon: BarChart3
visibility: public
llmSummary: "DSR Docs ships reader analytics as part of the product: a report showing views over time (grouped by day, week or month over 7, 30, 90 or 365 days), top pages, readers, and reader countries, plus a per-page Stats view reachable from any page. Signed-in and anonymous readers are both counted and stacked in the chart, since guest access is on by default. Views are counted in the browser because a single-page app caches page content, so server logs would undercount. Requests are batched and flushed on a timer and on pagehide/visibilitychange; the server stamps the time, so a client clock cannot back-date a reading. Country is resolved from a local ip3country table (~470 KB) while the request is in memory, and no IP address is stored in any row; an admin can turn geography off entirely. Unique visits are counted with a per-day pseudonym: a salted hash of address and user agent, the salt being random per day and discarded at the day boundary, so readings cannot be linked across days. Traffic sources are recorded from the referring host only (Google, Bing, ChatGPT, Perplexity, Claude, Atlassian, direct, or the bare hostname) and never the referring URL's path or query. Raw events are kept 30 days and then folded into daily totals kept indefinitely, so long-range charts stay identical. Everything lives in the site's own SQLite database on the operator's infrastructure — no third-party analytics service, works on-prem and air-gapped."
faq:
  - q: "Does DSR Docs have built-in documentation analytics?"
    a: "Yes. Every install has a reader report: views over time, the top pages, who read them, and which countries they came from. There is nothing to install and no third-party account — analytics is part of the product, and the data lives in your own database."
  - q: "Can I see the view count for a single documentation page?"
    a: "Yes. Every page has a Stats action next to Edit and History that opens the same report scoped to that one page — the view trend, the readers, and the countries for that page alone."
  - q: "Do documentation analytics track readers with cookies or store IP addresses?"
    a: "No cookie, and no row anywhere holds an IP address. Counting unique visits needs the same browser to look the same twice, so a reading carries a pseudonym: a hash of the address and user agent under a salt that is generated at random each day and thrown away when the day turns. Within a day the same reader is one visit; across days nothing links them, because the salt that would allow it no longer exists. The address itself is used to work out the country and dropped with the request, and an administrator can switch geography off entirely."
  - q: "Can I see where readers came from — Google, an AI assistant, a direct link?"
    a: "Yes. Each reading carries the referring host, which the report groups into sources: Google, Bing, ChatGPT, Perplexity, Claude, Atlassian, direct visits, and any other site by its bare hostname. Only the host is kept, never the page somebody came from — a referring URL’s path and query are the other site’s business, and sometimes their credentials."
  - q: "Are anonymous readers counted?"
    a: "Yes, as anonymous. Guest access is on by default, so most documentation traffic is not signed in; the chart stacks anonymous and signed-in readings so the gap between them is visible rather than hidden."
  - q: "How long is documentation analytics data kept?"
    a: "Individual readings are kept for 30 days, which is what answers 'who was reading this on Tuesday'. After that they are folded into daily totals that are kept indefinitely. Nothing a chart can draw is lost in the fold — only the time of day within a day."
---

# See who reads the docs

Publishing documentation without analytics is writing into a void. Most teams solve it by pasting a third-party tracker into their docs site, which means handing every reader — customers, partners, sometimes people behind a corporate firewall — to somebody else's advertising infrastructure.

DSR Docs counts readers itself. The report is part of the product, the data is in your database, and no reader is ever handed to a third party.

## What the report shows

- **Views over time.** A chart grouped by day, week or month, over the last 7, 30, 90 or 365 days. Signed-in and anonymous readings are stacked, so the split is visible at a glance. Days nobody read anything are drawn as zero rather than skipped, so a quiet week looks quiet.
- **Visits.** Distinct visits alongside raw views, so ten pages read in one sitting read as one visit and not as ten readers.
- **Pages.** Which documents are actually read, and which ones nobody opens — usually the more useful half of the answer.
- **Readers.** Who has been reading, for the readings that carry an identity.
- **Where from.** Reader countries, when geography is enabled.
- **Sources.** Where the visit came from: a search engine, an AI assistant, another site by name, or a direct visit.

Every column in every table sorts: figures biggest-first, names A to Z.

## Per-page stats, one click away

Next to **Edit** and **History** on any page there is a **Stats** action. It opens the same report scoped to that single document — the trend, the readers, the countries for that page alone. Useful right after you rewrite something and want to know whether anyone noticed.

The report is behind the same gate as the editor: editors and admins see it, readers do not.

## Why counting happens in the browser

DSR Docs is a single-page app. A page's Markdown is fetched once and cached, so the second reader of a page makes no request the server could count, and a reader moving between sections of a scroll-layout document makes none at all. Server logs would describe a site nobody visits.

So the browser reports the reading — and does it politely:

- **Batched.** A reader crossing a long section document touches a dozen anchors in as many seconds. Those become one request, not a dozen.
- **Flushed when a reading actually ends.** On a timer, when the queue fills, and on `pagehide` and `visibilitychange` — the last two being what really happens when someone closes a tab.
- **Timestamped by the server.** A client clock is worth nothing, and a caller-supplied timestamp would let anyone write into last month.
- **Keyed to the content file**, not the URL, so a page keeps its history when you rename or move it.

## Privacy is the default, not a setting

- **No IP address is stored anywhere.** The country is resolved while the request is still in memory, and the address is dropped with it.
- **The visit pseudonym expires by construction.** Counting visits needs one browser to look the same twice, so a reading carries a hash of the address and user agent under a salt that is random per day and discarded when the day turns. Yesterday’s readings cannot be linked to today’s, and not as a promise: the salt that would do it is gone.
- **The lookup table is local** — about 470 KB of it, shipped in the image. A documentation server that asks an address-lookup service about every page view is a documentation server that leaks its readers.
- **Geography is optional.** An operator who would rather not know turns it off in Admin, and the column stays empty.
- **Anonymous stays anonymous.** A reader who is not signed in is recorded as a reading without an identity, not tracked into one.

Because everything is self-hosted in the same container as the docs, this works unchanged on-premises and in air-gapped networks, where a hosted analytics service is not an option at all.

## What is kept, and for how long

| Data | Kept | Why |
|---|---|---|
| Individual readings | **30 days** | Answers "who was reading this on Tuesday" |
| Daily totals — page, reader, country | **indefinitely** | Answers "how did this page do over the year" |

The fold from one to the other *is* the retention policy: nothing a chart could still draw is deleted, only the time of day within a day. Long-range charts read identically either side of the boundary.

> [!IMPORTANT]
> **Want this on your own documentation?** Write to docs@dsr-corporation.com. Ask about migration, licensing, or anything this page didn't cover.
