AX/J/001

Playwright vs Puppeteer in production: the hidden cost of choice

Most framework comparisons miss what actually costs in production — debugging, retries, hiring, maintenance. Here we break down the decision by the factors that matter two years into running it.

Most Playwright vs Puppeteer comparisons look the same. They start with a feature list. Playwright supports three engines, Puppeteer focuses on Chromium. Playwright has auto-wait, Puppeteer has a deeper user base. Playwright comes from Microsoft, Puppeteer from Google.

All true. All irrelevant when it's three in the morning on Friday and you're configuring retries for a scrape that has to deliver data before Monday's market open.

Choosing between these tools is a decision about how your team will solve problems nobody anticipated.

What actually costs in production

After several years maintaining production browser automations for operators at scale, the list of things that weigh most looks nothing like the one in comparison articles.

First: debug experience. When a scrape goes sideways in production and returns an unexpected payload, the first question is: why. Playwright gives you a trace viewer — a full recording of every click, network request and screenshot which you can open an hour after the incident and walk through frame by frame. Puppeteer requires you to build that layer yourself, or rely on DevTools in headed mode, which is a non-starter on production.

Second: auto-wait. This sounds like a detail, but Playwright handles 90% of the things Puppeteer asks you to code by hand — waiting for an element to be visible, attached, in a state that allows a click. In Puppeteer, at least half of all flakes come from someone forgetting to waitForSelector before clicking. In Playwright that whole class of error simply does not exist.

Third: hiring and onboarding. This one is underrated. When you hire an engineer to maintain a scraping pipeline — if they've written Playwright before, they're productive in their first week. Puppeteer requires them to first understand what abstraction layer the previous team built. Every team builds it differently.

Where Playwright quietly wins

Three things that rarely come up in comparisons but become obvious a year into production:

  • Codegen. Playwright can record a session in a real browser and emit working code — not perfect, but a solid starting point. For new scrapes that saves half a day. Puppeteer-Recorder exists, but the output quality is noticeably worse.
  • Multi-browser. Sometimes a target has a quirky anti-bot that detects Chrome but not Firefox. In Playwright you change one line. In Puppeteer you rewrite the scrape from scratch.
  • Mobile emulation with device descriptors. Realistic iPhone 14 emulation — viewport, user agent, touch events, geolocation — is one line. In Puppeteer you assemble it from fragments. For scrapes of mobile-first sites this is critical.

Where Puppeteer still wins

Two specific scenarios where Puppeteer remains the clearly better choice:

First: deeper Chromium integration. If you need to manipulate CDP (Chrome DevTools Protocol) at a level Playwright's abstraction does not allow — intercepting network requests at raw WebSocket frame level, manipulating heap snapshots, custom debugging targets — Puppeteer stays closer to CDP. Playwright exposes most of CDP via page.context().newCDPSession(), but in practice less gracefully.

Second: cold-start performance at extreme scale. Puppeteer starts up 200–300ms faster than Playwright on typical AWS m6i instances in our benchmarks. If you run a pipeline where cold-start happens thousands of times per hour, that's a real cost difference.

When neither: raw CDP

There are scenarios where neither Playwright nor Puppeteer is the right tool. If you're building something highly specialised — say, custom anti-anti-bot work where you need fingerprint control at a level neither abstraction exposes — you drop back to raw CDP and drive Chrome over a WebSocket yourself.

This is not the path we recommend in 95% of cases. But sometimes a target's anti-bot is aggressive enough that detection happens at a layer Playwright does not cover. Then CDP is your only option.

What actually decides this

The framework is the smallest decision in this project. What decides the long-term success of an automation is:

  1. How you designed retry logic and whether it's genuinely idempotent.
  2. Whether you have a dead-letter queue for payloads that failed to parse — and whether anyone looks at it.
  3. Whether every object exiting the scrape passes a schema validation, or you ship raw output and pray.
  4. How you handle proxy and fingerprint rotation — one of the two most common silent failures.
  5. Whether you have observability that warns you of a trend before the pipeline breaks, or you find out from the customer.

Each of these decisions weighs more than choosing between Playwright and Puppeteer. Playwright gives you a few centimetres of extra margin on these decisions. But if these decisions are made badly, no framework will save you.

Framework is the smallest decision. Everything around it weighs more.

Recommendation

For new projects in 2026: Playwright. The advantage is at the level of infrastructure around the tool — tracing, codegen, multi-browser — not the code itself. What Playwright does for developer experience invests in product stability over the long term.

Exception: if you have a team with two years of Puppeteer experience and a working production system, don't migrate. The gain will not cover the cost of rewriting pipelines or the risk of regression. Keep Puppeteer for legacy systems, use Playwright for new ones.

And as always: the framework is not where this project gets won.

Hitting a similar problem?

Most of these techniques we ship to production.

If this article resonates with something you are trying to solve — write. Initial project assessment is free.