guide

Running Playwright on AWS Lambda: Challenges & Solutions

Running Playwright on AWS Lambda: Challenges, Solutions, and Alternatives

Table of Contents


Introduction

Running end-to-end browser tests or web scraping jobs serverlessly with Playwright on AWS Lambda can feel like herding cats – intriguing but tricky. Playwright, a powerful browser automation library from Microsoft, lets you control headless Chromium, Firefox, and WebKit via code. AWS Lambda, Amazon’s serverless compute platform, lets you run code on-demand without managing servers. Combining the two offers a purr-fect scenario for scalable automation: you only pay when your code runs, it scales automatically to meet demand, and there’s no need to maintain flaky browser servers yourself (Headless Chrome on AWS Lambda).

Imagine triggering a Lambda function that spins up a headless browser to run tests or scrape a page, then returns a result (or saves a screenshot to S3) – all on-demand and hands-off.

In this article, we’ll guide you through how to run Playwright on AWS Lambda, explain the key challenges (and gotchas) you’ll face, and show how to solve them. We’ll also highlight a simpler alternative that can save you from clawing through complex setup – BrowserCat, a hosted browser automation service that can take the heavy lifting off your paws. Along the way, we’ll include code snippets (with parallel execution examples) and relevant tips so developers of all levels can follow along. Let’s dive in and get this cat moving! 🐱


Setup: Running Playwright on AWS Lambda

Setting up Playwright on AWS Lambda requires a few extra steps compared to running it on your local machine. The goal is to get a Playwright script working inside the constraints of Lambda’s environment. Here’s a high-level setup overview:

  1. Create an AWS Lambda function:
    Start by creating a new Lambda function (e.g., using Node.js 18 or Python 3.x runtime). You can do this via the AWS Console or Infrastructure as Code (AWS SAM/CloudFormation). Ensure you allocate sufficient memory (at least 1024 MB is recommended to run headless browsers) and a comfortable timeout (the max is 15 minutes, but often a few seconds per execution is ideal).

  2. Bundle Playwright and a headless browser:
    By default, installing Playwright also downloads browser binaries that aren’t compatible with Lambda’s Amazon Linux OS. You have a couple of options to get a workable Chromium binary into Lambda:

    • Lambda Layer or Custom Binary: Use a community-provided Chromium build for AWS Lambda. For Node.js, the popular chrome-aws-lambda package provides a headless Chrome that works on Lambda. Pair this with playwright-core (which excludes the default browsers) and reference the chrome-aws-lambda executable. Another shortcut is the playwright-aws-lambda npm package, which wraps Playwright with a Lambda-friendly Chromium.
    • Container Image: AWS Lambda supports container images up to 10 GB, which can include all dependencies. Microsoft publishes Playwright-ready Docker images with browsers pre-installed. You can base your Lambda container on one of these (e.g., mcr.microsoft.com/playwright:<version>-focal) so that the Playwright browsers are already present.
  3. Write the Lambda handler with Playwright code:
    In your function’s code, initialize Playwright’s browser in headless mode and perform the desired actions. For Node.js, you might write something like:

    const chromium = require('chrome-aws-lambda');
    const playwright = require('playwright-core');
    
    exports.handler = async (event) => {
        const browser = await playwright.chromium.launch({
            args: chromium.args,
            executablePath: await chromium.executablePath,
            headless: chromium.headless,
        });
        const page = await browser.newPage();
        await page.goto('https://example.com');
        const content = await page.content();
        console.log(content);
        await browser.close();
    };
    
  4. Deploy and test:
    Package your code and dependencies. If using layers, deploy the layer and attach it to the Lambda. If using a container image, build and push it to ECR and set your Lambda to use that image. Then invoke the Lambda to verify everything runs. Start with a simple script (like navigating to a page and grabbing the title) to confirm all dependencies are in place.


Challenges in a Serverless Environment

Running a headless browser on Lambda comes with a few unique challenges that developers need to be aware of:

  • Incompatible binaries: The Playwright installer fetches browser binaries built for standard Linux environments, which aren’t compatible with AWS Lambda’s slim Amazon Linux environment.
  • Large deployment package: Headless browsers are big. AWS Lambda has limits on package sizes (50 MB zipped for code, 250 MB uncompressed, plus 250 MB for layers).
  • Cold start and performance overhead: Spawning a browser is a heavyweight operation. On a cold start, downloading and launching Chromium can add a few seconds of latency.
  • Ephemeral storage and session limits: Lambda provides /tmp storage (512 MB by default), which is erased between invocations.
  • Memory and CPU constraints: A headless browser can easily use 1+ GB of RAM. Lambda functions max out at ~10 GB RAM and 6 vCPUs.
  • Troubleshooting and logging: Debugging headless browser issues on Lambda can be challenging, often requiring reliance on CloudWatch logs.

Solutions and Best Practices

Here are some solutions and best practices to address the challenges:

  • Use a Lambda-friendly Chromium build or container: Use the playwright-aws-lambda library or the combination of playwright-core + chrome-aws-lambda for Node.js projects. Containers can also simplify the setup.
  • Trim the fat: Install playwright-core instead of the full Playwright if you only need Chromium.
  • Adjust Lambda resources: Allocate more memory (e.g., 1536 MB or 2048 MB) to improve browser launch times.
  • Optimize startup in code: Launch the browser as late as possible and reuse it within the same invocation.
  • Parallelize where possible: Use Playwright’s async/await capabilities to perform tasks concurrently.

Parallel Execution with Playwright (Code Example)

Here’s an example of parallel execution using Playwright inside a Lambda handler:

const { chromium } = require('playwright');

exports.handler = async function(event) {
    const browser = await chromium.launch({ headless: true });
    const context = await browser.newContext();

    const page1 = await context.newPage();
    const page2 = await context.newPage();

    await Promise.all([
        page1.goto('https://example.com'),
        page2.goto('https://example.org')
    ]);

    const [title1, title2] = await Promise.all([
        page1.title(),
        page2.title()
    ]);

    await browser.close();
    return { title1, title2 };
};

This code demonstrates how to open two pages concurrently and navigate to two URLs in parallel, improving throughput.


Alternatives: BrowserCat vs. Other Approaches

If managing Playwright on AWS Lambda feels overwhelming, consider these alternatives:

  • DIY on AWS Lambda: Offers flexibility but requires significant DevOps effort.
  • Other cloud automation platforms: Services like Browserless.io or Checkly provide hosted browser automation but may have usage-based costs.
  • BrowserCat – hosted Playwright on tap: BrowserCat manages the browser fleet and infrastructure, allowing you to focus on writing scripts. It eliminates the need for packaging Chromium or dealing with AWS limits. BrowserCat’s pay-as-you-go pricing and managed service make it an excellent alternative for developers who want to avoid infrastructure headaches.

Conclusion

Running Playwright on AWS Lambda can unlock scalable, cost-efficient browser automation. While the setup involves overcoming challenges like binary compatibility and cold starts, the rewards are worth it. For those who prefer a simpler solution, BrowserCat offers a managed Playwright service that eliminates the heavy lifting.

Whether you choose to DIY or use a hosted service, you’ll be able to leverage the power of Playwright in the cloud. Happy automating, and may your scripts always run purr-fectly in the cloud! 😸


References

Automate Everything.

Tired of managing a fleet of fickle browsers? Sick of skipping e2e tests and paying the piper later?

Sign up now for free access to our headless browser fleet…

Get started today!