Which TLS Fingerprint Should You Use to Identify a Client?
Short answer: use JA4. Set a JA3 fingerprint or JA4 side by side and JA4 wins on stability, readability and protocol coverage — it survives Chrome’s per-connection extension shuffling, states its TLS version and ALPN in plaintext, and covers QUIC. JA3 keeps two jobs: historical log evidence and a migration column. Neither value identifies a person, so treat each as one signal among several.
📌 TL;DR Executive Summary
- Core Takeaway: JA4, launched by FoxIO in September 2023, sorts cipher suites and extensions before hashing, so a client that randomizes extension order still produces one stable value. JA3, published by Salesforce in 2017, hashes the same fields in the order they were sent.
- Key Risk/Challenge: A JA4 match proves two handshakes reduced to the same value — not that the same software, device or operator sent them. Both values are absent after TLS session resumption and for non-TLS traffic.
- Recommended Solution: Write all new rules against JA4, keep JA3 as a comparison column while you migrate, and treat the TLS layer as one signal among several — including per-profile browser isolation when you manage several authorised accounts.
What a TLS Fingerprint Measures — and What It Doesn’t
A TLS fingerprint is a hash of the ClientHello, the first packet a client sends when it opens a secure connection. That packet has to describe what the client supports before the server agrees on anything: TLS versions, cipher suites, extensions, elliptic curves, signature algorithms and the ALPN list. With over 90% of web traffic now carried over TLS, this handshake metadata is often more useful than an IP address.
Two limits follow from that design. The fingerprint is absent for unencrypted HTTP and after a TLS session resumption, because the fields being hashed never appear on the wire. And it describes a software stack rather than a person: one browser build produces one value for millions of users. For the wider picture, see TLS fingerprinting explained.
How JA3 Builds Its Hash, and Why Chrome 110 Broke It
Salesforce published JA3 in 2017. It concatenates five ordered ClientHello fields into a single string and hashes that string with MD5, producing 32 hex characters. Order is both the design and the defect: change the sequence of extensions and the same browser produces a different value.
In early 2023, Chrome 110 started shuffling TLS extension order per connection. One Chrome install then produced many JA3 hashes, so a rule reading “this value means Chrome” became a rule reading “this value means one of hundreds of Chrome sightings”. Cloudflare lists three reasons JA3 degraded: extension randomization, inconsistent results across tools and databases, and its scope limit — TLS over TCP only, with no QUIC support.
Worth correcting a common myth: GREASE did not break JA3. GREASE placeholder values were already stripped from the computation before JA4 made the rule explicit, and JA4 excludes them from its counts and hashes. The extension shuffle is the cause. If you still maintain JA3 detectors, how JA3 fingerprinting works walks through the original field list.
How JA4 Is Structured, Field by Field
JA4 launched in September 2023 as part of FoxIO’s JA4+ suite, with core JA4 licensed under BSD 3-Clause. The output is a 36-character string in three parts: a metadata header, a truncated SHA-256 of the sorted cipher suites, and a truncated SHA-256 of the sorted extensions plus signature algorithms. Each hash section is 12 hex characters.
Take the sample t13d1516h2_8daaf6152771_02713d6af862, listed for Chrome on Linux. The header answers most triage questions on its own:
| Header field | Value | What it means |
|---|---|---|
| t | Transport | TLS over TCP. QUIC uses q, DTLS uses d |
| 13 | Version | TLS 1.3 |
| d | SNI | Domain name present. i means absent |
| 15 | Cipher count | 15 cipher suites offered |
| 16 | Extension count | 16 extensions offered |
| h2 | ALPN | HTTP/2 in the offer |
Because both hashes run over sorted lists, a client that shuffles extensions between connections still produces the same JA4. Signature algorithms keep their original order inside section c, so a little ordering evidence survives. The trade-off is real: JA4 deliberately drops the extension-order detail JA3 captured, which is why some analysts keep both columns during a transition. For what each section implies in practice, see JA4 fingerprint detection.
Parsing the string inside a log pipeline takes a few lines of standard-library Python:
def parse_ja4(value: str) -> dict:
"""Split a JA4 string such as t13d1516h2_8daaf6152771_02713d6af862."""
header, cipher_hash, ext_hash = value.split("_")
return {
"transport": header[0], # t = TCP, q = QUIC, d = DTLS
"tls_version": header[1:3], # 13 = TLS 1.3, 12 = TLS 1.2
"sni": header[3], # d = domain present, i = absent
"cipher_count": int(header[4:6]),
"extension_count": int(header[6:8]),
"alpn": header[8:],
"cipher_hash": cipher_hash, # 12 hex chars, sorted cipher suites
"extension_hash": ext_hash, # 12 hex chars, sorted extensions
}
parsed = parse_ja4("t13d1516h2_8daaf6152771_02713d6af862")
print(parsed["tls_version"], parsed["alpn"]) # 13 h2
The family has grown well past the client method. FoxIO’s JA4 repository ships JA4S, JA4H, JA4L/LS, JA4X, JA4SSH, JA4T/TS/TScan, JA4D/D6 and JA4N, plus JA4Scan-TLS and JA4Scan-QUIC scanners, Rust and Python implementations, a Wireshark plugin and an nginx module for computing values at the server.
JA3 vs JA4, Feature by Feature
| Feature | JA3 | JA4 |
|---|---|---|
| Released | 2017, Salesforce | September 2023, FoxIO |
| Hash | MD5 over five ordered fields | Truncated SHA-256 over sorted lists |
| Output length | 32 hex characters | 36-character a_b_c string |
| Extension order | Hashed as sent, so shuffling changes the value | Sorted, so shuffling does not change the value |
| Readable metadata | Needs a lookup database for protocol and version | Plaintext header states transport, version, SNI flag, counts and ALPN |
| QUIC and DTLS | Not covered | Covered via the q and d prefixes |
| After session resumption | Absent | Absent |
| Licence | Public specification | BSD 3-Clause for core JA4; FoxIO License 1.1 for other JA4+ methods |
The two methods are six years apart. Log a JA3 fingerprint or JA4 value for the same handshake and that gap explains most of the differences: JA3 was designed when extension order was stable; JA4 was designed after Chrome proved it would not stay that way.
Where Both Values Go Quiet: Resumption, ECH and False Confidence
TLS session resumption is the quiet killer. When a client resumes an earlier session, the full ClientHello with its extension list never gets sent, so no fingerprint is computed and your pipeline records nothing. Connections that resume aggressively look like gaps in coverage rather than like clients. Non-TLS traffic behaves the same way: there is no handshake to hash.
Encrypted Client Hello changes the picture differently. It splits the handshake into a plaintext outer hello carrying a generic SNI and an encrypted inner hello carrying the real target. Commentary in 2026 puts ECH at the top of the list of pressures on metadata-level fingerprinting and points analysts toward behavioural signals. JA4 is still computed under ECH, but it describes the outer hello.
Signals, Adoption and What Vendors Actually Ship
Cloudflare adopted JA4 for Bot Management in 2023 and exposes JA4 Signals — per-fingerprint aggregates observed globally over the last hour, including h2h3_ratio_1h, browser_ratio_1h, uas_rank_1h and ips_quantile_1h. Signals are not the same thing as JA4+. A fingerprint identifies one handshake; a signal describes the population of traffic behind that value, which is what makes it usable in rule logic alongside Workers AI. Cloudflare’s JA4 write-up is the primary reference.
Adoption kept moving. Public tables list Cloudflare, DataDome and Akamai with JA4 in default rule sets by 2025, Akamai Bot Manager and Imperva Bot Manager following during 2025, and PerimeterX (Human Security) in 2024. Those tables are vendor-reported rather than independently audited, so read the dates as indicative. FoxIO’s fingerprint database at ja4db.com maps values to applications and is still under active development — expect gaps.
Licensing matters if you intend to build a product on top. Core JA4 is BSD 3-Clause; other JA4+ methods use the FoxIO License 1.1, which requires an arrangement for commercial monetization. Internal security logging is a different case from shipping a paid service on the same code.
What Each Option Costs
| Option | Cost | Notes |
|---|---|---|
| JA3 | Openly published specification (2017) | You pay in engineering time each time the value drifts |
| JA4 core | BSD 3-Clause licence | Rust and Python implementations, Wireshark plugin, nginx module |
| Other JA4+ methods | FoxIO License 1.1 | Commercial monetization needs an arrangement with FoxIO |
| Cloudflare Bot Management | Price not published | Exposes JA3, JA4 and JA4 Signals to customers |
| Send.win Pro | $19/mo, or $83.88/yr ($6.99/mo) | 150 profiles, 5 GB/month proxy bandwidth, 6 seats, up to 50 profiles open at once |
| Send.win Team | $49/mo, or $251.88/yr ($20.99/mo) | 500 profiles, 20 GB/month, 16 seats, page blocking in shared sessions |
| Send.win add-ons | $6/GB proxy bandwidth, $0.05/extra profile | 7-day money-back guarantee on the first card purchase |
If your goal is purely TLS fingerprint logging, you do not need a profile manager at all — FoxIO’s tooling with tshark 4.0.6 or later covers it. The Sendwin Browser desktop app itself needs a paid plan, and there is no trial of it; the cloud demo is how you look at the product first. Send.win paid plans start at $19/mo with a 7-day money-back guarantee on the first card purchase, and the free cloud demo needs no install.
Honest Pros and Cons
JA3
- Strengths: trivial to compute, present in years of existing logs, supported by nearly every parser and SIEM, and stable for clients that do not shuffle extension order.
- Weaknesses: unstable against modern Chrome, inconsistent across tools and databases, no QUIC support, and protocol or TLS version only visible through a lookup table.
How Send.win Helps With Ja3 Fingerprint Or Ja4
Send.win is a browser profile manager for professionals and teams: every account gets its own isolated browser profile.
- Isolated profiles – separate cookies, storage and sessions per profile
- Fingerprint protection – each profile keeps its own consistent browser fingerprint, so profiles never share one browser identity
- Desktop app + cloud browser – native app for Windows, macOS and Linux, or run profiles in the cloud with no install
- Residential proxies included – on Pro and Team, with timezone and locale matched to the proxy
- Team sharing – share a signed-in profile with a teammate without sharing the password
Try the free cloud demo — no install — or download the desktop app. Paid plans start at $19/month, and your first card purchase is covered by a 7-day money-back guarantee (see pricing).
JA4
- Strengths: stable under extension randomization, self-describing header, QUIC and DTLS coverage, Rust, Python and Wireshark implementations from one project, and default-rule-set adoption at several bot management vendors.
- Weaknesses: discards extension-order evidence, needs a tooling upgrade, depends on a fingerprint database that is still filling in, and carries a split licence that affects commercial builds.
Where Send.win Fits — the Browser Layer, Not the TLS Layer
JA3 and JA4 are computed on the server from the handshake. Send.win sits on the other side of the connection: it is a browser profile manager where each isolated profile keeps its own cookies, storage, sessions, fingerprint settings and proxy. The fingerprints it protects are the browser-level ones inside the engine — canvas, WebGL, audio, fonts, hardware — not the TLS handshake. It does not compute, store or rewrite a JA3 fingerprint or JA4 value.
That distinction matters when you choose a tool. If the problem is that two client accounts share one cookie jar, one storage partition and one exit IP, a better TLS tool will not fix it. One profile per client, each with its own proxy, timezone and locale following the exit IP, is the fix — and it applies to accounts you own or are authorised to manage. Send.win runs as the Sendwin Browser desktop app on Windows 10/11, macOS 12+ and Linux, or as a cloud browser on an EU server in Helsinki from any device. There is no API, SDK, headless mode or Selenium/Puppeteer/Playwright integration, so if you need scripted traffic, this is not that product.
Which Should You Pick?
You are building detection or logging now
Go JA4 first, with a JA3 column kept for a fixed comparison window so old rules can be checked against new traffic. Do not rewrite historical data; just stop writing new JA3-only rules.
You maintain an old SIEM with JA3 dashboards
Add JA4 as a new field, run both in parallel, and retire the JA3 panels once query volume drops. Migrating dashboards overnight produces silent gaps that look like traffic disappearing.
You need visibility into QUIC traffic
JA4 is the only option. JA3 has no QUIC scope, so a JA3-only stack cannot see those connections at all — QUIC strings start with q and share the same three-part structure.
You manage several client accounts from one machine
Choosing a JA3 fingerprint or JA4 rule set is server-side work, and it is not your bottleneck here: cookie and session isolation is. That is the case for a browser profile manager — one profile per client, each with its own proxy and fingerprint settings. Our guide to browser fingerprinting and isolation covers how the layers fit together.
🏆 Send.win Verdict
On the JA3 fingerprint or JA4 question, JA4 is the answer: stable under extension shuffling, readable without a lookup, and covering QUIC, while JA3 stays useful as historical evidence during a migration. Send.win does not compete with either. It handles the adjacent layer — keeping each client account’s cookies, storage, sessions, fingerprint settings and proxy in its own isolated profile on Windows, macOS or Linux, or in a cloud browser running from Helsinki. If your JA4 work is about understanding traffic and your day job is running many authorised accounts, you need both layers, not one.
See Send.win plans — paid plans start at $19/mo with a 7-day money-back guarantee on the first card purchase, and the free cloud demo needs no install.
Frequently Asked Questions
Is JA4 more reliable than JA3 for identifying clients?
Yes, for modern traffic. JA4 hashes sorted cipher suites and extensions, so per-connection shuffling no longer changes the value, and its plaintext header gives you transport, TLS version and ALPN without a lookup. JA3 stays reliable only for clients that do not randomize extension order.
Why did Chrome 110 break JA3?
Chrome 110 started shuffling TLS extension order on every connection in early 2023. Because JA3 hashes the fields in the order they arrive, one browser install began producing many different hashes. GREASE is often blamed, but GREASE values were already excluded from the computation.
What does t13d1516h2 mean in a JA4 string?
It is the metadata header: t means TLS over TCP, 13 means TLS 1.3, d means an SNI domain is present, 15 is the cipher suite count, 16 is the extension count and h2 is the ALPN value. Counts and hashes exclude GREASE, and QUIC strings start with q instead of t.
Does Cloudflare still use JA3, or has it moved to JA4?
Cloudflare adopted JA4 for Bot Management in 2023 and now ships JA4 Signals — per-fingerprint aggregates such as h2h3_ratio_1h and browser_ratio_1h observed over the last hour. JA3 values are still computed and exposed, which helps while existing rules are migrated.
Can a JA4 match prove which software made a request?
No. A match means two handshakes reduced to the same value, and that can happen across different devices, versions or operators. Use it as one signal alongside IP reputation, request timing, account history and HTTP-level behaviour.
What happens to JA4 under Encrypted Client Hello?
ECH splits the handshake into a plaintext outer hello with a generic SNI and an encrypted inner hello with the real target. A JA4 is still computed, but it describes the outer hello, which is why 2026 commentary pushes weight toward behavioural signals.
Should I keep JA3 logs during the migration?
Keep them as a comparison column for a fixed window, not as a primary rule input. Historical JA3 data still has forensic value for older case notes, so archive it rather than deleting it.
How do I compute JA4 from a pcap myself?
Install FoxIO’s Wireshark plugin — ja4.so.linux, ja4.so.macos or ja4.dll — with tshark 4.0.6 or later, then read the JA4 field from each TLS handshake in the capture. The repository also ships Rust and Python implementations if you want the value inside your own pipeline.