← Back to Projects
June 15, 20242 min read

HTML to PDF Serverless Service

High-performance HTML-to-PDF conversion using Puppeteer Core on AWS Lambda with optimized cold-start and concurrent generation support.

Node.jsPuppeteerAWS LambdaS3

HTML to PDF Serverless Service

A high-performance, serverless HTML-to-PDF conversion service built on AWS Lambda, designed to handle large-scale document generation for our fintech platform.

Problem

Our platform needed to generate thousands of PDFs daily — trade confirmations, account statements, settlement reports. The previous solution running on EC2 was:

  • Expensive (always-on infrastructure)
  • Hard to scale during peak hours
  • Prone to memory leaks from Puppeteer instances

Solution

Migrated to a serverless architecture using AWS Lambda with Puppeteer Core:

Architecture

  • AWS Lambda with custom Chromium layer for PDF rendering
  • S3 for storing generated PDFs with pre-signed URLs
  • API Gateway for REST endpoint access
  • SQS for handling batch generation requests

Key Optimizations

  • Cold-start optimization: Pre-loaded Chromium binary with custom Lambda layer
  • Memory management: Careful browser instance lifecycle handling
  • Concurrent processing: Stateless design supporting parallel PDF generation
  • Template caching: Frequently used templates cached in Lambda's /tmp directory

Results

  • 30% cost reduction compared to EC2 infrastructure
  • Sub-3s response time for single PDF generation
  • Auto-scales from 0 to thousands of concurrent executions
  • Zero maintenance — no servers to manage

Technical Highlights

// Lambda handler with optimized Chromium launch
const chromium = require('@sparticuz/chromium');
const puppeteer = require('puppeteer-core');

exports.handler = async (event) => {
  const browser = await puppeteer.launch({
    args: chromium.args,
    executablePath: await chromium.executablePath(),
    headless: chromium.headless,
  });
  
  const page = await browser.newPage();
  await page.setContent(event.html, { waitUntil: 'networkidle0' });
  
  const pdf = await page.pdf({
    format: 'A4',
    printBackground: true,
  });
  
  await browser.close();
  return pdf;
};