Key takeaways
- Vanilla Playwright does not clear Akamai Bot Manager v4. The patched Chromium build (Patchright) reached 74% on residential proxies in our April 2026 tests.
- A plain HTTP client with TLS impersonation reached 87% on the same targets, at roughly a quarter of the compute. On Akamai the browser is usually the wrong layer.
- Akamai ranks TLS fingerprinting first, which is the one signal Playwright cannot change — the handshake belongs to the Chromium build, not to your script.
- The two changes that moved Playwright's numbers most were a session warm-up (61% to 83%) and bezier mouse paths (+11 points), not a different stealth library.
- Keep the browser for Akamai-protected flows behind a login or a cart. Drop it for catalogue and price pages.
Vanilla Playwright does not clear Akamai Bot Manager. A patched Chromium build gets you to roughly three-quarters, and a plain HTTP client with the right TLS handshake beats it outright for about a quarter of the compute.
That last part is the counter-intuitive bit, and it is specific to Akamai. On Cloudflare, a stealth browser is the right answer. On Akamai it usually is not, because the two vendors rank their signals in a different order — and the signal Akamai ranks first is the one Playwright has no control over.
Choose Before You Read
| Your situation | Do this |
|---|---|
| Playwright is blocked on an Akamai catalogue or product page | Drop the browser, fix the TLS handshake |
| The Akamai target is behind a login or a cart | Keep the browser; add warm-up and motion |
| You are on vanilla Playwright and have changed nothing yet | Switch to Patchright first — it is one import line |
| You are on datacentre proxies | Fix that before anything else; it caps every row in the table below |
| You are not sure the WAF is Akamai | Confirm it first — the fix is different per vendor |
| You want the rows, not a stealth stack | Skip to the last section |
What We Measured
April 2026, 500 requests per approach over six hours against production sites running Bot Manager v4, through a residential pool of 2M+ IPs. The full method and the per-signal breakdown are in bypassing Akamai Bot Manager; what follows is the Playwright-relevant slice.
| Approach | Akamai v4 pass rate | Relative compute cost |
|---|---|---|
| Requests library + datacentre proxies | 22% | Lowest |
| Camoufox + datacentre proxies | 68% | High |
| curl-cffi + datacentre proxies | 71% | Low |
| Patchright + residential proxies | 74% | High |
| Camoufox + residential proxies | 83% | Highest |
| curl-cffi + residential proxies | 87% | Low |
Two rows matter here. Patched Playwright on residential IPs reaches 74%. A socket-level HTTP client on the same IPs reaches 87% — thirteen points higher, with no browser process at all. At 10,000 pages a day the compute gap between those two rows is about 4:1.
Vanilla Playwright is not in the table because it is not an approach, it is the control. It announces itself over the DevTools Protocol and gets refused.
Why Akamai Specifically Punishes a Browser
Akamai evaluates in this order:
- TLS fingerprint (JA3/JA4) — the handshake, before a single byte of your page runs
- IP reputation — ASN, history, whether the range is a known cloud provider
- JavaScript telemetry — the
sensor_datapayload, validated server-side - Behavioural biometrics — mouse paths, scroll events, dwell time
- Session continuity — whether this "new" session behaves like one
Layer 1 is the problem. A JA3 or JA4 fingerprint is a hash of what your client offers during the TLS handshake: cipher suites, extensions, elliptic curves, the order they appear in. It is decided by the TLS library compiled into your binary, and it is read before any JavaScript executes.
Playwright cannot change it. There is no launch argument, no context option and no stealth plugin that rewrites the handshake, because the handshake is not Playwright's — it belongs to the Chromium build underneath. A patched Chromium ships a handshake closer to real Chrome, which is exactly why Patchright scores better than vanilla. But "closer to real Chrome" is a fixed property of the build you installed, not a dial you turn per target.
So on a vendor that checks the handshake first, you are spending 200MB and a full page render to influence layers 3 through 5 while layer 1 decides the outcome. That is the whole asymmetry.
On Cloudflare the ordering is effectively reversed — JavaScript challenges carry more weight, which is why a stealth browser wins there and loses here.
Is It Akamai, Cloudflare or PerimeterX?
Worth thirty seconds, because the correct fix differs per vendor and people routinely apply the Cloudflare playbook to an Akamai target.
- An
_abckcookie in the response - A
sensor_dataPOST going out from the page Server: AkamaiGHostin the response headers- A
bm_szcookie, which confirms Bot Manager rather than plain Akamai CDN
If you see Turnstile or cf_clearance instead, you are on Cloudflare — different post. If you see _px cookies, it is PerimeterX, where every approach we tested hit a ceiling around two-thirds.
Among European retail, Zara, H&M, MediaMarkt and Fnac all run Akamai in front of their catalogues.
Session Warm-Up and Bezier Paths: What Actually Helped
If you are keeping the browser — and for authenticated flows you should — these did more than any library swap.
Session warm-up: 61% to 83%. Akamai's session-continuity layer scores a brand-new session that navigates straight to a high-value URL. Two or three ordinary page loads with real dwell time in between, before you touch the target, was the single largest gain we measured.
const { chromium } = require('patchright')
const jitter = (min, max) => new Promise(r => setTimeout(r, min + Math.random() * (max - min)))
const browser = await chromium.launch({ headless: true })
const context = await browser.newContext({ locale: 'de-DE', timezoneId: 'Europe/Berlin' })
const page = await context.newPage()
// Warm-up: land shallow, dwell, browse inward. The _abck cookie matures across these.
for (const path of ['/', '/damen', '/damen/kleider']) {
await page.goto(`https://example-retailer.de${path}`, { waitUntil: 'domcontentloaded' })
await jitter(1800, 4200)
}
// Only now the page you actually came for.
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' })
Bezier mouse paths: +11 points. A straight-line mouse.move() is a signature no human produces. Interpolating along a cubic bezier with a variable step count was worth eleven percentage points over the linear default. Note what this means in practice: you are now writing and maintaining a motion simulator, which is engineering work with no end date.
And the one that is not optional: jitter, not sleep. A fixed waitForTimeout(1000) between requests is itself a fingerprint. Randomise across 300–2,500ms.
What did not help: rotating user-agent strings, overriding navigator.webdriver from JavaScript after load (detectable — a rewritten property descriptor is visible to an Object.defineProperty guard), and playwright-extra, which is effectively unmaintained and should not start new work.
When to Drop the Browser Entirely
For any Akamai page that renders its data server-side — catalogue listings, product pages, search results — the browser is pure overhead. You pay for Chromium to influence the layers Akamai weighs least, while losing on the layer it weighs most.
A client built on curl-impersonate, such as curl_cffi, replays a real browser's TLS handshake at the socket level. In our tests that one change took the HTTP path from 22% to 71% on datacentre IPs, and to 87% on residential. Full walkthrough: TLS fingerprint impersonation with curl_cffi.
Keep the browser when:
- The page genuinely renders client-side and the data is not in the HTML
- You are behind a login, a cart or a checkout — Akamai's session tracking is strongest here, and a browser is the realistic way to hold a session
- You need to interact: a size selector, a store-availability lookup, a "load more" button
Drop it when the markup already contains what you came for. Checking takes one request.
What This Costs to Keep Alive
| Approach | Monthly infra at 10k pages/day | Engineering maintenance |
|---|---|---|
| curl-cffi + residential proxies | ~$120–180 | 3–5 hrs/month |
| Patchright + residential proxies | ~$380–520 | 8–12 hrs/month |
| Camoufox + residential proxies | ~$440–600 | 10–15 hrs/month |
The maintenance column is the one that gets underestimated. Akamai ships sensor-script changes roughly monthly, and each one can drop a pass rate by 15–30 points overnight. Your scraper does not break loudly; it starts returning fewer rows, and somebody notices a week later in a report.
When Stealth Stops Being a Library Decision
The honest arc of an Akamai project is: vanilla Playwright blocked → Patchright passes → volume rises → rate-limited → residential proxies added → behavioural scoring catches the timing → you are writing a mouse-movement simulator. Step six is where teams discover this was never a library choice.
If what you need is competitor prices, stock levels and product data arriving in your systems rather than a stealth stack to keep alive, the Playwright-versus-Akamai question is the wrong one to be answering. ScrapeWise runs the browsers, the proxies and the challenge handling and delivers structured rows. No plan and no compute units: a balance you top up, and a published charge per delivered page — EUR 0.15 per 1,000 for plain requests, EUR 0.75 with rendering, EUR 1.50 through the residential tier and EUR 3.75 for render plus residential. New accounts get 5 free requests and the balance never expires.
You can also call ready-made scraping API endpoints directly, or see how this feeds competitor price tracking.
So What Should You Run?
- Patched Playwright, warmed up, with motion — the Akamai target is behind a login or a cart and you need to hold a session.
- An HTTP client with TLS impersonation — the data is in the HTML. 87% against 74%, at a quarter of the compute.
- Camoufox — high-value, low-frequency pages where 42 seconds each is acceptable. It wins on Cloudflare, not on Akamai.
- Vanilla Playwright — tests, and targets with no WAF. Never this one against Bot Manager.
- None of the above — you want delivered rows on a schedule and would rather not maintain any of it.
Paste any URL — ScrapeWise handles the anti-bot
Managed infrastructure that adapts when sites change. No proxies, no code, no per-request fees.
Not ready to sign up? See 12 real Amazon rows, 972 columns →
97% accuracy on Amazon benchmarks · no credit card · book a 15-min call →
