Most online vision tests quietly keep your results on a server. Most online health tests of any kind do. The free ones often more than the paid ones — when the page itself is free, the data is doing the work of paying.
We don't do that. When you take this test, the patterns on your screen and the contrast values your eyes resolve are computed in your browser, written to your browser's storage, and stop there. Nothing about your result reaches us. We can't see it, can't aggregate it, couldn't hand it over if asked.
This post is the reasoning. What we do, what we don't, what we give up by deciding this way, and what we'll do if the policy ever changes.
What actually happens when you take the test
A short tour of the wiring, because privacy claims are only as good as the mechanism that backs them.
The test runs in your browser. The staircase, the response handling, the threshold estimate, the per-frequency log contrast sensitivity — all JavaScript executing locally. We don't have a "compute the result" endpoint. There's nothing to call.
Results are stored in localStorage. A small per-site key-value store the browser keeps on your device, scoped to our domain. Only pages on our domain can read it, only you can clear it. Clearing your browser's site data wipes it.
Share links encode the result in the URL fragment. When you tap "Share my result," the test builds a URL that looks like …/?utm_source=share…#r=<encoded-result>. The encoded payload (mode, AULCSF, per-frequency log CS, timestamp — about forty characters) lives in the part of the URL after the #. Browsers don't transmit fragments to servers in normal navigation (RFC 3986 §3.5 — fragment identifiers are resolved by the client). The link is readable by whoever you give it to. It isn't transmitted to us when someone opens it.
That isn't a guarantee that the link is mathematically secret — anyone you share with can paste it into another tool. The promise is the narrow one: it doesn't come back to our server.
Analytics, only if you say yes. We use PostHog to count events. The first time you load the test we show a consent banner; click No and the SDK never loads. Click Yes and we capture event-level signal — test_started, calibration_complete, result_viewed, result_shared — together with the psychophysical numbers (threshold contrast, log CS, AULCSF). No name, email, IP, or anything we could turn into a person. If your browser has Do Not Track on, the banner doesn't appear and analytics stays off by default.
The fuller technical and legal description lives on the privacy page; the share-link mechanism is described again, in greater detail, on the methodology page.
What we don't have
Inverted, the list is shorter and sharper.
We don't have a database of test results. No table called results, no row called yours, no endpoint that returns it. If we wanted to look up what you scored, we couldn't.
We don't have your email — not unless you typed one into the newsletter form on the results page. In that case we have an email address and the variant you tested on, and that's it.
We don't have your name, address, phone number, or any other identity attribute. The test doesn't ask. The site doesn't ask. We don't infer.
We don't have a profile that links your result to your behaviour. There's no cookie tying "person who scored low at 6 cpd" to "person who later clicked an ad about mold." Each of those things may exist as an anonymous event count. Neither is attached to the other or to you.
We don't sell or share. Nothing in the way the test is built routes data to a broker, an ad network, or any third party beyond the analytics provider on the banner.
Why this matters: vision data is more sensitive than it looks
A contrast sensitivity score is not, on its face, alarming. It's a number that comes out of a small psychophysical task. But the same is true of most health data points until they end up next to other things.
Reduced contrast sensitivity is associated with cataract, glaucoma, multiple sclerosis, concussion, certain medications, and normal aging. None of those associations is diagnostic. All of them are the kind of thing an insurer, an employer, or a marketer might find interesting if they could attach a low score to a name. The score itself doesn't give that person to them; the linkage would.
Re-identification of "anonymous" health data is hard to keep solved at scale. In 2000, Latanya Sweeney showed that the combination of ZIP code, sex, and date of birth uniquely identifies roughly 87 percent of the US population — work she later extended into the formal definition of k-anonymity (Sweeney, 2000). In a 2013 study of Washington State's $50 hospital-data release, she attached a real name to roughly 43 percent of newsworthy patient records by cross-referencing public demographics (Sweeney, 2013). "Anonymous" is a property of a release in a moment, not a property of the data itself.
The most reliable privacy guarantee is the one that doesn't depend on us keeping a promise. If we don't have your data, we cannot release it, leak it, mis-merge it, be warranted into producing it, or sell the company holding it. The pile that doesn't exist doesn't get re-identified.
What we give up by deciding this way
Privacy-by-default has costs, and it's worth being honest about which ones we eat.
No history across devices. Test on your laptop today, on your phone next week, and the app sees two unrelated sessions. Your laptop has one history; your phone has another. For someone tracking a long arc of change, that's friction.
No automatic re-test comparison. "You scored 1.9 log CS at 6 cpd three months ago — here's how today compares" is a useful feature, and we don't have it. The numbers exist in your browser; we have no server-side view to make the comparison. The trend is yours to keep.
Less ability to improve the test. Test-retest reliability, normative bands for under-represented age groups, calibration drift on specific device classes — every one of those product questions is easier with a corpus of real anonymised results. We work from the published literature and our own pilots instead, and progress is a step slower.
Less help for epidemiology research. A million completed tests, even anonymised, would be a useful artefact for researchers studying contrast sensitivity in long COVID, post-concussion recovery, or biotoxin exposure. We're not building it by default. If we ever do, it will be opt-in, explicit, and described before you consent to it.
For users who want a persistent record across devices, a future paid tier will offer it as an explicit feature — opt in, your data on our server under an explicit contract, deletable on request. The free test stays as it is.
Why some products store results by default
This is where the post earns its mild edge, because the default choice in the rest of the industry is not an accident.
Storing is useful. It lets teams improve the test, A/B-test result presentation, run cohort analyses on test-retest reliability, and debug by replaying real result trajectories. Most of those are genuine product-quality goods. We don't have access to them.
Comparison features rely on it. "See how you compare to other users in your age band" is only buildable if you have those other users' scores. So is "your score has moved by X over Y months." So is the longitudinal sparkline every paid health-tracking app will show you. None of those are bad features. They have an entry price, paid in your data.
Account models depend on lock-in. A product whose value compounds with each new entry into your account is one you're less likely to leave. That's not a conspiracy theory — it's a perfectly ordinary business model, used by every fitness tracker, journal, and habit app on your phone.
Defaults are policy. When a checkbox is opt-out and it's pre-ticked, the overwhelming majority of users never uncheck. The default state is the policy, regardless of what the privacy page formally says. The way to opt every user into storage is to make storage the default and put the opt-out three menus deep.
Most of this isn't malicious. It's the natural result of building under a different assumption about what the user owes the product. We're under a different assumption: the user owes the product nothing, and the product earns trust by giving up the easy defaults.
Our explicit promise
The version we'll stand behind in writing.
The free test will keep computing results in your browser and storing them in your browser. Nothing about a free-tier result leaves your device toward our server unless you explicitly act — by sharing a link (the recipient gets it via a URL fragment, never our infrastructure), by opting in to anonymous analytics (the psychophysical numbers travel without your identity), or by typing your email into the newsletter form (we get your email and nothing else).
A future paid tier will offer opt-in server-side storage as a feature. If you choose to use it, your data will live on our server under an explicit contract — exportable as JSON, deletable on request, never repurposed beyond what the policy in force on signup day described.
We will not sell or share any user data. That's a permanent commitment, backed in plain language on the privacy page.
If we ever materially change any of this — what we collect, who receives it, what defaults apply — we'll announce it here, update the privacy policy with a new effective date, and email anyone subscribed to updates. Changes apply forward only. Past free-tier results don't migrate onto a server because we changed our minds; they stay where they are unless you decide to bring them along.
Take the test
The simplest version of all of this: take the test without typing anything, without an account, and without giving us a way to look at your result later. If you want to keep it, share the URL with yourself. If you don't, close the tab and we'll never know you were here. That's the product working as intended.
For the longer story of why the test exists, the origin post covers it. For the legal version of this policy, the privacy page is the authoritative source.
Note. This post describes the free-tier behaviour as it stands today. The privacy policy on this site is the binding document; if anything here ever drifts from it, the policy wins.
References
- Sweeney, L. (2000). Simple Demographics Often Identify People Uniquely. Data Privacy Working Paper No. 3, Carnegie Mellon University. The foundational result: ZIP, sex, and date of birth uniquely identify about 87 percent of the US population. The paper that frames why "anonymous" health data tends to stop being anonymous in the presence of a second dataset.
- Sweeney, L. (2013). Matching Known Patients to Health Records in Washington State Data. Harvard University Data Privacy Lab Working Paper 1089-1 (also arXiv:1307.1370). Empirical demonstration: a $50 state hospital data release was successfully re-identified for roughly 43 percent of newsworthy patients by cross-referencing public demographics. The modern citation for "deidentified health data is harder to keep deidentified than you'd think."
- Pelli, D. G., Robson, J. G., & Wilkins, A. J. (1988). The design of a new letter chart for measuring contrast sensitivity. Clinical Vision Sciences, 2, 187–199. The methodology anchor for the contrast sensitivity test itself — included here for completeness; this post is about the data-handling layer, not the measurement.