Short answer: Playwright unless you are specifically fighting automation-flag detection. It has the cross-browser support, the mature selector and waiting API, the tooling and the community. nodriver wins on exactly two axes — ~80–120MB per instance against Playwright's ~200MB, and it never fires the Runtime.enable CDP call that modern detection systems flag. It buys those with a smaller API surface, Chrome-only support, and a hard ceiling: it does nothing about behavioural scoring, so DataDome, Akamai Bot Manager and PerimeterX still block it.
The trap is assuming nodriver is "Playwright but stealthier". It is lighter and quieter at the protocol layer, and that is a narrower advantage than it sounds.
Choose Before You Read
| Your situation | Use |
|---|---|
| General browser automation, testing, cross-browser | Playwright |
| Blocked specifically by automation-flag detection | nodriver |
| Memory-bound: many concurrent browsers on one box | nodriver |
| Target runs DataDome, Akamai or PerimeterX | Neither — see below |
| Node.js codebase | Playwright (nodriver is Python) |
| You need the data, not a browser fleet | Neither — see below |
The Architectural Difference in One Paragraph
Playwright is a full automation framework. It drives Chromium, Firefox or WebKit over a WebSocket bridge, and gives you page.goto(), auto-waiting selectors, network interception, tracing, codegen and a test runner. That bridge is what makes the API pleasant. It is also what leaves a signature.
nodriver removes the framework. It drives Chrome directly over the Chrome DevTools Protocol with no intermediate layer and without the automation flags that expose headless status. Crucially, it avoids the Runtime.enable CDP call — a command detection systems specifically watch for, because a real user's browser has no reason to issue it. No bridge process also means no bridge memory: ~80–120MB per instance against Playwright's ~200MB.
So the trade is legible: you give up API surface and cross-browser support, and you get a lighter, quieter process.
Memory Is the Real Advantage, Not Stealth
This is the part that gets buried under the stealth framing, and it is the one that changes capacity plans.
| Playwright + Chromium | nodriver | |
|---|---|---|
| Memory per instance | ~200MB | ~80–120MB |
| Instances on a 16GB box (leaving 4GB headroom) | ~60 | ~100–150 |
| Browsers supported | Chromium, Firefox, WebKit | Chrome only |
| Language | Python, Node.js, Java, .NET | Python |
| Auto-waiting selectors | Yes | Manual |
| Test runner, tracing, codegen | Yes | No |
Runtime.enable fired |
Yes | No |
On a memory-bound box, nodriver roughly doubles your concurrency for the same hardware. If your bottleneck is "how many browsers fit on this machine" rather than "which sites block me", that is the whole case — and it is a better case than the stealth one.
But price the other side honestly. Playwright's auto-waiting is not a convenience feature; it is the thing that stops flaky scrapers. Writing manual waits across a few hundred page shapes is real, recurring work, and it fails in the worst way — intermittently, under load, on the pages you check least often.
The Behavioural Wall Both Hit
Here is the ceiling nobody prices before committing.
nodriver's stealth is protocol-level. It removes the tells that come from how the browser is being driven. What it does not do is fake human behaviour: it does not generate mouse movement, scroll events, or realistic keystroke timing.
Modern enterprise anti-bot systems score behaviour heavily. So:
| Anti-bot system | Playwright (vanilla) | nodriver |
|---|---|---|
| Basic detection, no active WAF | Passes | Passes |
| Cloudflare BotFight (free tier) | Blocked (passes once hardened) | Passes |
| Cloudflare Enterprise / Turnstile | Blocked | Blocked |
| DataDome | Blocked | Blocked |
| Akamai Bot Manager v4 | Blocked | Blocked |
| PerimeterX / HUMAN | Blocked | Blocked |
Read the right-hand column carefully. nodriver upgrades you from "blocked by things that check for automation flags" to "blocked by things that score behaviour". If your target is on the bottom four rows, switching to nodriver does not help — and the hours spent porting are hours not spent on the actual fix.
That is the single most common wasted migration in this space: reaching for a stealthier driver to solve a problem that is not a driver problem.
Diagnose before you port
- 429s or sudden 403s after a burst — rate limiting. A quieter driver sending the same burst gets blocked identically.
- Connection refused outright rather than challenged — datacenter IP reputation. No driver fingerprint rescues a refused connection; that is a proxy problem.
- Challenge page served consistently — behavioural or fingerprint scoring. This is where a stealth browser like Camoufox belongs, not a lighter driver.
- Works once, fails on repeat — session and navigation patterns. Hitting 500 URLs in catalogue order with no referrer reads as automation regardless of driver.
Our full diagnostic is in scraping without getting blocked.
nodriver vs Camoufox
These two get compared constantly and they are not substitutes — they sit at opposite ends of the same axis.
nodriver is the lightest option. ~80–120MB, protocol-level stealth, no behavioural handling. Fast, cheap, stops at basic protection.
Camoufox is the heaviest option. A Firefox fork with stealth patches applied at the C++ level, 0% headless detection on standard bot-detection tests (vendor benchmark, checked September 2026) — and an average of 42.49 seconds to clear a Cloudflare Turnstile challenge, at 200MB+ per context. That is roughly 85 challenged pages per hour per worker.
| nodriver | Camoufox | |
|---|---|---|
| Memory | ~80–120MB | 200MB+ per context |
| Throughput on challenged pages | n/a — it gets blocked | ~85/hour/worker |
| Cloudflare Enterprise | Blocked | Passes |
| DataDome / PerimeterX | Blocked | Passes |
| Browser | Chrome | Firefox fork |
| Right when | Volume is high, protection is light | Data is high-value, volume is bounded |
Choosing between them is really choosing between throughput and access. If the sites you need do not fight back, nodriver gets you far more pages per euro. If they do, nodriver gets you zero pages and the comparison is over. The full arithmetic is in Camoufox vs Playwright.
The configuration most teams land on: route per domain. Light driver by default, measure block rate per domain rather than site-wide — a single 8% site-wide failure figure hides one target failing 90% of the time while thirty others sit at zero — and promote only the failing handful to a heavier browser with its own concurrency cap.
When Playwright Is Simply the Right Answer
Worth saying plainly, because the stealth conversation crowds it out:
- You are testing, not scraping. nodriver has no test runner, no tracing, no codegen. Playwright is a testing framework that happens to be usable for scraping; nodriver is not.
- You need Firefox or WebKit. nodriver is Chrome-only. Cross-browser is not a feature it has a worse version of — it does not have it.
- You are on Node.js, Java or .NET. nodriver is Python.
- Your team is more expensive than your servers. Auto-waiting selectors, a mature debugging story and a large community are worth more than 100MB per worker at almost any realistic salary-to-hosting ratio.
The memory argument only wins when you are genuinely running enough concurrent browsers for 100MB each to show up on an invoice. Most teams are not, and adopt nodriver for stealth reasons that do not survive contact with their actual block logs.
When Neither Is the Answer
Both hand you a way to drive a browser. Neither hands you data.
What stays yours either way: writing selectors and rewriting them after every redesign, running and rotating proxies, session management, retry logic, storage, change detection, and the matching layer that turns rows into a usable comparison. The driver is the part of this problem that attracts the most attention and consumes the least ongoing time.
ScrapeWise sits above the whole layer: we run the browsers, the stealth tooling, the proxies, the anti-bot escalation and the parsers, and deliver structured rows through the portal data grid, a CSV or Excel export, or the REST API. Whether a given page needed a light CDP driver or something much heavier is our problem, not a line item on your capacity plan.
The honest trade-off: ScrapeWise is a data feed, not an automation framework. If you are building custom browser automation — testing, agents, anything interactive — Playwright is the right tool and we are not a substitute for it. For data delivery there is less to weigh: no plan, no compute units, a balance you top up from €5 that never expires, and a charge per delivered page from €0.15 per 1,000 plain pages (€0.75 rendered, €1.50 for residential proxies on the hardest targets), with 5 free requests on every new account.
You can also call ready-made scraping API endpoints directly.
So Which Should You Pick?
- Playwright — your default, and correct for nearly all browser automation. Cross-browser, multi-language, auto-waiting, and the tooling that keeps scrapers from going flaky.
- nodriver — you are on Python, memory-bound, and blocked specifically by automation-flag detection on otherwise light targets. Roughly double the concurrency per box.
- Camoufox — the target runs DataDome, Akamai or Cloudflare Enterprise. Neither of the above gets through; plan for ~2,000 pages per worker per day.
- Routed — light driver by default, heavy browser promoted per domain on measured block rate.
- Neither — you want rows on a schedule and would rather not run a browser fleet to get them.
For the full matrix of which tool clears which anti-bot system, see Playwright stealth in 2026, and Patchright vs Playwright if you are on Node.js and unwilling to adopt Python or Firefox.
Paste a URL your current tool cannot reach
See why teams switch to ScrapeWise. 97% accuracy benchmark, no per-SKU pricing.
97% accuracy on Amazon benchmarks · no credit card · book a 15-min call →
