Tracking

An honest privacy policy. Yes, I track you. Here's exactly what I do and why.

Most "privacy policies" are written by lawyers to make tracking legal. This one is written by me, the person who actually built the tracking, to tell you what's going on so you can decide if you're okay with it. If you're not, there's a section at the bottom on how to opt out.

What I track

Every time you load a page, my code sends a small ping back to my server with:

While you're reading the page, I also track:

That's it. I don't fingerprint you, I don't load any third-party scripts, and I don't run ads. There is no Google Analytics, no Plausible, no Meta pixel, no Hotjar. It's all my own code, running on my own server, and the data sits in a SQLite file on a Hetzner box in Falkenstein, Germany. That's the only place the analytics data physically lives.

Why I track

I want to know what people actually use. Which talks get watched. Which events get clicked. Whether anyone reads the CFP guide. Whether the filters are useful. When I know that, I can spend my (limited) time building features that matter and ignore the ones nobody touches. That's literally the whole reason.

The other reason is bots. The site gets hammered by crawlers, AI scrapers, and outright spam. Some of that traffic is fine (Google, Bing, LLM bots citing the archive). A lot of it isn't. If I can't tell humans from bots, I can't size the server properly, can't trust the "popular talk" rankings, and can't keep the contact form from drowning in garbage. The tracking is partly there to make that distinction.

Cookies

I use exactly one cookie. It's called theme and it remembers whether you picked light or dark mode. That's it. No tracking cookies, no session cookies, no third-party cookies.

Your IP address

I do not store your raw IP address when you browse the site. The CDN sees it (it has to — that's how HTTP works), but the hash pipeline strips it before anything lands in my own database. What I do store is a visitor hashsha256(ip + user-agent + daily-salt). The salt rotates every day at midnight UTC, so even the hash can't be linked across days. Two people on the same network with different browsers produce different hashes; the same person across two days produces two different hashes. I cannot run the operation backwards to recover an IP.

The one exception: if you write to me — either through the [ feedback ] link at the bottom-right corner of every page, or through the dedicated contact page — your IP gets stored alongside your message. Not because I want it, but because both forms hit the same endpoint and that endpoint is the single biggest spam target on the site; I need the IP to rate-limit, block, and triage. If you don't write to me, I never see your IP.

The email field on both forms is optional. If you leave it blank, I have no idea who you are — just the message text and the IP that submitted it. I never have your email unless you choose to give it to me.

Sessions

The visitor hash described above doubles as a session identifier — it's how I count unique visitors and stitch a single person's clicks across multiple pages into one "session". It's not tied to a cookie, a login, or anything you can carry with you, and it dissolves at midnight UTC.

What I do with the data

I look at aggregates. Examples of what the admin dashboard actually shows me:

I don't sit there looking at individual people. The data is interesting in bulk, not one row at a time. I don't share it with anyone. I don't sell it. There is no marketing partner, no analytics partner, no anyone — this is a one-person side project.

Who reads it

Me. Just me. The server lives behind a Tailscale tunnel, an SSH key, and an IP whitelist — three things you'd need to compromise to touch the SQLite file directly. The admin dashboard is reachable over HTTPS but locked to one logged-in session at a time, so a stolen admin cookie kicks me out of my own session and I notice immediately. No team accounts, no read-only seats, no analytics-partner SSO, no third-party support tools with database access.

How long I keep it

Honest answer: indefinitely, for now. The tracking data is SQLite-small and the year-over-year comparisons are useful — "did this feature get more use after the redesign?" only works if I still have last year's rows. Because the visitor hash rotates every day at midnight UTC, rows older than today can't be linked back to a person anyway. I'm not sitting on identifiable history; I'm sitting on aggregated row counts that happen to be stored as individual rows.

If that ever changes — if the DB gets big enough that I need to prune — I'll prune raw rows older than some threshold (probably 180 days) and keep only the aggregates. Feedback-widget and contact-form messages are the exception: I keep them around in case the back-and-forth helps. If you want a message deleted, ask and I'll wipe the row.

Logs from the CDN

The site is served through a CDN (Bunny). My server pulls Bunny's raw access logs once an hour to catch traffic that doesn't run JavaScript — mostly LLM crawlers and basic scrapers that the in-page beacon can't see.

Bunny anonymizes the access logs before they reach me. They drop the last octet of every IPv4 address, replacing it with 0 (so 172.64.110.27 becomes 172.64.110.0) and collapse everything into a /24 network. I never see a full client IP from CDN traffic — only the /24. When I ingest a log file into my database, I run that already-masked address through the same daily visitor-hash pipeline described above and discard the masked value too. Bunny retains the logs they expose to me for three days on their side, then they age out.

The edge servers obviously see the full IP momentarily while serving each response — that's how TCP works — but the full IP never lands in any log I have access to, hashed or otherwise.

How to opt out

Right now, the cleanest opt-out is to disable JavaScript for allbsides.com. The pages are all statically rendered server-side, so they mostly work without JS — the talks page loses some filtering, the homepage typed-text intro is plain text, and the per-talk thumbnail won't expand to a video. With JS off, no scroll, time-on-page, filter, or click data leaves your browser. The CDN-log side still records your visit (it has to — that's just HTTP) but the visitor hash is the only identifier kept.

If you want to harden further:

I'm slowly working on a proper opt-out toggle (a "do not track me" button you can flip), but the catch is bots. Bots would set the toggle to look like opted-out humans, which corrupts the human/bot distinction I rely on to size the server, rank talks honestly, and keep the contact form usable. I'm working on it but won't ship a fake fix — when the toggle lands, it'll be paired with a way to keep bots from hiding behind it.

Your rights (GDPR)

I'm based in Estonia, the server runs in Falkenstein, Germany (Hetzner), and the CDN is operated by a Slovenian company (Bunny — their edge nodes serve from PoPs worldwide for performance, but the operator is EU). Most of you are in the EU too. Every legal entity in the data path sits under EU jurisdiction — so GDPR applies. Under it, you have the right to ask what data I hold about you and the right to have it deleted.

For most visitors, the honest answer to "what do you have on me?" is: nothing identifiable. The visitor hash is one-way and rotates every 24 hours, so even I cannot point at any row in the analytics tables and tell you it's yours. There is literally nothing to hand over.

The exception is anything you've sent through the [ feedback ] widget or the contact page. Those rows hold your message, your IP, and your email only if you typed one in (both forms make email optional — if you left it blank, I genuinely don't know who sent it). To get a row back or deleted, tell me enough to identify it: the email you used, the rough date you sent it, the page it was about, or a phrase from the message itself. I'll find it and either show it to you or wipe it.

Questions, corrections, complaints

If anything on this page is wrong, vague, or contradicts what the site actually does — tell me. I'd rather fix the page than be wrong. Use the [ feedback ] link in the bottom-right corner of this page (or any page on the site). Email field is optional — leave it blank if you want, the message still reaches me.

[ feedback ]