DEV Community

IronSoftware
IronSoftware

Posted on

Why Selenium WebDriver Is the Wrong Tool for Document Generation

Developers frequently reach for Selenium WebDriver when they need to convert web pages to documents. The reasoning seems logical: Selenium controls a real browser, browsers can print pages, so Selenium should be able to generate documents. In practice, this approach creates significant production challenges that consume development time, increase infrastructure costs, and introduce reliability problems that purpose-built solutions avoid entirely.

The Problem

Selenium WebDriver was designed for one purpose: automated browser testing. Every architectural decision in the framework optimizes for running test suites against web applications. When developers repurpose Selenium for document generation in production systems, they inherit all the overhead of a testing framework without any of the benefits.

The issues manifest across several dimensions:

Resource consumption that scales poorly with document volume. Each Selenium session spawns a full browser process with complete JavaScript engines, rendering pipelines, and memory structures designed for interactive browsing rather than document conversion.

Driver management complexity that requires constant attention. ChromeDriver versions must match Chrome versions exactly, and browser auto-updates can break production systems without warning.

Reliability concerns in server environments. Selenium assumes a desktop environment with displays, window managers, and user interaction capabilities that server deployments lack.

Concurrency limitations that prevent horizontal scaling. Browser instances conflict with each other, consume shared resources, and fail unpredictably under load.

Error Messages and Symptoms

Developers using Selenium for document generation commonly encounter these errors:

SessionNotCreatedException: session not created:
This version of ChromeDriver only supports Chrome version 120
Current browser version is 121.0.6167.85

TimeoutException: Message: timeout: Timed out receiving message from renderer

WebDriverException: unknown error: Chrome failed to start:
crashed. (chrome not reachable)

InvalidSessionIdException: invalid session id
Message: Session already closed

OutOfMemoryError: Java heap space
Enter fullscreen mode Exit fullscreen mode

These errors reflect fundamental mismatches between Selenium's design assumptions and production document generation requirements.

Who Is Affected

The Selenium-for-documents pattern appears across multiple scenarios:

Web application teams who need to generate reports, invoices, or certificates from their existing HTML templates. They already use Selenium for testing and assume extending it to document generation will reduce dependencies.

Data pipeline developers building ETL processes that need to archive web content as documents. They choose Selenium because it handles JavaScript-rendered content that simpler HTTP requests cannot capture.

Integration teams connecting to third-party web applications where documents must be extracted from authenticated sessions. Selenium's ability to maintain browser state seems like an advantage.

Linux server deployments including Docker containers, Kubernetes pods, and cloud functions where headless execution is required. These environments lack displays and must configure Selenium specially.

High-throughput systems generating hundreds or thousands of documents per hour. These discover Selenium's scaling limitations after significant development investment.

Evidence from the Developer Community

The pattern of Selenium document generation problems is well-documented across developer forums and issue trackers.

Timeline

Date Event Source
2021-10-14 Selenium 4 adds print-to-PDF feature Official Release Notes
2023-02-08 Developers report print configuration limitations GitHub Issues
2023-03-28 selenium-print Python package released to work around limitations PyPI
2024-03-04 Robot Framework users report PDF save issues robotframework.org forum
2025-ongoing Stack Overflow questions about headless PDF issues continue Stack Overflow

Community Reports

"I get a print preview window to print the invoice. I need to save the invoice as PDF to a specific folder."
GitHub user, selenide/selenide#2152, February 2023

The fundamental problem: Selenium's print feature is designed for browser print dialogs, not automated document generation. Developers spend significant effort working around this mismatch.

Stack Overflow contains numerous questions about saving pages as documents in Selenium. The accepted answers often require:

  • Base64 encoding and decoding
  • Chrome DevTools Protocol commands
  • Custom print settings configuration
  • Waiting for print dialogs
  • Handling headless vs headed mode differences

Each workaround adds complexity and potential failure points to what should be a simple operation.

Root Cause Analysis

Selenium WebDriver's architecture creates several fundamental problems when used for document generation:

Testing Framework, Not Production Library

Selenium optimizes for the testing use case:

  • Sessions are short-lived (single test or test suite)
  • Failures trigger test failures (expected behavior)
  • Resource consumption matters less than test accuracy
  • One browser instance typically runs at a time

Production document generation has opposite requirements:

  • Processes may run continuously
  • Failures must be recovered gracefully
  • Resource efficiency directly affects infrastructure costs
  • Concurrent generation is essential for throughput

Browser Process Overhead

Each Selenium session creates:

  1. A separate browser process (300-500 MB RAM minimum)
  2. A WebDriver process managing the browser
  3. Multiple child processes for rendering, networking, GPU
  4. Shared memory segments, temporary files, and sockets

For a testing scenario running 100 tests sequentially, this overhead amortizes across the test suite. For document generation producing 100 documents in parallel, the system must maintain 100 complete browser stacks simultaneously.

ChromeDriver Version Coupling

Chrome releases new versions approximately every four weeks. Each major version requires a matching ChromeDriver version. The selenium-manager tool attempts to download matching drivers automatically, but:

  • Network restrictions in enterprise environments block driver downloads
  • Container images become stale between builds
  • Multiple Chrome installations create version confusion
  • Browser auto-updates break previously working systems
selenium.common.exceptions.SessionNotCreatedException:
Message: session not created: This version of ChromeDriver only
supports Chrome version 121
Current browser version is 122.0.6261.57
Enter fullscreen mode Exit fullscreen mode

This error appears repeatedly in production logs when systems fall out of sync.

Headless Mode Limitations

Selenium's headless mode addresses the display requirement but introduces its own problems:

  • Some CSS and JavaScript features behave differently in headless mode
  • Print-to-PDF results may differ from headed browser output
  • Debugging headless failures requires special tooling
  • Screenshot and visual comparison features work differently

The Selenium documentation itself notes these differences and recommends testing in both modes, adding to the complexity burden.

Attempted Workarounds

Developers have created various workarounds for Selenium document generation issues:

Workaround 1: Chrome DevTools Protocol Direct Access

Approach: Bypass Selenium's print API and send CDP commands directly to Chrome.

# Python example using CDP for PDF
import base64
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://example.com')

# Send CDP command directly
result = driver.execute_cdp_cmd('Page.printToPDF', {
    'landscape': False,
    'printBackground': True,
    'preferCSSPageSize': True
})

# Decode base64 result
pdf_data = base64.b64decode(result['data'])
with open('output.pdf', 'wb') as f:
    f.write(pdf_data)
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Requires understanding of Chrome DevTools Protocol
  • CDP commands differ across Chrome versions
  • Still inherits all browser process overhead
  • Adds complexity to already complex Selenium setup
  • Firefox and Edge use different protocols

Workaround 2: WebDriverManager for Version Handling

Approach: Use tools like WebDriverManager or selenium-manager to automatically download matching driver versions.

// Java example with WebDriverManager
import io.github.bonigarcia.wdm.WebDriverManager;

public class PdfGenerator {
    public void setup() {
        // Automatically downloads matching ChromeDriver
        WebDriverManager.chromedriver().setup();
        WebDriver driver = new ChromeDriver();
    }
}
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Requires network access for driver downloads
  • Downloads happen at runtime, adding startup latency
  • Corporate proxies may block download URLs
  • Does not solve the underlying resource consumption problem
  • Still requires browser installation

Workaround 3: Browser Pooling

Approach: Maintain a pool of pre-warmed browser instances to reduce per-document startup costs.

// C# example concept - browser pooling
public class BrowserPool
{
    private ConcurrentBag<IWebDriver> _availableDrivers;

    public IWebDriver GetDriver()
    {
        if (_availableDrivers.TryTake(out var driver))
            return driver;
        return CreateNewDriver();
    }

    public void ReturnDriver(IWebDriver driver)
    {
        // Reset browser state
        driver.Navigate().GoToUrl("about:blank");
        _availableDrivers.Add(driver);
    }
}
Enter fullscreen mode Exit fullscreen mode

Limitations:

  • Browser state leaks between documents (cookies, local storage)
  • Memory grows over time requiring periodic restarts
  • Pool sizing requires careful tuning
  • Crashed browsers must be detected and replaced
  • Significantly increases code complexity

A Different Approach: IronPDF

Selenium WebDriver excels at its designed purpose: testing web applications. For document generation, dedicated libraries that embed rendering engines directly provide a more appropriate architecture.

IronPDF embeds a rendering engine as a .NET library, eliminating the external browser process model that causes Selenium's production challenges. The architectural difference affects every aspect of document generation:

Why IronPDF Avoids These Issues

No external browser process: IronPDF's rendering engine runs in-process, eliminating the inter-process communication overhead, startup latency, and crash recovery complexity of Selenium's browser automation model.

No driver version management: The rendering engine ships as part of the NuGet package. Version compatibility is guaranteed at compile time rather than discovered at runtime.

Designed for production: Memory management, concurrency handling, and error recovery optimize for document generation rather than interactive browsing.

Server environment native: No display configuration, no window manager requirements, no X11 or virtual framebuffer setup for Linux deployments.

Code Example

using IronPdf;

public class DocumentGenerator
{
    public void GenerateInvoiceDocument()
    {
        // ChromePdfRenderer provides the rendering engine
        // No external browser process required
        var renderer = new ChromePdfRenderer();

        // Configure page settings directly
        renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.PrintHtmlBackgrounds = true;

        // Render HTML directly to PDF
        // Supports full CSS, JavaScript, and modern web standards
        string invoiceHtml = GetInvoiceHtml(customerId: 12345);
        var pdf = renderer.RenderHtmlAsPdf(invoiceHtml);

        // Save directly - no base64 encoding/decoding required
        pdf.SaveAs("/documents/invoices/invoice-12345.pdf");
    }

    public void GenerateFromUrl(string url)
    {
        var renderer = new ChromePdfRenderer();

        // Convert any URL to PDF
        // Handles JavaScript rendering, authentication, custom headers
        var pdf = renderer.RenderUrlAsPdf(url);
        pdf.SaveAs("webpage.pdf");
    }

    private string GetInvoiceHtml(int customerId)
    {
        // Your HTML template logic
        return $"<html><body><h1>Invoice #{customerId}</h1></body></html>";
    }
}
Enter fullscreen mode Exit fullscreen mode

Key differences from Selenium approach:

The ChromePdfRenderer class embeds rendering capabilities directly. No WebDriverManager.chromedriver().setup(), no new ChromeDriver() with service configuration, no execute_cdp_cmd for PDF output.

Page settings use direct properties rather than JSON configuration objects that must be serialized to Chrome DevTools Protocol format.

Output goes directly to a file path rather than requiring base64 decoding of CDP response data.

API Reference

For complete documentation on the methods shown:

Resource Comparison

The architectural differences produce measurable resource impacts:

Memory Usage Per Document

Selenium WebDriver approach:

  • Chrome browser process: 300-500 MB base
  • ChromeDriver process: 20-40 MB
  • Additional per-tab overhead: 50-100 MB
  • JavaScript heap for page: varies by content
  • Total: 400-700 MB minimum per concurrent document

IronPDF approach:

  • Single .NET process with embedded engine
  • Memory scales with actual document content
  • No separate driver process
  • No browser UI overhead
  • Typical: 50-150 MB for most documents

Startup Time

Selenium WebDriver approach:

  1. Launch ChromeDriver process
  2. ChromeDriver launches Chrome
  3. Chrome initializes rendering subsystems
  4. WebDriver session established
  5. Navigation to content URL
  6. Page load and JavaScript execution
  7. Print command execution
  8. Base64 response transfer

Total: 2-5 seconds for simple documents

IronPDF approach:

  1. Call RenderHtmlAsPdf or RenderUrlAsPdf
  2. Internal rendering
  3. PDF bytes available

Total: Sub-second for simple documents

Concurrency Scaling

Selenium document generation faces a fundamental scaling ceiling: each concurrent document requires a complete browser stack. At high concurrency, systems exhaust available memory, file descriptors, or process limits.

IronPDF's in-process model allows efficient concurrent rendering limited primarily by CPU cores and available memory for actual document content rather than browser infrastructure.

Migration Considerations

Licensing

IronPDF is commercial software. A license is required for production deployment. Free trial licenses are available for evaluation. Developers should review the pricing page to understand the cost structure for their use case.

API Differences

Migrating from Selenium involves conceptual changes:

Selenium Pattern IronPDF Equivalent
new ChromeDriver() new ChromePdfRenderer()
driver.get(url) renderer.RenderUrlAsPdf(url)
execute_cdp_cmd('Page.printToPDF', ...) renderer.RenderHtmlAsPdf(html)
Base64 decode result Direct PdfDocument object
driver.quit() Renderer is disposable or reusable

What You Gain

  • Elimination of ChromeDriver version management
  • Reduced memory footprint (50-80% typical reduction)
  • Lower startup latency for document generation
  • Simplified deployment without browser installation requirements
  • Production-oriented error handling and logging
  • Direct .NET integration without process boundaries

What to Consider

  • Commercial license required for production use
  • Different API requires code changes
  • Some edge cases in browser rendering may differ
  • Learning curve for IronPDF-specific features

Conclusion

Selenium WebDriver solves the browser automation problem effectively. Attempting to repurpose it for production document generation creates ongoing maintenance burden, resource inefficiency, and reliability challenges. Libraries designed specifically for document generation, such as IronPDF, provide architectures that match production requirements without the overhead of test automation frameworks.


Jacob Mellor is CTO at Iron Software and originally built IronPDF.


References

  1. Selenium Print Page Documentation{:rel="nofollow"} - Official Selenium documentation on print functionality
  2. Print Page as PDF in Selenium 4{:rel="nofollow"} - Sauce Labs blog on Selenium 4 PDF feature
  3. How to Generate PDF With Selenium - Baeldung{:rel="nofollow"} - Java tutorial on Selenium PDF generation
  4. Stack Overflow: Save page as PDF in Selenium{:rel="nofollow"} - Community discussion of implementation challenges
  5. selenium-print PyPI Package{:rel="nofollow"} - Third-party wrapper addressing Selenium PDF limitations
  6. GitHub: Selenide print-to-pdf issue{:rel="nofollow"} - Issue discussion on print configuration limitations

For the latest IronPDF documentation and tutorials, visit ironpdf.com.

Top comments (0)