Privacy
Short version: no cookies and no accounts. The site's own page-view counts do not include your IP address, and if your browser tells scripts that it sends Do Not Track or Global Privacy Control the site's counter does not count you at all. Encrypted backups of the counter's database are kept for about a year. Cloudflare, which delivers the site, sees your connection and adds its own analytics script to every page, which Do Not Track and Global Privacy Control do not stop. Cloudflare also adds a small script that decodes my e-mail address on the two pages that show it, and its Network Error Logging, which is on, asks Chrome and other Chromium-based browsers to report requests to this site that fail.
What is counted
Page views are counted by a self-hosted copy of GoatCounter running on the same server as this site. After a page has loaded, a script from this site sends one request to /_stats/count on this origin. The script and that request stay on this site: no analytics company receives them (Cloudflare, which carries every request to this site, sees them too; see Cloudflare below). That request carries:
- the page path (always the bare path: the site's loader sets it, so a query string in the address never reaches it) and the page's title;
- the address of the page that linked here, if your browser sends one;
- your screen width in pixels;
- the query string of the page you landed on, if it has one;
- whether your browser reports that it is automated;
- and, like every request, your IP address and your browser identifier (user agent).
For each page view GoatCounter records:
- the page path, without any query string, and the page's title (for example
/blog/some-post: GoatCounter drops the trailing slash); - where the visit came from, as one value:
- when the query string of the page you landed on has a
utm_source,ref,srcorsourceparameter, the value of the first of those that is set, in that order, in place of the linking page's address; - otherwise, when it has a
utm_campaignorcampaignparameter, the address of the page that linked here exactly as your browser sent it, its own query string included; - otherwise, the address of the page that linked here without its scheme and query string (or a group name such as "Google" for some well-known sites), if your browser sent one;
- when the query string of the page you landed on has a
- the value of a
utm_campaignorcampaignparameter in that query string, as a campaign name (both, when both are set); - your screen width in pixels;
- the name and version of your browser and of your operating system, read from the browser identifier (user agent);
- the country your connection appears to come from, looked up in a country-level database;
- whether this is your first view of that page within a visit.
The query string of the page you landed on is not stored itself: GoatCounter reads only those six parameters from it.
It does not store your IP address or your browser identifier with the counts, and it sets no cookies. To tell a new visit from a reload, it holds the two together in memory, linked to a random visit number and to the pages viewed in that visit, until eight hours after your last page view. They reach its database only while the counter restarts: it saves open visits when it stops and deletes them as soon as it starts again. Requests that look automated are not counted; GoatCounter keeps their path, time and browser identifier in its database for 30 days. The nightly backups described below can keep copies of both kinds of record for longer.
When your browser tells scripts that it sends Do Not Track or Global Privacy Control, the site never loads its counting script and sends nothing to GoatCounter, so GoatCounter does not count your visit at all. This check covers GoatCounter only: it cannot reach Cloudflare's analytics script (see Cloudflare below), which Cloudflare's network adds to each page after the page has left my server, so that script loads and reports whatever your browser signals.
What the server logs
The web server (Caddy) writes one access-log line per request to averyuslaner.com, with the time, the method, the host name, the path requested (without any query string), the protocol, the response status, the response size and the duration. Requests to the counter, for the counting script or for a count, are not logged at all, and neither are requests to www.averyuslaner.com, which the server only redirects to averyuslaner.com. The log does not contain your IP address, your browser identifier, cookies, or any request header, the Referer header included. These logs go to the server's system journal and nowhere else: the journal deletes each entry within about 15 days (sooner if it exceeds 200 MB). They are used only to diagnose errors.
Backups
Every night the server copies the counter's whole database into a backup stored with Backblaze B2. The backup is encrypted on the server before it leaves, so Backblaze cannot read it. The copy holds the page views listed above, the automated requests with their path, time and browser identifier, and, if the counter happens to be stopped at that moment, the open visits with their IP addresses, browser identifiers and pages viewed. I delete old backups by hand about once a month, keeping the last 14 daily, 8 weekly and 12 monthly ones, so a copy can last about a year, a little longer when that clean-up runs late. The server logs are not backed up, and the backup of the bird feeder data holds nothing about visitors.
Cloudflare
The site is delivered through Cloudflare, which caches pages and absorbs attacks. Your connection terminates at Cloudflare's network before it is forwarded to my server, so Cloudflare sees your IP address and request details and processes them under Cloudflare's privacy policy. Cloudflare does not send me its logs of the requests it carries, but its security dashboard shows me a sample of the requests it carries, whether or not one of its security rules, such as its firewall or the rate limit on the data API, acted on them. Each request shown comes with its IP address, the network and country it came from, the path requested and possibly its query string, and the browser identifier (user agent), for up to 31 days. Its AI crawler report shows me how often the crawlers of AI companies fetched which pages; it is about those crawlers, not about visitors.
Cloudflare also adds scripts of its own to the pages, in two ways. One is Web Analytics, below. The other is its e-mail address obfuscation, which I keep on: on the pages that show my e-mail address (this one and the resume), Cloudflare replaces the address with an encoded copy and adds a small script, loaded from this site's own address, that turns it back into a link in your browser and does nothing else. I have turned off the other Cloudflare features that would add scripts to the pages.
Cloudflare also asks your browser to report requests to this site that fail, a feature called Network Error Logging, which is on for this site. The instruction comes in the headers of every response from this site; Chrome, Edge and other Chromium-based browsers follow it, Firefox and Safari do not. For up to 7 days after your last visit, whenever a request to this site fails, because the connection could not be made or broke off or because the site answered with an error such as "page not found", your browser itself sends a report to a.nel.cloudflare.com, sometimes a while later. Requests that succeed are not reported. The report holds the address that failed, query string included, the page the request was made from, the error or status code, the server's IP address, how long the request took and your browser identifier (user agent), and like any request it comes from your IP address. Cloudflare's Network Error Logging page says that Cloudflare looks up your network, country and metro area from that address and keeps the address only while it handles the report. Do Not Track and Global Privacy Control do not stop these reports.
Cloudflare Web Analytics
I also use Cloudflare's own visitor statistics. Cloudflare's network adds a script to every page it delivers, loaded from static.cloudflareinsights.com; the pages I publish do not contain it. After the page has loaded, the script reports the view to Cloudflare, and it sends a last report when you leave the page. It sends both to /cdn-cgi/rum on this site's own address, which Cloudflare's network answers itself: the reports never reach my server. Cloudflare has also set the script to count a change within a page as a new page view: picking another range on the dashboard, following a link to another part of the same page or using the "Skip to content" link is reported as a further view, with its own time, and with it go the measurements of the view before it (among them the element you clicked).
Cloudflare's Web Analytics page and its documentation of the script, what it records and its page-speed measurements say that it uses no cookies and stores nothing in your browser, such as local storage. The Web Analytics page also says that Cloudflare does not "fingerprint" individuals "via their IP address, User Agent string, or any other data for the purpose of displaying analytics". What it records is:
- the page path (Cloudflare's Web Analytics FAQ says it does not record query strings) and the page that linked here;
- how you reached the page: by a link, a reload, the back or forward button (whether your browser loaded the page again or showed a copy it had kept in memory), a page your browser prepared in advance, a tab your browser restored after pausing it, or a change within the page as above, and whether your browser's cache supplied it;
- your browser, operating system and kind of device, and your country;
- the version of your operating system, which the script asks your browser for directly;
- timings of how the page loaded, and how much memory the page's JavaScript uses;
- the largest element on the page and how long it took to appear, with the address of its image or font if it has one, and the element that moved most while the page loaded, with where it was before and after;
- for the slowest response to a click, tap or key press, which element you clicked or typed into, the kind of input and how long the page took to respond.
The same FAQ says that Cloudflare keeps what the script sends in full for 7 days and then aggregates it down to a sample of about 10%, and that the statistics can be viewed for the previous six months; it does not say when they are deleted. Cloudflare sees every request anyway, as said above, and this data too falls under Cloudflare's privacy policy.
The Do Not Track and Global Privacy Control check covers GoatCounter only: Cloudflare adds its script after the page has left my server, so the check cannot stop it, and the script runs whatever your browser signals. If your browser or an extension blocks static.cloudflareinsights.com, as many content blockers do, the script does not load and Web Analytics does not count you (Cloudflare still sees your requests, as above).
Nothing else. No analytics from Google or anyone else beyond these two, no social buttons, no embedded players, no fonts loaded from other hosts. Everything the pages I publish ask your browser to fetch comes from averyuslaner.com. In your browser's network tool, the one request to another host is Cloudflare's script from static.cloudflareinsights.com, and its report goes to averyuslaner.com/cdn-cgi/rum. The failure reports described under Cloudflare go to a.nel.cloudflare.com and are sent by the browser itself, so they need not show there.
The bird feeder data
The dashboard shows statistics from a camera and a weather sensor at a bird feeder in my yard. What reaches this site is deliberately coarse. The data the dashboard is built from, which the public data API serves field for field (listed under "Read the data yourself" on How it works), carries:
- hourly counts of detections and visits per species, with the classifier's average confidence for the hour and whether the hour's counts may still change;
- daily totals of detections and visits, with the number of bird species, the first and last hour with activity, and whether the day was fully observed (before 21 October 2026: whether its identifications were reliable);
- hourly temperature, humidity and sea-level pressure, rounded, with the number of sensor readings behind each hour, which shows when the sensor was out for part of an hour;
- a list of the individual detections of the last 24 hours, each with its time, duration, species and confidence;
- how many minutes of each hour the camera was watching (streaming, with video that decodes), since 21 October 2026;
- the image classifier's summary scores (F1): the macro F1 of each training run on its validation set and, for runs since October 2026, on held-out detections I labelled, with how many there were and how the run split its data; the run's label, the day it was trained and the sizes of its training and validation sets; and for the latest run the kind of model, its F1 per species with the number of held-out detections behind each, the 95 % interval of its held-out score, how well its confidence is calibrated and the confidence below which a detection counts as Unknown;
- the species the classifier can report, with the first day each was seen;
- date ranges, from a scan of the stored detections, when the camera captured badly or not at all, with a short reason;
- the outdoor weather for each hour in the centre of Salt Lake City (temperature, humidity, precipitation, cloud cover, wind, sea-level pressure and sunshine) from Open-Meteo's weather model, which the web server fetches itself: it comes from Open-Meteo, not from home, and describes the city, not the yard;
- a coarse fresh, stale or offline state of the data, the hour of the latest push from home and the hour of the latest detection.
Never published: any image, video, or identifier that could fetch one; the location of the bird feeder beyond the city named on my resume; the camera or network names; when I review or label images (no field says so, but see below); any time finer than the hour, except in the last 24 hours of detections; whether equipment at home is on or off, beyond what the list above shows: the hour of the latest push (rounded down to the hour), which hours have sensor readings and how many, how many minutes of each hour the camera was watching (so an outage, or the camera being switched off, shows to the hour), the coarse state of the data and those date ranges. Someone who polls the data often can still estimate, to within minutes, when home sends its updates: the data and its version tag (ETag) change when an update brings something new (and, each hour, when new weather arrives, which says nothing about home), and the fresh, stale or offline state changes only with an update or on the hour. Checking images shows the same way: each update repeats the past two weeks of data, and once a week all of it, so a detection I check changes in the next update that covers its day. It becomes certain, turns Unknown or disappears in the last day's list (while it is on it) and in the daily totals at once, and in the hourly counts once its hour is two days old, so someone who watches the data can tell roughly when I was checking. The camera points at a bird feeder, not at a street or a neighbour. The data flows one way, from home to the website, and the website has no way to reach back. To get the weather, the web server asks Open-Meteo every hour for that one public point; the request carries nothing about you or the bird feeder.
What I do not do
- No user accounts, logins, login sessions or comments.
- No cookies of any kind, including from either analytics service (Cloudflare states that Web Analytics sets none).
- No advertising, affiliate links or sponsored content.
- No sale or sharing of the visit data the server keeps: the only copy that leaves it is the encrypted backup described above. What Cloudflare's script measures, and the failure reports described there, go from your browser to Cloudflare directly (see Cloudflare).
- No e-mail collection. The domain does not send mail.
Contact
Questions about any of this: [email protected]. Security reports go to the address in security.txt.