{
    "archive_path": "archive/1791799470.531906",
    "base_url": "royfish.dev/fingerprints-are-the-new-cookies",
    "basename": "fingerprints-are-the-new-cookies",
    "bookmarked_date": "2026-10-12 10:04",
    "canonical": {
        "archive_org_path": "https://web.archive.org/web/royfish.dev/fingerprints-are-the-new-cookies",
        "dom_path": "output.html",
        "favicon_path": "favicon.ico",
        "git_path": "git/",
        "google_favicon_path": "https://www.google.com/s2/favicons?domain=royfish.dev",
        "headers_path": "headers.json",
        "htmltotext_path": "htmltotext.txt",
        "index_path": "index.html",
        "media_path": "media/",
        "mercury_path": "mercury/content.html",
        "pdf_path": "output.pdf",
        "readability_path": "readability/content.html",
        "screenshot_path": "screenshot.png",
        "singlefile_path": "singlefile.html",
        "warc_path": "warc/",
        "wget_path": "royfish.dev/fingerprints-are-the-new-cookies.html"
    },
    "domain": "royfish.dev",
    "extension": "",
    "hash": "1RB0WC1SNN9X7TWNKMPN",
    "history": {
        "archive_org": [],
        "dom": [],
        "favicon": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://www.google.com/s2/favicons?domain=royfish.dev"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-10-12T10:08:22.229820+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1791799470.531906",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-12T10:08:21.459702+00:00",
                "status": "succeeded"
            }
        ],
        "git": [],
        "headers": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--head",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://royfish.dev/fingerprints-are-the-new-cookies"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-10-12T10:08:22.644067+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1791799470.531906",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-12T10:08:22.239376+00:00",
                "status": "succeeded"
            }
        ],
        "htmltotext": [],
        "media": [],
        "mercury": [
            {
                "cmd": [
                    "/app/node_modules/@postlight/parser/cli.js",
                    "https://royfish.dev/fingerprints-are-the-new-cookies"
                ],
                "cmd_version": "1.0.0",
                "end_ts": "2026-10-12T10:08:28.919244+00:00",
                "index_texts": null,
                "output": "mercury",
                "pwd": "/data/archive/1791799470.531906",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-12T10:08:25.481387+00:00",
                "status": "succeeded"
            }
        ],
        "pdf": [],
        "readability": [
            {
                "cmd": [
                    "/app/node_modules/readability-extractor/readability-extractor",
                    "/tmp/tmpxqefizm2",
                    "https://royfish.dev/fingerprints-are-the-new-cookies"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-10-12T10:08:25.471077+00:00",
                "index_texts": [
                    "From now on I\u2019ll call you:\n\nTry refreshing the page. Clear the cookies. Connect to a VPN.\nYou\u2019re still the \u2026.\nNow open it on your phone or some other device and your nickname will be different and just as consistent.\nIs it different in incognito? Good. But it\u2019s always the same? Bad news.\nImagine this:\nMost websites you visit get paid to show ads and indirectly run my script that lets me know you\u2019re the \u2026. I can use it to decide what ads you\u2019ll see. But more importantly, if you\u2019ve made an account on that website, I can offer to buy your data - whatever they can share under their privacy policy: your name, activity, conversations with AI\u2026\nPretty soon I\u2019d know more about you than your friends do - perhaps more than you know yourself.\n\u201cSo what?\u201d - you say.\n\n\u201cI have nothing to hide. And I prefer my ads to be relevant\u2026 sometimes they show me exactly what I need! And the data is anonymised anyway\u2026\u201d\n\nSee, the thing is, it\u2019s not about you at all. It\u2019s not really about the ads anymore either. Nobody cares about you. And if the police or your government happen to care, I\u2019ll gladly take their money too.\nI look at all this data and I don\u2019t see people. I see patterns. Patterns emerging out of patterns. A living, digital fractal state of the economy, society and human psyche. The crystal ball of the 21st century and it\u2019s made of silicon!  That\u2019s the product.\nAnd to the highest bidder it goes!\nWhat does that make you then? A gear? An ox? A volunteer?\n\nFingerprints are the new cookies\nRemember the big fuss about third-party cookies? It was so big that the EU had already rolled out one of its greatest inventions - consent banners.\nIf EU ships faster than tech companies, that can only mean the tech companies are sitting on their hands. And one of those tech companies happens to hold two-thirds of the browser market.\nWhat was the play?\nLet\u2019s give it up for Google - the biggest ad company on Earth!\nACT I. PRESSURE - \u201cPRIVACY IS PARAMOUNT TO US, IN EVERYTHING WE DO.\u201d\nIt\u2019s 2019 and the cookies are still hot. It\u2019s become bad PR and Safari and Firefox already block them.\nA year later Google pledges: we will destroy cookies!! And establish a new, privacy-first reign.\nACT II. DISTRACTION - \u201cINSTEAD OF DEPRECATING THIRD-PARTY COOKIES, WE WOULD INTRODUCE A NEW EXPERIENCE\u201d\n5 years later: people are now preoccupied with far greater worries than cookies, and the solutions Google has developed (Privacy Sandbox) kinda suck and have raised antitrust concerns so nobody uses them.\n\u201cYou know what, let\u2019s just keep the cookies. We\u2019ll mask your IP address* though!\u201d (* but only when incognito while authenticated) (** in the end they didn\u2019t even deliver on that)\nACT III. ACCELERATION - YOU CAN NOW USE DEVICE FINGERPRINTING IN OUR AD PRODUCTS\nNow there\u2019s a better way to know who\u2019s who!\nHow does fingerprinting work?\nNice, let\u2019s nerd out properly.\nYou visit a website. Your browser sends a request to the server and the server returns code for the browser to run.\nThe request already reveals information about you; what browser you use, the language it\u2019s in, the OS that runs it and your IP address, which the server needs to send you the response. That often reveals your location.\nThen the code runs.\nSee, we\u2019ve made a lot of civilizational progress in making browsing safe. Long gone are the days when getting a virus just by visiting a website was a daily concern. The thing is, the definition of safety varies depending on who you ask. The broad consensus ends at isolation: a website\u2019s code can\u2019t see the data stored by other websites, and it can\u2019t see your files or other applications without permission. Chrome and Edge stop here. Then you have Safari (especially on iOS/macOS 26+) and Firefox extending that definition to privacy, but they still don\u2019t fully protect you from fingerprinting. Brave and Tor are the leading privacy-first browsers, with up and coming Mullvad Browser (Mullvad being, in my opinion, one of the best VPN providers out there).\nThe code runs on your hardware, which can be measured in ways that produce consistent and unique readings. There\u2019s not much that can be done about this really, so there\u2019s only two established solutions:\n\nfeed a little bit of noise here and there. It\u2019s called farbling and that\u2019s what Brave does to make your fingerprint inconsistent.\nmake everything look the same, always, so there\u2019s no telling browser users apart. Tor and Mullvad adopt this approach.\n\nOk, let\u2019s create a fingerprint\nSo there are two sources for data that can make up your fingerprint; the network request and the code environment.\nWhen you look at network, the data is generally either fragile or generic:\n\nthe IP address; in a \u2018happy path\u2019 where one person always uses the same IP address, it might be the only data you need. But commonly people do a lot of browsing on mobile networks, they share the WiFi with others, they use VPNs or their home network\u2019s IP address is rotated by the ISP. It\u2019s fragile as such.\nheaders like User-Agent or Accept-Language; reveal your browser, OS, versions and the language set.\n\nWhen you can execute code on the device, you have ways to measure its hardware qualities (without any permission prompts!) and these are surprisingly stable:\n\nGPU; behaviour, vendor, driver\nCPU; behaviour, vendor, number of threads\nmemory size\ndisplay data; resolution, pixel ratio, refresh rate\naudio processing\ndevice model\n\nAnd on the software level; installed fonts, extensions, system info\u2026\nMillions of devices use the latest Chrome, there are millions of Macs with the M4 chip and there are millions of browsers in French.\nBut when you look at devices that run the latest Chrome in French on an M4, that number now drops significantly. Add to it hardware measurements and it gets so low it becomes practically unique.\nThe fingerprint doesn\u2019t need to be truly, globally unique - it just needs to be unique enough to tell people apart in your sample size.\nA ZIP code (inferred from IP), a birth date (you\u2019ve given away on some platform) and sex (you fill it in everywhere) together are enough to uniquely identify over 60% of Americans.\nYou can always add another variable to decrease the potential pool of candidates.\nInformation Entropy\nHave you ever played Akinator? You think of a character, a genie asks you some twenty questions, and somehow it knows. That\u2019s fingerprinting in a nutshell, except your browser answers the questions for you. Once you understand information entropy, Akinator\u2019s magic turns into a simple trick.\nLet\u2019s simplify with that game where you have to guess the character on a board through questions like \u201cIs my character a man?\u201d. If I say \u201cyes\u201d, and half of the characters on your board are men, you\u2019re now considering only half of the total candidates. Now we can say that my answer gave you log\u2082(100 / 50) = log\u2082(2) = 1 bit of information, because it cut the pool of candidates in half.\nThe bits you get from one answer are called its surprisal: the rarer the answer, the more it tells you.\n\na trait shared by 1 in 2 people is worth 1 bit (is a man),\n1 in 8 is worth 3 bits (has a mustache),\nand 1 in 128 is worth 7 bits (has one eye).\n\nSurprisal quantifies the value of the answer, and entropy quantifies the value of the question. If 1 person in 128 is one-eyed, then asking about it will yield \u2018no\u2019 127 times in 128.\n\n\n\nAnswer\nProbability\nSurprisal\nEntropy contribution\n\n\n\n\nYes\n1/128\nlog\u2082(128 / 1) = 7 bits\n1/128 x 7 = ~0.055\n\n\nNo\n127/128\nlog\u2082(128 / 127) = ~0.0113 bits\n127/128 x 0.0113 = ~0.011\n\n\n\nSumming up the contribution of each possible answer, the question itself is worth ~0.066 bits of entropy - that\u2019s the average amount of bits you gain from an answer.\nWhen we combine traits that are independent we simply add up their bits or multiply the ratios, so a man with a mustache and one eye would mean 11 bits, or 1 in 2048. Alas, as Thomas Bayes would have you know, nothing is ever so simple in practice. A mustache is already a strong indicator of a man, and a man is probably more likely to have one eye. The traits are not independent so the bits don\u2019t really add up.\nSome interesting applications of this type of reasoning:\n\nIn medical diagnostics: A positive result from a 99% accurate test for a disease known to affect 0.01% of the population is about 100 times more likely to be wrong than you are to have the disease. You need more evidence!\nIn cryptography: A password made out of four random words is as strong as eight random keyboard characters (but much easier to remember!)\n\nIn forensic science: singling out one person in a city of a million takes about 20 bits. A witness description that matches 1 person in 1,000 provides only 10 bits, which still leaves a thousand possible suspects.\n\nSo what can I do about it?\nTest your browser:\n\ncoveryourtracks.eff.org shows you how unique your fingerprint is, with entropy for each measured data point.\n\nIf you\u2019re using Chrome you\u2019re basically walking around with an ID on your forehead.\nSafari and Firefox offer some level of protection, but you\u2019re still identifiable by advanced trackers.\nBrave, Tor and Mullvad Browser are the only major browsers at the moment that implement advanced protections against fingerprinting.\nIf you don\u2019t feel like switching browsers, I get it. I am a big Arc fan myself and unfortunately it\u2019s discontinued and will never have any privacy features. There are extensions like JShelter - they disrupt fingerprinting scripts by intercepting browser API calls. But they also break some websites. Same problem applies to Firefox\u2019s Resist Fingerprinting feature.\nThe ironic truth is, privacy extensions make you more unique, since fewer people have them. So a smart tracker could detect that, ignore the signals disrupted by the extension and focus on the ones that are not.\nNo extension can be as effective as engine-level protection built into the browser. So if you don\u2019t want to be tracked, you gotta commit.\nmethods used on this page\nI\u2019m simply creating a hash out of a few measurements of your device. Any of these change and the hash is now different. Professional applications are much more complex than this and are able to maintain identification line when single variables change.\n\n\nOfflineAudioContext\nRenders a short tone through a compressor without playing it; tiny float differences in the result depend on your browser\u2019s audio engine and your CPU.\nconst off = new OfflineAudioContext(1, 5000, 44100);\n// \u2026 a 1 kHz triangle wave into a dynamics compressor \u2026\nconst data = (await Promise.race([off.startRendering(), timeout])).getChannelData(0);\nlet sum = 0;\nfor (let i = 4500; i < 5000; i++) sum += Math.abs(data[i]);\nreturn sum.toFixed(3);\n\n\n\nWebGL\nReads your GPU\u2019s vendor and model (without version numbers), what the GPU and its driver support, and the pixels of a small rendered triangle.\nconst gl = document.createElement('canvas').getContext('webgl');\nconst dbg = gl.getExtension('WEBGL_debug_renderer_info');\nreturn gpuName(gl.getParameter(dbg ? dbg.UNMASKED_RENDERER_WEBGL : gl.RENDERER) || '');\n// \"ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)\" -> \"apple m4\"\n// \u2026\nreturn fnv1a(new TextEncoder().encode([...(gl.getSupportedExtensions() || []).sort(), ...limits, ...precision].join('|')));\n// \u2026\ngl.drawArrays(gl.TRIANGLES, 0, 3);\ngl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, px);\n\n\n\ncanvas\nDraws text in a few fonts, emoji and a gradient, then reads the pixels back; anti-aliasing and font rendering depend on your OS, GPU and fonts.\nctx.font = '15px \"Times New Roman\", serif';\nctx.fillText('Sphinx of black quartz \ud83e\udd8a', 4, 22);\n// \u2026\nconst data = ctx.getImageData(0, 0, 240, 60).data;\n\n\n\nIntl\nYour time zone and your date and number settings; a VPN changes your IP location, but not your time zone.\nconst date = Intl.DateTimeFormat().resolvedOptions();\n// \u2026\nreturn [date.timeZone, date.locale, date.calendar, date.numberingSystem, hourCycle, (1234567.891).toLocaleString()].join('/');\n\n\n\nnavigator\nYour number of CPU cores, your memory size (Chrome only) and your browser\u2019s language.\nreturn [navigator.hardwareConcurrency, navigator.deviceMemory, navigator.language].join('/');\n\n\n\ncrypto.subtle\nHashes all the values with SHA-256, and the hash picks a trait and an animal for your nickname.\nconst digest = await crypto.subtle.digest('SHA-256', bytes);\n// \u2026\nnickname: stranger || `${pick(TRAITS, hex, 0)} ${pick(ANIMALS, hex, 8)}`,"
                ],
                "output": "readability",
                "pwd": "/data/archive/1791799470.531906",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-12T10:08:23.781969+00:00",
                "status": "succeeded"
            }
        ],
        "screenshot": [],
        "singlefile": [],
        "title": [
            {
                "cmd": [
                    "curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--max-time",
                    "120",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) curl/curl 8.14.1 (x86_64-pc-linux-gnu)",
                    "https://royfish.dev/fingerprints-are-the-new-cookies"
                ],
                "cmd_version": "curl 8.14.1 (x86_64-pc-linux-gnu)",
                "end_ts": "2026-10-12T10:08:23.774542+00:00",
                "index_texts": null,
                "output": "Fingerprints are the new cookies",
                "pwd": "/data/archive/1791799470.531906",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-12T10:08:23.760575+00:00",
                "status": "succeeded"
            }
        ],
        "wget": [
            {
                "cmd": [
                    "wget",
                    "--no-verbose",
                    "--adjust-extension",
                    "--convert-links",
                    "--force-directories",
                    "--span-hosts",
                    "--no-parent",
                    "-e",
                    "robots=off",
                    "--reject=js,mjs,woff,woff2,ttf,otf,eot,mp4,m4v,mov,webm,ogv,mkv,avi,flv",
                    "--timeout=120",
                    "--restrict-file-names=windows",
                    "--page-requisites",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/0.7.4 (+https://github.com/ArchiveBox/ArchiveBox/) wget/GNU Wget 1.21.3",
                    "--compression=auto",
                    "--timestamping",
                    "https://royfish.dev/fingerprints-are-the-new-cookies"
                ],
                "cmd_version": "GNU Wget 1.21.3",
                "end_ts": "2026-10-12T10:08:23.751151+00:00",
                "index_texts": null,
                "output": "royfish.dev/fingerprints-are-the-new-cookies.html",
                "pwd": "/data/archive/1791799470.531906",
                "schema": "ArchiveResult",
                "start_ts": "2026-10-12T10:08:22.653834+00:00",
                "status": "succeeded"
            }
        ]
    },
    "icons": null,
    "is_archived": true,
    "is_static": false,
    "latest": {
        "archive_org": null,
        "dom": null,
        "favicon": "favicon.ico",
        "git": null,
        "media": null,
        "pdf": null,
        "screenshot": null,
        "singlefile": null,
        "title": "Fingerprints are the new cookies",
        "warc": null,
        "wget": "royfish.dev/fingerprints-are-the-new-cookies.html"
    },
    "link_dir": "/data/archive/1791799470.531906",
    "newest_archive_date": "2026-10-12T10:08:25.481387+00:00",
    "num_failures": 0,
    "num_outputs": 6,
    "oldest_archive_date": "2026-10-12T10:08:21.459702+00:00",
    "path": "/fingerprints-are-the-new-cookies",
    "schema": "Link",
    "scheme": "https",
    "snapshot_id": "0f1c3328-cbe7-40f5-bca1-248155019cf7",
    "sources": [
        "/data/sources/1791799470-import.txt"
    ],
    "tags": null,
    "tags_str": "",
    "timestamp": "1791799470.531906",
    "title": "Fingerprints are the new cookies",
    "updated": "2026-10-12T10:08:21.459003+00:00",
    "updated_date": "2026-10-12 10:08",
    "url": "https://royfish.dev/fingerprints-are-the-new-cookies"
}