Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a worker that renders each record into print-focused HTML, converts it with an isolated PHP PDF renderer, enforces page parity at every record boundary, and validates the finished file before delivery. For duplex jobs, the difficult part is not producing a PDF; it is guaranteeing that every front and back lands on the intended sheet side. The workflow below covers renderer choice, HTML/CSS constraints, PHP code, parity rules, validation, scaling, and recovery from common failures.

Choose the renderer for your template

Dompdf, mPDF, and TCPDF (including the newer tc-lib-pdf line) can generate PDFs from HTML, but they are not browser engines. Design the template for the renderer you select rather than assuming that browser CSS will work unchanged.

Renderer What it handles well Important constraints for duplex batches
Dompdf PHP HTML-to-PDF conversion with a mostly CSS 2.1 layout engine and selected CSS3 features such as @import, @media, and @page. The project warns that one Dompdf instance should not render more than one HTML document, because parsing and rendering artifacts can persist into later renders. Create a fresh instance for each document or isolated batch unit.
mPDF UTF-8 HTML, headers and footers, page numbering, tables of contents, barcodes, and documented conditional page breaks for double-sided output. Its manual describes the library as dated; templates often need mPDF-specific CSS and markup rather than modern browser layout.
TCPDF / tc-lib-pdf A supported HTML/CSS subset without a browser engine. addHTMLCell() can perform automatic page and region breaks, while getHTMLCell() returns operators for caller-controlled placement. Paged-media controls include page-break rules, orphans, widows, and print media. You must stay inside the documented HTML/CSS subset and take responsibility for placement when exact front/back registration matters.

Compare candidates on CSS fidelity, @page and break-rule support, Unicode and font embedding, parity controls, memory behavior, deployment dependencies, and how easily you can inspect record boundaries. Do not use a throughput number from another project: measure your PHP version, template, fonts, images, and hardware together.

Design the duplex document before writing PHP

Define the logical unit

Decide whether one record is one page, a front/back pair, or a variable-length section. Give each logical side a self-contained wrapper and an explicit boundary. If a record must always occupy exactly two pages, the parity calculation is simple: every new record starts on the same side. Variable-length records require conditional parity breaks.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Brother DCP-L2640DW Wireless Compact Monochrome Multi-Function Printer, Copy, Scan, Duplex, Mobile Printing
  • BEST FOR SMALL BUSINESSES – Engineered for extraordinary productivity, the Brother DCP-L2640DW Monochrome (Black & White) 3-in-1 combines laser printer, scanner, copier in one compact footprint and delivers high-quality black & white prints
  • FAST PRINTER WITH EFFICIENT SCANNING – Produces documents quickly with print speeds up to 36 ppm(2) and scan speeds up to 23.6/7.9 ipm(3) (black/color). A 50-page auto document feeder(4) allows for convenient, time saving multi-page scanning and copying
  • FLEXIBLE CONNECTION OPTIONS – Easily navigate the changing demands of your business with secure multi-device connectivity via built-in dual-band wireless (2.4GHz / 5GHz) and Ethernet. Or connect locally to a single computer via USB interface
  • BROTHER MOBILE CONNECT APP – Print, scan, and manage your wireless printer anytime, from almost anywhere from your mobile device. Order Brother Genuine Supplies, track toner usage, and complete more work on-the-go(5)
  • CHOOSE BROTHER GENUINE TONER – When it’s time to replace your toner, be sure to choose Brother Genuine TN830 or TN830XL replacement toner. And with Refresh EZ Print Subscription Service, you’ll never worry about running out of toner again and you’ll enjoy savings of up to 50%(6) on Brother Genuine Toner. Get started with Refresh today with a Free Trial(1)

Use print CSS that the engine supports

  • Set paper size and margins with @page; leave a safe margin for the printer’s non-printable area and any bleed.
  • Use explicit page-break markers at record boundaries. Do not rely on flexbox, grid, JavaScript, or generated content unless your selected engine documents support for them.
  • Reserve space for headers, footers, barcodes, and registration marks in the layout, not by letting content push them onto another page.
  • Embed the exact font files required for Unicode text and consistent metrics. A fallback font can change line wrapping and therefore page parity.
  • Prepare images at the resolution needed at final paper size; oversized source images increase memory use without improving output.

Make front/back geometry intentional

For short-edge or long-edge binding, the printer may mirror the back side differently. Place marks and artwork according to the binding edge, and test a physical two-page sample. A PDF can have correct page numbers while still producing an upside-down or laterally misregistered back.

PHP batch architecture

  1. Load and validate rows. Reject missing identifiers, malformed URLs, invalid dates, and values outside the template’s limits before starting rendering.
  2. Render one record (or a bounded chunk). Escape all data and use local, deterministic assets. Never let an arbitrary row inject HTML or CSS.
  3. Create a fresh renderer. Isolate an instance per document or bounded batch unit. This is mandatory for Dompdf and a prudent memory boundary for every renderer.
  4. Apply fixed page geometry and breaks. Keep the same paper size, margins, fonts, and break markers throughout a batch.
  5. Track parity. Before a record that must begin on an odd or even page, issue a conditional break. If the current page already has the requested parity, no blank page is added.
  6. Write a temporary PDF. Inspect it before publication, then move it atomically to the final path.
  7. Log reproducibility data. Store the input ID, renderer and PHP versions, template revision, page count, and validation result.

Complete mPDF example with record boundaries

The following example assumes each record has a front and a back section. It uses mPDF’s conditional page-break type: O requests an odd-page start and E requests an even-page start. Confirm the exact method signature against the mPDF version installed in your application.

<?php
declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use MpdfMpdf;
use MpdfOutputDestination;

$rows = [
    ['id' => 'A-100', 'name' => 'Ada Lovelace', 'address' => '1 Example Street'],
    ['id' => 'B-200', 'name' => 'Grace Hopper', 'address' => '2 Example Street'],
];

function e(string $value): string {
    return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

function front(array $row): string {
    return '<section class="side front">'
        . '<h1>Customer card</h1>'
        . '<p class="id">Record: ' . e($row['id']) . '</p>'
        . '<p>' . e($row['name']) . '<br>' . e($row['address']) . '</p>'
        . '</section>';
}

function back(array $row): string {
    return '<section class="side back">'
        . '<h2>Instructions</h2>'
        . '<p>Keep this side aligned with the front when duplex printing.</p>'
        . '</section>';
}

$css = <<<'CSS'
@page { size: A4; margin: 14mm 14mm 16mm 14mm; }
body { font-family: sans-serif; font-size: 11pt; }
.side { page-break-after: always; min-height: 250mm; position: relative; }
.side:last-child { page-break-after: auto; }
.id { font-size: 9pt; }
CSS;

$mpdf = new Mpdf([
    'format' => 'A4',
    'margin_left' => 14,
    'margin_right' => 14,
    'margin_top' => 14,
    'margin_bottom' => 16,
]);
$mpdf->WriteHTML($css, MpdfHTMLParserMode::HEADER_CSS);

$first = true;
foreach ($rows as $row) {
    if (!$first) {
        // Start the next record on an odd page; mPDF adds a blank page only when needed.
        $mpdf->AddPage('', '', 'O');
    }
    $mpdf->WriteHTML(front($row), MpdfHTMLParserMode::HTML_BODY);
    $mpdf->WriteHTML('<pagebreak />', MpdfHTMLParserMode::HTML_BODY);
    $mpdf->WriteHTML(back($row), MpdfHTMLParserMode::HTML_BODY);
    $first = false;
}

$tmp = tempnam(sys_get_temp_dir(), 'cards-');
$mpdf->Output($tmp, Destination::FILE);

$final = __DIR__ . '/out/cards.pdf';
if (!is_dir(dirname($final))) {
    mkdir(dirname($final), 0775, true);
}
rename($tmp, $final); // atomic on the same filesystem

echo "Wrote {$final}n";

For a record that must begin on an even page, use AddPage('', '', 'E'). If your installed mPDF release exposes a different argument order, use its AddPage reference and retain the same rule: request the desired parity and let the renderer add a page only when the current page does not match.

Dompdf and TCPDF implementation notes

Dompdf

Build one complete HTML document per isolated Dompdf instance. Set paper and orientation explicitly, load only approved local assets, call render(), and save the output. Do not reuse the object for the next document; persisted parsing and rendering artifacts can affect later renders. Dompdf’s CSS support is strongest when the template stays close to CSS 2.1 with its documented additions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Brother HL-L2405W Wireless Compact Monochrome Laser Printer with Mobile Printing, Black & White Output | Includes Refresh Subscription Trial(1), Works with Alexa
  • BEST FOR HOMES & HOME OFFICES – Engineered for consistent, premium print quality, the Brother HL-L2405W Monochrome (Black & White) Laser Printer delivers sharp, crisp prints at an affordable price. Prints one-sided documents at speeds up to 30ppm(2)
  • COMPACT, CONNECTED PRINTER – Flexible connection options make this an ideal printer for home use and at-home offices. Securely connect to multiple devices with built-in dual-band wireless (2.4GHz/5GHz) or locally to a single computer via USB interface
  • BROTHER MOBILE CONNECT APP – Manage your printer remotely and print from your mobile device anytime, from almost anywhere. Order Brother Genuine Supplies, track toner usage, and complete more work on-the-go(3)
  • VERSATILE PAPER HANDLING – Enjoy seamless, reliable everyday printing with the 250-sheet paper tray(4) and a manual feed slot that enables printing on envelopes and specialty pape
  • BROTHER IS AT YOUR SIDE – Backed by Brother with a 1-year limited warranty and free online, call, or live chat support for the life of your printer

TCPDF or tc-lib-pdf

Use addHTMLCell() when the library should manage automatic page and region breaks. Use getHTMLCell() when your application must place the returned operators at an exact position. Keep HTML simple and use the documented paged-media controls for print output. For duplex jobs, explicit page starts are safer than allowing a long cell to flow across a record boundary.

Validation before releasing a batch

  • Open the PDF and verify the expected page count.
  • Check that every record starts on its intended odd or even page.
  • Confirm no record crosses a forced boundary unexpectedly.
  • Inspect front/back artwork for the printer’s binding-edge orientation.
  • Verify fonts, Unicode text, images, and barcodes at 100% print scale.
  • Ensure every blank parity page is intentional and represented in internal logs or metadata.
  • Run a small deterministic fixture after changing PHP, the renderer, fonts, images, or the template.

Validation can be automated with the PDF parser or command-line inspection tools already approved in your deployment. Treat a page-count or boundary mismatch as a failed job, not as a warning.

Scaling, memory, and reliability

Use bounded work units

Very large HTML documents consume memory in both parsing and layout. Process a bounded number of records per worker, write each unit to a temporary file, and merge only if your PDF toolchain supports a tested merge step. Isolated units also make retries cheaper and prevent one malformed row from invalidating an entire run.

Make jobs repeatable

Pin the renderer and PHP versions, template revision, font files, and image assets. Keep inputs ordered by a stable key. Record a checksum or revision for each template so a regenerated batch can be compared with the original.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Canon imageCLASS LBP6030w - Monochrome Single-Function Wireless Compact Wireless Laser Printer, 1 Year Limited Warranty, 19 PPM, White - Print Only
  • FAST PRINT SPEEDS: Print up to 19 pages per minute.
  • COMPACT DESIGN: Space-saving, compact design fits anywhere in your home, school or small office.
  • WIRELESS CONNECTIVITY: Print from almost anywhere in your workspace using your compatible mobile device.
  • PAPER CAPACITY: Up to 150 sheets.
  • SUSTAINABILITY: Uses less than 2 watts in Energy Saver mode.

Handle failures safely

Use a queue with retries for transient asset or filesystem failures, but do not retry deterministic validation failures indefinitely. Keep the temporary file private, verify it, then atomically rename it. Never replace a previously released PDF with a partially rendered file.

Common failures and fixes

Front and back drift to the wrong side

The document is missing an explicit boundary or the parity rule is applied after content has already been written. Add the conditional break before the next record and log the page number at that point.

A blank page appears unexpectedly

A conditional break is doing its job, or an extra CSS break is present. Inspect both the renderer call and the template’s page-break-* rules; keep one authoritative boundary mechanism.

Content is clipped or overlaps the footer

Margins, header/footer reservations, or a fixed-height container exceed the printable area. Reduce content, increase the margin, or move the element into the normal flow. Do not solve it with a browser-only CSS rule the renderer does not support.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Brother HL-L2460DW Wireless Compact Monochrome Laser Printer with Duplex, Mobile Printing, Black & White Output | Includes Refresh Subscription Trial(1), Works with Alexa
  • BEST FOR HOME OFFICES & SMALL TEAMS – Engineered for consistent, premium print quality, the Brother HL-L2460DW Monochrome (Black & White) Laser Printer produces documents that are clear, crisp, and easy to review and share, all at an affordable price
  • COMPACT, CONNECTED, EXCEPTIONALLY EFFICIENT– Connect with built-in dual-band wireless (2.4GHz/5GHz), Ethernet, or to a single computer via USB interface. Prints at speeds up to 36ppm(2), plus automatic duplex printing saves time and reduces paper waste
  • BROTHER MOBILE CONNECT APP – Manage your wireless printer remotely and print from your mobile device anytime, from almost anywhere. Order Brother Genuine Supplies, track toner usage, and complete more work on-the-go(3)
  • VERSATILE PAPER HANDLING – Tackle high-volume black & white printing with the 250-sheet capacity paper tray.(4) The manual feed slot enables printing on envelopes and specialty paper
  • BROTHER IS AT YOUR SIDE – Backed by Brother with a 1-year limited warranty and free online, call, or live chat support for the life of your printer

Unicode characters become boxes

The required font is not embedded or the renderer cannot locate it. Configure and embed the exact font files, verify the font license for server use, and rerun the deterministic fixture.

Images or barcodes disappear

The asset path is unavailable to the worker, remote retrieval is blocked, or the format is unsupported. Prefer local, deterministic assets and check the renderer’s supported image formats and permissions.

Later documents change after rendering earlier ones

This is a classic instance-reuse problem, especially with Dompdf. Construct a new renderer for each document or isolated batch unit.

The worker runs out of memory

Reduce the batch size, avoid embedding unnecessarily large images, and recycle the renderer between units. Measure the target workload; no universal throughput or memory figure applies across templates and environments.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
HP LaserJet M209dw Wireless Printer, Print, Fast speeds, Easy Setup, Mobile Printing, Best-for-Small Teams, Instant Ink Eligible
  • HP LaserJet M209dw Wireless Printer, Print, Fast speeds, Easy setup, Mobile printing, Best-for-small teams, Instant Ink eligible
  • Perfect for small teams printing black & white documents and reports, plus auto two-sided printing. Perfect for 1-5 people
  • FASTEST TWO-SIDED PRINTING IN ITS CLASS – Up to 30 black-and-white pages per minute single-sided, u up to 19 black-and-white images per minute two-sided printing
  • DUAL-BAND WI-FI WITH SELF-RESET – Automatically detects and resolves connectivity issues
  • STRONG SECURITY – Built-in security features help protect your printer from potential attacks
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your source is already available at a stable URL, ScreenshotNeo can capture it without maintaining a headless-browser worker. It accepts the cookie or consent banner as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its PDF capture supports paper size, margins, landscape mode, and page ranges. You can also use custom CSS and JavaScript, wait for a selector or network idle, set cookies and headers, block resource types, and run bulk capture for up to 100 URLs per call.

Host each rendered HTML document at an authenticated or signed URL, then call the API. The request pattern below is documented at ScreenshotNeo’s API documentation; configure PDF output and print options there when the endpoint is used for PDF rather than the default image response.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo: ${res.status}`);

An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Plans are:

Plan Included shots per month Price
Free 1,000 $0, no card
Starter 3,000 $5
Growth 15,000 $15
Pro 60,000 $39
Scale 250,000 $99
Business 1,000,000 $249

Yearly billing gives two months free, and every feature is included on every plan. Create a free ScreenshotNeo account to start with 1,000 shots a month and no card.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Should each record be rendered as its own PDF?

Use separate PDFs when independent delivery or retrying individual records matters; use one batch PDF when a print run must remain a single ordered file. In either case, preserve the same parity and validation rules.

How do I test duplex alignment without wasting a full print run?

Print a two-record fixture on ordinary paper, mark the top edge and binding edge, and compare both sides at 100% scale before approving the production batch.

Can a browser screenshot service replace a PHP renderer for arbitrary private data?

Only when the service can reach the rendered URL securely. Use signed or authenticated URLs, avoid exposing sensitive rows publicly, and keep the PHP renderer for data that cannot leave your controlled environment.

The Bottom Line

Reliable duplex PDFs come from deterministic templates, isolated renderer instances, explicit parity breaks, and automated boundary validation. Choose the engine whose supported CSS matches your template, then treat every unvalidated page as a failed batch.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.