Compare / versions
Chrome 156 (beta) vs Chrome 154
Two majors ahead of stable, measured on the fleet: what 155 and 156 add and remove, which of it a page can already detect in the beta, what is identical on the wire, and what you can set before 156 ships.
Chrome 154 has been stable since 22 September 2026. The fleet's channel: "beta" currently launches Chrome 156 (156.0.8078.4, in beta since 30 September), with 157 on dev; 155 is between them and already behind the beta. So this page compares the browser most of your visitors run today with the one they will run in a few weeks, two release notes apart. Below: what Google shipped in 155 and 156, what we could measure as different from inside a page and on the wire, which of those differences matter for detection, and what can be configured — by you in the launch, by us on the fleet, or by nobody.
What 155 added
From the Chrome 155 beta post. Items marked measured show up in the probe table; "not exposed" means our probe found the API or property absent in the 156 beta build — behind a flag, in an origin trial, or shipped in a form we didn't probe.
- CSS:
symbols()for inline counter styles (measured: present in 156, absent in 154);margin-trim(measured: present in 156);text-decoration-skip-spaces(not exposed); thecornershorthands that setborder-radiusandcorner-shapetogether (not exposed). - JavaScript: failed module loads can be retried with another
import(); Import Text —import … with { type: "text" }. - Web APIs: Additional Windowing Controls (
window.maximize(),minimize(),restore(),setResizable(), gated by thewindow-managementpermission — not exposed to a plain page); post-quantum algorithms in WebCrypto (ML-KEM, ML-DSA, X-Wing) plus ChaCha20-Poly1305; Digital Credentials issuance to mobile wallets; JPEG XL decoding (image/jxl); themedia-playback-while-not-visiblepermission policy (measured: present in 156); linear canvas colour spacessrgb-linearanddisplay-p3-linear(not exposed); new HTML insertion and streaming methods such asstreamAppendHTML()(not exposed); custom request headers andresponseHeadersonWebTransport.
What 156 adds
From the Chrome 156 release notes.
- CSS:
random()for random numeric values (measured: present in 156);scroll-snap-type: pair(measured: present in 156); a pseudo-class for the element that started a navigation;text-decoration-inset(listed again; not exposed in this beta); optional descriptors in@property; single-axis scroll containers (overflow: scroll clip). - Network: compression-dictionary transport updates (
rel=compression-dictionary— supported in both builds);WebTransportrequest headers andresponseHeaders; module-load retry. - Storage and security: IndexedDB rewritten on SQLite for new stores; Local Network Access restrictions — requests to local and loopback addresses need the new
local-network/loopback-networkpermissions. - Graphics and media: WGSL
@builtin(frag_depth)withless/greatermodifiers; a WebRTC diagnostic-logging API for authorised apps. - Removal: the
<fencedframe>element andwindow.fenceare stubbed, with phased removal starting in 157 (measured: still present in both 154 and 156).
What is identical
Everything on the wire: JA4, peetprint, the Akamai HTTP/2 fingerprint and the header order are the same in 156 and 154 (the JA3 hash differs between any two Chrome runs because of GREASE — never use it to compare builds). Canvas output, the WebGL strings, screen and window metrics, plugins, permissions and navigator.webdriver (false on the fleet) are identical too, and a plain-http:// URL loads directly in both (Playwright disables Chromium's HTTPS upgrades, see Chrome 154 vs 153). Timings differ only by proxy luck.
What affects detection
- The version is declared in four places and they must agree: the reduced user agent (
Chrome/156.0.0.0), thesec-ch-uaheader,navigator.userAgentData.brandsand the high-entropyfullVersionList. 156 also moves the GREASE token first and changes it (Not:A-Brand;8ahead ofChromium;156andGoogle Chrome;156; in 154 it wasNot A(Brand;99last). Spoofing the UA string alone leaves the client hints on the old version. - Five cheap feature probes separate 156 from 154:
CSS.supports("margin-trim", …),CSS.supports("list-style-type", "symbols(…)"),CSS.supports("width", "random(…)"),CSS.supports("scroll-snap-type", "pair")anddocument.featurePolicy.features()containingmedia-playback-while-not-visible. A "Chrome 156" user agent on a 154 engine fails all five; a 156 engine with a "Chrome 154" user agent passes them — equally suspicious. - A beta user agent is itself a signal. Most real visitors run stable; a 156 UA while 154 is current puts you in a small cohort. Use
channel: "beta"to test what breaks before it ships, not to blend in. - Local Network Access permissions change what a page may fetch from private addresses; on the fleet the browser's "local network" is ours and unreachable to sessions, so nothing changes for you, but scripts that probe
permissions.query({ name: "local-network" })get a new answer in 156. - Nothing changed at the TLS or HTTP/2 layer, so anti-bot systems keyed on Chrome 154's JA4 keep matching 156; only JavaScript-level version checks move. Post-quantum WebCrypto algorithms are a future async probe (
crypto.subtlewith ML-KEM), not something a server sees in the handshake.
Configurable — by you, by us, by nobody
| Item | Who controls it | How |
|---|---|---|
| Which major runs | You | channel: "beta" for 156 today, "dev" for 157, nothing for stable (154). When 156 goes stable, 154 becomes a pinned previous major for a while (version: "154"). See Chrome. |
Features that exist but aren't exposed yet (corner, streamAppendHTML, windowing controls, linear canvas) | cdpfleet (launch flags) | Chromium --enable-features / --enable-blink-features switches are set by the fleet, not by launch options. Tell us if you need one for testing. |
| Local Network Access permissions | Not relevant on the fleet | The browser runs on our servers; sessions can't reach our local network either way. |
Ask before HTTP (the http:// warning) | Playwright / cdpfleet | Off for fleet sessions through Playwright's --disable-features=…HttpsUpgrades… (measured: http:// loaded directly in both builds). |
<fencedframe> / window.fence | Nobody | Stubbed in 156, removed from 157 on; still present in both builds we measured. |
Privacy Sandbox APIs (requestStorageAccessFor, Shared Storage, Attribution Reporting) | Nobody | Already gone in 154 and 156 (document.browsingTopics and joinAdInterestGroup are still present in both). |
| Fingerprint surface (UA, client hints, canvas, WebGL, screen) | You, per context | Unchanged between the versions; newContext options as before, or Camoufox when the identity itself must change. |
Measured on the fleet (2026-10-05)
One headful launch of each on the production fleet through the same proxy, probed from inside a page and via tls.peet.ws. Timings are a single sample; core counts are the node's.
Launch and cost
Single run; timings depend on the proxy and on fleet load.
| Chrome 156 beta | Chrome 154 | |
|---|---|---|
| Launch body | {"headless":false,"channel":"beta"} | {"headless":false} |
| Threads used | 2 (linux_headful) | 2 (linux_headful) |
| Browser version | 156.0.8078.4 | 154.0.8037.97 |
| Launch request → browser ready | 0.7 s | 0.7 s |
| Playwright connect | 0.0 s | 0.1 s |
| Load example.com | 0.5 s | 1.0 s |
| Load tls.peet.ws/api/all | 2.4 s | 2.5 s |
What the network sees
From tls.peet.ws/api/all, requested by the browser itself. JA3 hashes change between runs of the same build (GREASE), so compare JA4 and the HTTP/2 fingerprint.
| Chrome 156 beta | Chrome 154 | |
|---|---|---|
| HTTP version | h2 | h2 |
| JA4 | t13d1517h2_8daaf6152771_cb7bf5808d99 | t13d1517h2_8daaf6152771_cb7bf5808d99 |
| Peetprint hash | fc97c1cdfb1409c9a9326c1b726d1dee | fc97c1cdfb1409c9a9326c1b726d1dee |
| Akamai HTTP/2 fingerprint | 1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p | 1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p |
| Cipher suites / extensions | 16 / 19 | 16 / 19 |
| Header order (first 12) | method, authority, scheme, path, sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform, upgrade-insecure-requests, user-agent, accept, sec-fetch-site, sec-fetch-mode | method, authority, scheme, path, sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform, upgrade-insecure-requests, user-agent, accept, sec-fetch-site, sec-fetch-mode |
What page scripts see
Read with page.evaluate on example.com. Cores and memory are the server's and vary between fleet nodes.
| Chrome 156 beta | Chrome 154 | |
|---|---|---|
| navigator.userAgent | Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.0.0 Safari/537.36 | Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 |
| UA-CH brands | Not:A-Brand 8 · Chromium 156 · Google Chrome 156 | Chromium 154 · Google Chrome 154 · Not A(Brand 99 |
| UA-CH full version list | Not:A-Brand 8.0.0.0 · Chromium 156.0.8078.4 · Google Chrome 156.0.8078.4 | Chromium 154.0.8037.97 · Google Chrome 154.0.8037.97 · Not A(Brand 99.0.0.0 |
| navigator.platform / vendor | Linux x86_64 / Google Inc. | Linux x86_64 / Google Inc. |
| Languages | en-US, en | en-US, en |
| Timezone / locale | UTC / en-US | UTC / en-US |
| Screen (w×h×availW×availH×depth) | 1280x720x1280x720x24 | 1280x720x1280x720x24 |
| Window outer / inner / DPR | 1288x805 / 1280x720 / 1 | 1288x805 / 1280x720 / 1 |
| hardwareConcurrency / deviceMemory | 48 / 32 | 64 / 32 |
| WebGL vendor | Google Inc. (Google) | Google Inc. (Google) |
| WebGL renderer | ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver) | ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver) |
| WebGL version | WebGL 2.0 (OpenGL ES 3.0 Chromium) | WebGL 2.0 (OpenGL ES 3.0 Chromium) |
| WebGPU (navigator.gpu) | yes | yes |
| Canvas hash | f5a94624 | f5a94624 |
| navigator.webdriver | no | no |
| window.chrome / navigator.connection | yes / yes | yes / yes |
| Plugins / PDF viewer | 5 / yes | 5 / yes |
| Notification.permission / permissions.query | default / prompt | default / prompt |
Web platform features
Presence probes; a user agent that claims one version while exposing another's features is a detectable inconsistency.
| Chrome 156 beta | Chrome 154 | |
|---|---|---|
Iterator.prototype.includes (new in Chrome 154) | yes | yes |
FontFace.width (new in Chrome 154) | yes | yes |
CSS text-decoration-inset (new in Chrome 154) | no | no |
Iterator.prototype.join (Chrome 153) | yes | yes |
Iterator.zip (Chrome 153) | yes | yes |
CSS scroll-axis-lock (Chrome 153) | no | no |
<camera> element (Chrome 153) | yes | yes |
document.requestStorageAccessFor (deprecated in 153) | no | no |
Topics API (document.browsingTopics) | yes | yes |
Protected Audience (navigator.joinAdInterestGroup) | yes | yes |
Shared Storage (window.sharedStorage) | no | no |
Attribution Reporting (window.attributionReporting) | no | no |
| Private Aggregation | no | no |
WebHID (navigator.hid) | yes | yes |
CSS margin-trim (Chrome 155) | yes | no |
CSS text-decoration-skip-spaces (Chrome 155) | no | no |
CSS corner shorthand (Chrome 155) | no | no |
CSS symbols() (Chrome 155) | yes | no |
Element.streamAppendHTML (Chrome 155) | no | no |
WebTransport.reliability (Chrome 155) | no | no |
window.maximize() — Additional Windowing Controls (Chrome 155) | no | no |
Canvas srgb-linear colour space (Chrome 155) | no | no |
Permission policy media-playback-while-not-visible (Chrome 155) | yes | no |
CSS random() (Chrome 156) | yes | no |
CSS scroll-snap-type: pair (Chrome 156) | yes | no |
Fenced frames (window.fence) — removal starts in 157 | yes | yes |
rel=compression-dictionary (Chrome 156 updates) | yes | yes |
bot.sannysoft.com
The classic headless-detection test page; what it marks red.
| Chrome 156 beta | Chrome 154 | |
|---|---|---|
| Checks / failed | 57 / 1 | 57 / 1 |
| Failed checks | WebGL Renderer | WebGL Renderer |
A plain-HTTP URL (http://ip-api.com/json)
Chrome 154 warns before loading insecure HTTP by default — does that reach an automated session?
| Chrome 156 beta | Chrome 154 | |
|---|---|---|
| Final URL | http://ip-api.com/json/?fields=status | http://ip-api.com/json/?fields=status |
| HTTP status | 200 | 200 |
| Content loaded / warning page first | yes / no | yes / no |
Playwright over the remote connection
Which client features work on this side.
| Chrome 156 beta | Chrome 154 | |
|---|---|---|
| page.evaluate runs in the page's own world | yes | yes |
| addInitScript visible to page scripts | yes | yes |
| Console events | yes | yes |
| Request interception (page.route) | yes | yes |
| Screenshot | yes | yes |
| yes | yes | |
| Mobile device emulation | yes | yes |
| Tracing | yes | yes |
Rows where the two sides differ are highlighted. IP addresses are replaced with placeholders (203.0.113.x). The probe is compare/probe.mjs in our repository; the raw result is below.
Raw output
{
"ran_at": "2026-10-05T21:09:52.065Z",
"sides": [
{
"label": "Chrome 156 beta",
"engine": "chrome",
"body": {
"headless": false,
"channel": "beta"
},
"launch": {
"browser": "chrome",
"resource_class": "linux_headful",
"weight": 2,
"launch_ms": 669,
"connect_ms": 40,
"example_ms": 470,
"peet_ms": 2405
},
"network": {
"http_version": "h2",
"ja4": "t13d1517h2_8daaf6152771_cb7bf5808d99",
"ja3_hash": "9c429a8ece1d6d255c17d625673fa006",
"peetprint_hash": "fc97c1cdfb1409c9a9326c1b726d1dee",
"ciphers": 16,
"extensions": 19,
"akamai_h2": "1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p",
"akamai_h2_hash": "52d84b11737d980aef856699f885ca86",
"header_order": [
"method",
"authority",
"scheme",
"path",
"sec-ch-ua",
"sec-ch-ua-mobile",
"sec-ch-ua-platform",
"upgrade-insecure-requests",
"user-agent",
"accept",
"sec-fetch-site",
"sec-fetch-mode"
]
},
"page": {
"user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.0.0 Safari/537.36",
"platform": "Linux x86_64",
"vendor": "Google Inc.",
"languages": [
"en-US",
"en"
],
"hardware_concurrency": 48,
"device_memory": 32,
"max_touch_points": 0,
"webdriver": false,
"plugins": 5,
"pdf_viewer": true,
"ua_data": {
"brands": [
{
"brand": "Not:A-Brand",
"version": "8"
},
{
"brand": "Chromium",
"version": "156"
},
{
"brand": "Google Chrome",
"version": "156"
}
],
"mobile": false,
"platform": "Linux",
"architecture": "x86",
"bitness": "64",
"formFactors": [
"Desktop"
],
"fullVersionList": [
{
"brand": "Not:A-Brand",
"version": "8.0.0.0"
},
{
"brand": "Chromium",
"version": "156.0.8078.4"
},
{
"brand": "Google Chrome",
"version": "156.0.8078.4"
}
],
"model": "",
"platformVersion": "",
"uaFullVersion": "156.0.8078.4",
"wow64": false
},
"screen": "1280x720x1280x720x24",
"window": {
"outer": "1288x805",
"inner": "1280x720",
"dpr": 1
},
"timezone": "UTC",
"locale": "en-US",
"webgl": {
"vendor": "Google Inc. (Google)",
"renderer": "ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver)",
"version": "WebGL 2.0 (OpenGL ES 3.0 Chromium)"
},
"canvas_hash": "f5a94624",
"webgpu": true,
"chrome_object": true,
"chrome_runtime": false,
"notification_permission": "default",
"notification_query": "prompt",
"has_focus": true,
"connection_api": true,
"stack_read_by_debugger": false,
"features": {
"iterator_includes": true,
"iterator_join": true,
"iterator_zip": true,
"fontface_width": true,
"css_text_decoration_inset": false,
"css_scroll_axis_lock": false,
"websocket_options_bag": null,
"camera_element": true,
"topics_api": true,
"protected_audience": true,
"shared_storage": false,
"attribution_reporting": false,
"request_storage_access_for": false,
"webhid": true,
"private_aggregation": false,
"css_margin_trim": true,
"css_text_decoration_skip_spaces": false,
"css_corner_shorthand": false,
"css_symbols": true,
"stream_append_html": false,
"webtransport_reliability": false,
"window_maximize": false,
"media_display_state": true,
"canvas_srgb_linear": false,
"policy_media_playback_while_not_visible": true,
"css_random": true,
"css_scroll_snap_pair": true,
"fenced_frames": true,
"compression_dictionary": true
}
},
"page_main_world": null,
"sannysoft": {
"checks": 57,
"failed": 1,
"failed_names": [
"WebGL Renderer"
],
"passed": 30
},
"plain_http": {
"final_url": "http://ip-api.com/json/?fields=status",
"status": 200,
"title": "",
"loaded": true,
"warning_page": false,
"page_text": "{\"status\":\"success\"}"
},
"playwright": {
"evaluate_in_main_world": true,
"console_events": true,
"init_script": true,
"route": true,
"screenshot": true,
"pdf": true,
"mobile_emulation": true,
"tracing": true
},
"browser_version": "156.0.8078.4"
},
{
"label": "Chrome 154",
"engine": "chrome",
"body": {
"headless": false
},
"launch": {
"browser": "chrome",
"resource_class": "linux_headful",
"weight": 2,
"launch_ms": 719,
"connect_ms": 128,
"example_ms": 956,
"peet_ms": 2543
},
"network": {
"http_version": "h2",
"ja4": "t13d1517h2_8daaf6152771_cb7bf5808d99",
"ja3_hash": "06971656b55d8d6c33e327e2e51e8440",
"peetprint_hash": "fc97c1cdfb1409c9a9326c1b726d1dee",
"ciphers": 16,
"extensions": 19,
"akamai_h2": "1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p",
"akamai_h2_hash": "52d84b11737d980aef856699f885ca86",
"header_order": [
"method",
"authority",
"scheme",
"path",
"sec-ch-ua",
"sec-ch-ua-mobile",
"sec-ch-ua-platform",
"upgrade-insecure-requests",
"user-agent",
"accept",
"sec-fetch-site",
"sec-fetch-mode"
]
},
"page": {
"user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36",
"platform": "Linux x86_64",
"vendor": "Google Inc.",
"languages": [
"en-US",
"en"
],
"hardware_concurrency": 64,
"device_memory": 32,
"max_touch_points": 0,
"webdriver": false,
"plugins": 5,
"pdf_viewer": true,
"ua_data": {
"brands": [
{
"brand": "Chromium",
"version": "154"
},
{
"brand": "Google Chrome",
"version": "154"
},
{
"brand": "Not A(Brand",
"version": "99"
}
],
"mobile": false,
"platform": "Linux",
"architecture": "x86",
"bitness": "64",
"formFactors": [
"Desktop"
],
"fullVersionList": [
{
"brand": "Chromium",
"version": "154.0.8037.97"
},
{
"brand": "Google Chrome",
"version": "154.0.8037.97"
},
{
"brand": "Not A(Brand",
"version": "99.0.0.0"
}
],
"model": "",
"platformVersion": "",
"uaFullVersion": "154.0.8037.97",
"wow64": false
},
"screen": "1280x720x1280x720x24",
"window": {
"outer": "1288x805",
"inner": "1280x720",
"dpr": 1
},
"timezone": "UTC",
"locale": "en-US",
"webgl": {
"vendor": "Google Inc. (Google)",
"renderer": "ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver)",
"version": "WebGL 2.0 (OpenGL ES 3.0 Chromium)"
},
"canvas_hash": "f5a94624",
"webgpu": true,
"chrome_object": true,
"chrome_runtime": false,
"notification_permission": "default",
"notification_query": "prompt",
"has_focus": true,
"connection_api": true,
"stack_read_by_debugger": false,
"features": {
"iterator_includes": true,
"iterator_join": true,
"iterator_zip": true,
"fontface_width": true,
"css_text_decoration_inset": false,
"css_scroll_axis_lock": false,
"websocket_options_bag": null,
"camera_element": true,
"topics_api": true,
"protected_audience": true,
"shared_storage": false,
"attribution_reporting": false,
"request_storage_access_for": false,
"webhid": true,
"private_aggregation": false,
"css_margin_trim": false,
"css_text_decoration_skip_spaces": false,
"css_corner_shorthand": false,
"css_symbols": false,
"stream_append_html": false,
"webtransport_reliability": false,
"window_maximize": false,
"media_display_state": true,
"canvas_srgb_linear": false,
"policy_media_playback_while_not_visible": false,
"css_random": false,
"css_scroll_snap_pair": false,
"fenced_frames": true,
"compression_dictionary": true
}
},
"page_main_world": null,
"sannysoft": {
"checks": 57,
"failed": 1,
"failed_names": [
"WebGL Renderer"
],
"passed": 30
},
"plain_http": {
"final_url": "http://ip-api.com/json/?fields=status",
"status": 200,
"title": "",
"loaded": true,
"warning_page": false,
"page_text": "{\"status\":\"success\"}"
},
"playwright": {
"evaluate_in_main_world": true,
"console_events": true,
"init_script": true,
"route": true,
"screenshot": true,
"pdf": true,
"mobile_emulation": true,
"tracing": true
},
"browser_version": "154.0.8037.97"
}
]
}Bottom line
For scrapers, 156 is a quiet release: identical on the wire, identical fingerprint surface, and five new CSS-level ways for a page to confirm it really is 156. The practical items are the client-hint brand order change and the Local Network Access permissions — both invisible unless something inspects them.
For testers, the beta channel is already there: launch channel: "beta" next to stable, run the same script, and diff the output — which is exactly what this page did.