BeanNestTools

PDF internals research

How PDF Structural Overhead Hides Inside Your File

Two PDFs render identically and hold the same content, but one is seven times larger. Where did the extra size go?

The padded PDF fixture isolates one structural change: forty additional small metadata objects are added while the compressed page-content stream remains 250 bytes. Comparing that file with its unpadded twin measures how much those added objects and the associated PDF structure change this specific file, without treating the result as a typical metadata cost.

Reviewed 2026-09-20 by BeanNest Studio

The controlled pair keeps the content stream unchanged

text-40-flate.pdf and text-40-flate-padding.pdf both contain a 250-byte Flate content stream with the same 18.328x inflation sample. The padded fixture differs by the forty additional generated metadata objects.

The measured file growth is 5109 bytes

The unpadded compressed file is 821 bytes and the padded file is 5930 bytes, so the controlled difference is 5109 bytes. That number belongs to this generated pair and includes every byte added by the extra objects and the surrounding file structure.

Object count rises from five to forty-five

The analyzer reports 5 objects for the unpadded fixture and 45 for the padded fixture. At the same time, stream share falls from 30.5 percent to 4.2 percent because the 250-byte content stream is unchanged while the total file grows.

The per-object average is corpus-specific

Dividing the 5109-byte difference by forty gives about 128 bytes per added object in this fixture. That average includes object syntax and the file's larger indexing structure; it is not a floor, a typical PDF metadata size, or a prediction for an XML packet or another writer.

The experiment shows that structure can dominate a small file

In this controlled pair, the added structural bytes are much larger than the page-content stream. That is enough to demonstrate the mechanism the guide needs: two files with the same compressed page content can have very different totals because their object graphs differ.

The corpus does not establish a scaling law

Only one padding count is measured here, so the evidence cannot show whether overhead scales linearly, worse than linearly, or differently across other object counts and PDF writers. Establishing a scaling relationship would require additional fixtures at multiple padding levels.

The arithmetic behind the 5109 bytes

Bytes outside the stream are 571 in the unpadded file and 5680 in the padded one, and 5680 minus 571 is 5109, the same figure as 5930 minus 821 because the 250-byte stream is identical. Dividing by forty gives 127.7, which the guide rounds to about 128 bytes per added object. Every one of those bytes sits outside the page-content stream.

What a stream-only change could and could not do here

In the padded file the content stream is 250 of 5930 bytes, 4.2 percent. A tool that only recompresses streams could touch at most that 4.2 percent, no matter how well it worked, because the other 95.8 percent is structure. That is the practical reading of a low stream share: the saving has to come from somewhere other than the stream.

Questions to ask before blaming the content

When two PDFs show the same pages but very different sizes, compare object counts and stream shares before comparing the pages. A large file with a low stream share points at structure; a large file with a high stream share points at bytes inside streams, such as images, embedded fonts or page content. The measurement here supports that way of asking, not a rule about how many bytes any given object costs.

Structural cost is not evidence that metadata should be removed

The fixture uses deliberately disposable padding to isolate byte cost. Real document information, accessibility structure, fonts, and other objects can serve functional purposes. This measurement supports a size explanation, not a recommendation to strip structural objects from arbitrary PDFs.

Scope of this guide

This research measures how non-content objects contribute to PDF size using an intentionally padded corpus file. It does not describe a specific application's metadata behaviour and does not recommend deleting structural objects.

Method and evidence

We generated four single-page PDFs with BeanNest's own writer, then parsed each file's raw byte structure with BeanNest's own analyzer. Both tools are dependency-free and deterministic, so the same commands reproduce the same numbers on any machine. For this guide we compared the padded corpus file against its unpadded twin, which are identical except for forty additional metadata objects, so the size difference isolates structural overhead from page content.

Environment: Node.js on a desktop workstation. No PDF library, no network access, and no third-party file was used. The corpus is produced from text BeanNest owns.

Captured: 2026-09-20. Re-review trigger: Re-review when the corpus padding model or the analyzer's object detection changes.

Evidence files: kept in BeanNest's source repository, not published on this site.

  • docs/research-evidence/pdf/analysis-2026-09-20.json
  • docs/research-evidence/pdf/README.md

What this guide does not claim

  • recommendations to strip metadata objects for size
  • claims about a specific editor's metadata behaviour
  • assertions that structural objects are always removable
  • size predictions for files outside the corpus

Try the tool this guide explains