SYS.07 — PRIVACY
What this server knows
Rather than describe it in the abstract, here is what your browser is telling this server as you read this. Most of it is not written down — what is, and for how long, is 07.02.
No cookie was set to produce it, and nothing above was sent anywhere to produce it either.
- IP
- [recorded server-side — your browser cannot read it]
- TIMESTAMP
- —
- REQUEST
- —
- USER-AGENT
- —
- REFERRER
- —
- LANGUAGE
- —
- VIEWPORT
- —
- TIME ZONE
- —
8 FIELDS · NOTHING ELSE
These values are read by a small script in your browser. With scripting off nothing was read — and nothing was sent here to read it.
THE SHORT VERSION
- YesServer logs, 14 days, with no address in the clear
- NoNo cookies
- NoNothing counts your visit
- YesOne local entry: the colour scheme you picked
- NoNo third-party embeds, no CDN, no tag manager
- YesContact form to my mailbox, and the stored copy is deleted after 30 days
- NoNo advertising, no profiling
- NoNothing sold, nothing shared
Tim Seil, Luxembourg — reachable at contact@timseil.dev, and a postal address on request. There is no data protection officer: the scale of processing described below does not require one, and appointing one would not change any of it.
Every request to this application is written to a log line, the way every web server on the internet does it. That record is what makes it possible to see that the site is up, to find out why a page returned an error, and to notice when somebody is looking for a way in.
| FIELD | WHY IT IS KEPT | RETENTION |
|---|---|---|
| Method and path | To tell a working page from a broken one | 14 days |
| Status code and size | The same, and to spot a page that grew | 14 days |
| Duration | To find what is slow before you have to tell me | 14 days |
| Request and trace id | To follow one request through the system | 14 days |
| A keyed hash of your address | Abuse, and the rate limit in 07.06 | 14 days |
Three things a log usually holds are missing from this one. Your address is never written down as an address: what is stored is a keyed hash, the key is made fresh each time the process starts, and it is never written to disk — so a hash cannot be turned back into an address, and two visits either side of a restart cannot be tied to each other. The query string is never logged. And there is no user-agent or referrer column: your browser sends both on every request, as it does everywhere on the web, and this application does not keep them.
Legal basis: legitimate interest in operating and securing the service, Art. 6(1)(f) GDPR. The lines are not combined with anything else, and nobody but me reads them.
Nothing counts you. There is no analytics on this server: no counter, no pixel, no tag manager, no product bought for the purpose and nothing written for it either. I do not know how many people read this page. I find out that something was read when somebody writes to me about it.
That is also why there is no consent banner. A banner is a question you are asked because the answer is worth something to the one asking; here there is nothing to ask about, and a banner would be a worse trade for you than the thing it pretends to be about.
The log lines in 07.02 could in principle be counted. They are not: nothing aggregates them, no dashboard shows a visitor number, and after 14 days they are gone.
One entry, in local storage, written only when you do something. No cookie, no identifier, and it is never sent back to the server — I cannot read it.
| KEY | WHAT IT HOLDS | WHEN IT IS WRITTEN |
|---|---|---|
| ts.theme | Which of the seven colour schemes you picked | When you pick one |
Clearing your browser storage removes it. Without it the site still works: it follows whatever your system says about light and dark.
- Fonts. Served from this domain. Your browser makes no request to a font provider.
- The contribution graph. Fetched server-side from the GitHub API and cached here. Your browser never talks to GitHub.
- No embeds. No third-party video, no comment widget, no social buttons, no tag manager.
- Images. From this server, not from a CDN. That costs a few milliseconds and keeps the page to a single origin.
You can check all four: open your browser's network panel on any page here and you will find exactly one origin. What I can promise is that scope — this application and the pages it serves reach for nothing and nobody else. What sits between your machine and this one on the way, from your own network onwards, is not mine to make promises about, and I would rather say so than write a sentence that reads better.
Two ways in: the form on /contact, or plain mail to the address above. Both end in the same mailbox. The form exists because a mailto: link fails silently on any device with no mail client configured — it is convenience, not data collection.
| WHAT THE FORM SENDS | WHY | WHERE IT IS KEPT |
|---|---|---|
| Your name | So I know who I am answering | Database and mailbox |
| Your email address | The only way to reply | Database and mailbox |
| Your message | The reason you wrote | Database and mailbox |
| The time you sent it | Ordering, and spotting a double submission | Database and mailbox |
| A keyed hash of your address | The rate limit: three messages per 10 minutes | Database |
| How long the form was open | Telling a person from a bot | Database |
Two things here are the opposite of what a page like this usually says, so they are worth stating rather than burying. A row is written to a database: the message is stored before it is handed to the mail relay, so that a relay having a bad morning means a delayed reply instead of a lost message. And the measurement of how long the form was open is stored with it — of the two invisible fields the form sends, only the hidden one that must stay empty is thrown away on arrival.
It is deleted 30 days after the exchange is settled, by a loop that runs every hour.
The message is then handed to OVH GmbH in Köln, Germany, my mail provider, which delivers it and acts as a processor under Art. 28 GDPR. It then sits in my mailbox for as long as the conversation is useful to either of us. It is used to answer you and for nothing else: no newsletter, no list, no forwarding.
Legal basis: Art. 6(1)(b) GDPR where your message is about work, otherwise legitimate interest under Art. 6(1)(f); the rate-limit record rests on Art. 6(1)(f). Filling the form is voluntary, and every field on it is one I need in order to answer — without an address there is no reply. If you would rather not use it, the address above works just as well.
You can ask what is stored about you, ask for it to be corrected or deleted, object to the processing, or ask for a copy. Write to contact@timseil.dev or use the form. I answer within a month, and usually the same week.
One practical note about the logs. They are keyed by a hash and a time, not by a person, and the key that made the hash is gone the next time the process starts — so there is nothing in them I could find for you even if we both wanted me to. That is what the hashing is for. What I can look up is the contact table, by the address you wrote from.
If you think any of this is wrong, you can also complain to the CNPD — the Commission nationale pour la protection des données, Luxembourg.
LAST REVISED 2026-09-19