theia

Privacy-First Server-Side Analytics

v0.0.10 · July 2026

Analytics built for privacy. Track page views through server logs, with zero impact on your visitors' experience.

Traditional analytics slow down pages and invade privacy with persistent tracking. Our approach starts different: server-side by default, privacy-first by design. Clean data without compromise.

Features

No Client-Side JavaScript

theia parses nginx access logs directly. Nothing loads in the visitor's browser, so there's no script to block and no impact on page performance.

Privacy-First Hashing

IP addresses are hashed with user-agent and date (SHA256) before storage. Raw IPs never touch the database.

Automatic Bot Detection

Bots and static asset requests are filtered out automatically, so pageview counts reflect real visitors.

Real-Time Log Tailing

Reads the nginx access log as it grows and writes to SQLite asynchronously. No batch jobs, no delay.

Machine-Readable Output

theia stats --format json returns the same summary as the table view, for scripting or dashboards.

Automatic Data Retention

Old records clean up on a schedule: hourly stats after 60 days, visitor hashes after 1 day. Nothing to prune by hand.

How It Works

  1. 1

    Reads the nginx access log in real time with a tail-style follow, no polling or batch jobs.

  2. 2

    Parses each line for path, referrer, user agent, IP, status code, and bytes sent.

  3. 3

    Hashes the IP with the user agent and date (SHA256) before anything is written to disk.

  4. 4

    Flags bots and static asset requests automatically, so counts reflect real visitors.

  5. 5

    Writes to SQLite asynchronously, then prunes old records on a schedule.

How does theia compare?

Most privacy-friendly analytics tools still ship a tracking script, just a small one. theia ships none.

PlausibleElixir + ClickHouseClient-side tracker scriptCloud-first analytics platform

Hosted or self-hosted analytics with a polished dashboard, goals, and funnels. A tracker script still loads and runs on every page.

Good for:You want a dashboard product with funnels and goal tracking, and don't mind running ClickHouse.

Less ideal for:You want zero client-side footprint or don't want to operate a ClickHouse cluster.

UmamiNext.js + PostgresClient-side tracker scriptSelf-hosted analytics dashboard

Full analytics UI with events, funnels, and a Postgres backend. Easy Docker deploy, still relies on a client-side tracker.

Good for:You want a friendly dashboard and are already running Postgres.

Less ideal for:You'd rather not run a database service just to count pageviews.

GoatCounterGo + SQLiteClient-side tracker scriptLightweight self-hosted analytics

Closest in spirit to theia on the server side. Single Go binary, SQLite by default, minimal resource use. Still ships a tracker script to the browser.

Good for:You want a tiny self-hosted footprint and are fine with a client-side script.

Less ideal for:You want tracking with literally nothing running in the visitor's browser.

theiaGo + SQLiteNone, server logs onlyZero-JS server-side analytics

Parses nginx access logs directly. No script ships to the browser at all, so there's nothing to block and nothing to slow the page down.

Good for:You want pageview analytics with zero client-side footprint and already run nginx.

Less ideal for:You need client-side events like clicks or scroll depth that server logs can't see.

Tech stack details drawn from each project's public documentation, not an independent benchmark.

Commands

theia daemon --log-path <path> --db-path <path>Start tracking pageviews from an nginx access log
theia stats --db-path <path>Show a summary for the last 7 days
theia stats --days 30 --host example.comFilter the summary by lookback window and host
theia stats --format jsonMachine-readable summary output
theia stats --top 20Show more top paths and referrers

Install

curl

curl -sSL https://codeberg.org/Elysium_Labs/theia/raw/branch/main/install.sh \
  -o install.sh
sudo bash install.sh

wget

wget \
  https://codeberg.org/Elysium_Labs/theia/raw/branch/main/install.sh
sudo bash install.sh

Requires Linux with systemd. Installs a binary, sets up nginx log formatting, and creates a systemd service.