PDFPipe

The document is wrong

The generated PDF is far too large

A three-page invoice comes out at eight megabytes. Email gateways reject it, storage costs climb, and the recipient waits to open it.

What is actually happening

Almost always images at their source resolution. A photo straight from a phone is several thousand pixels wide, and putting it in a box 200 pixels across does not resize the file, only the display. The second cause is embedding a full font family when the document uses one weight.

Confirming it is this and not something that looks like it

Divide the file size by the number of images. If it is roughly the size of your source images, that is the whole answer.

The fix

Resize images to the resolution they will actually be printed at before embedding them, and subset fonts to the characters the document uses. For print, three times the CSS pixel width is more than enough; beyond that you are storing detail no printer will reproduce.

python
from PIL import Image

def for_document(source: Image.Image, css_px_width: int) -> Image.Image:
    """Three times the display width covers print resolution. Anything past that
    is bytes nobody will ever see."""
    target = css_px_width * 3
    if source.width <= target:
        return source
    ratio = target / source.width
    return source.resize((target, round(source.height * ratio)), Image.LANCZOS)

If that was not it

These produce the same symptom often enough to be worth ruling out before assuming the fix above did not work.

  • Fonts embedded in full rather than subset to the glyphs used
  • A background image repeated on every page, embedded once per page by some pipelines
  • PNG used for photographs, where JPEG or WebP would be a fraction of the size
  • Vector graphics with tens of thousands of path nodes, common in exported maps

Frequently asked

Does this happen with every rendering engine?

The behaviour behind it is not specific to one tool. Almost always images at their source resolution. Anything rendering HTML to a paged medium has to make the same decision, so the fix travels with you if you change how the render happens.

Will this show up as an error in my logs?

No, and that is what makes it expensive. A document that renders wrong is still a successful render as far as every log line is concerned. It is found by someone opening the file, which is usually the customer.

Related failures

Problems people arrive at from the same starting point, or mistake for this one.

Paste your markup and see the rendered document, without signing up.