Most email providers cap attachments at 20-25 MB. A single scanned report, design export, or photo-heavy presentation can easily exceed that. The fix is compressing the PDF before sending, reducing file size by 50-85% while keeping the document perfectly readable.
This guide covers the fastest free methods, what causes large PDFs, and how to automate compression for recurring workflows.
What causes a PDF to be too large for email
The dominant cause of oversized PDFs is raster image content. Images embedded at print resolution (300 DPI or higher) contain 4x more pixels than needed for screen viewing. A single full-page photo at 300 DPI takes several MB; at 150 DPI the same image takes under 1 MB.
| Content type | Compression potential | Explanation |
|---|---|---|
| Scanned pages (raster) | 70-85% | High-res scans are the biggest offender |
| Embedded photos | 60-80% | Print-res images downsampled to screen DPI |
| Charts and diagrams (vector) | 5-15% | Vectors don't benefit much from DPI reduction |
| Text and fonts | 10-30% | Lossless only: font subsetting, stream compression |
| Pure text, no images | 10-20% | Already compact, limited room to compress |
Reducing image resolution to 150 DPI for email is the single most effective step. At 150 DPI, text and most graphics remain sharp on a screen; the difference only becomes visible when zooming above 200%.
Email attachment size limits by provider
Every major email provider enforces a maximum attachment size. If your PDF exceeds the limit, the email is rejected or held:
| Email provider | Attachment limit | Notes |
|---|---|---|
| Gmail | 25 MB | Offers automatic Google Drive link above limit |
| Outlook / Microsoft 365 | 20 MB | Exchange Online policy; on-premise may differ |
| Yahoo Mail | 25 MB | |
| Apple iCloud Mail | 20 MB | |
| ProtonMail | 25 MB (free), no limit (paid) | |
| Zoho Mail | 20 MB |
For enterprise email systems using Exchange Server, limits are set by the server admin and may be as low as 10 MB. When in doubt, target under 10 MB to ensure reliable delivery.
Method 1: Free browser tool (no upload, no signup)
The fastest way to compress a PDF for email is to use a browser-based tool that processes files locally:
- Go to Compress PDF
- Drop your PDF onto the upload area
- The tool resamples images to 150 DPI and re-encodes them as JPEG at 85% quality
- Download the result (shows new size and reduction %)
Your file never leaves your device. The tool uses pdfjs-dist to render each page and pdf-lib to reconstruct the PDF with resampled images. This is the safest option for confidential documents.
Typical processing time: 2-10 seconds for a 10-page document.
Method 2: Ghostscript (best for batches and scripts)
Ghostscript is the most powerful free PDF compressor and handles batch processing reliably. The /ebook preset is the standard choice for email:
gs -sDEVICE=pdfwrite \
-dCompatibilityLevel=1.5 \
-dPDFSETTINGS=/ebook \
-dNOPAUSE -dBATCH -dQUIET \
-sOutputFile=compressed.pdf input.pdfThe Ghostscript documentation for PDF settings defines four quality presets:
| Preset | DPI | Typical use case |
|---|---|---|
/screen | 72 | Smallest possible, screen-only viewing |
/ebook | 150 | Email and web sharing (recommended) |
/printer | 300 | High-quality print |
/prepress | 300+ | Archival, maximum fidelity |
For email, /ebook hits the right balance. At 150 DPI, text-heavy PDFs look identical to the original on any modern monitor; scanned documents remain fully legible.
Batch compress an entire folder
for f in *.pdf; do
gs -sDEVICE=pdfwrite \
-dPDFSETTINGS=/ebook \
-dNOPAUSE -dBATCH -dQUIET \
-sOutputFile="compressed_${f}" "$f"
doneMethod 3: Python one-liner
If you already have Python installed, the simplest approach calls Ghostscript via subprocess:
import subprocess
from pathlib import Path
def compress_for_email(input_path: str, output_path: str, dpi: str = "ebook") -> None:
"""Compress a PDF to email-friendly size using Ghostscript."""
subprocess.run(
[
"gs",
"-sDEVICE=pdfwrite",
f"-dPDFSETTINGS=/{dpi}",
"-dNOPAUSE",
"-dBATCH",
"-dQUIET",
f"-sOutputFile={output_path}",
input_path,
],
check=True,
)
original = Path(input_path).stat().st_size
compressed = Path(output_path).stat().st_size
reduction = (1 - compressed / original) * 100
print(f"Reduced {original / 1e6:.1f} MB → {compressed / 1e6:.1f} MB ({reduction:.0f}% smaller)")
compress_for_email("report.pdf", "report-email.pdf")This approach works well in CI pipelines and automated document workflows where PDFs need to be email-ready before being sent.
Method 4: macOS Preview (zero install)
On macOS, the built-in Preview app compresses PDFs without any extra software:
- Open the PDF in Preview
- File > Export as PDF
- Set Quartz Filter to "Reduce File Size"
- Save
The Reduce File Size filter applies aggressive compression (equivalent to /screen in Ghostscript). It works well for reducing very large files but may over-compress at 72 DPI. Use Ghostscript if you need more control over quality.
What to do if the PDF is still too large
Some PDFs resist compression because their images are already optimized or the content is mostly vector. In those cases:
Split the PDF into smaller parts
If the document has distinct sections (chapters, months, departments), split it into smaller files and send in separate emails. Each recipient gets only the pages relevant to them.
Remove unnecessary pages before compressing
Review the document and remove pages you don't need to send. Fewer pages means smaller file regardless of compression.
Share via a cloud link
Gmail automatically offers a Google Drive upload link when you attach a file over 25 MB. Dropbox, OneDrive, and iCloud Drive offer similar functionality. Sharing a link sidesteps the attachment size limit entirely, and the recipient gets the full-quality original.
Optimize PDFs at generation time
If you generate PDFs programmatically (invoices, reports, certificates), producing lean output from the start avoids the need to compress afterward. Common causes of bloat in generated PDFs:
- Base64-encoded images larger than their display size
- Full font files instead of subsetted fonts (a 300 KB typeface subsetted to the glyphs actually used weighs 15-30 KB, a 90%+ reduction measured by web.dev)
- Embedded preview thumbnails
PDF4.dev subsets fonts automatically and avoids embedding preview metadata, producing compact PDF output without a separate compression step.
Typical results for email-targeted compression
The table below shows real-world compression results at the /ebook (150 DPI) preset:
| Document type | Before | After | Reduction |
|---|---|---|---|
| 10-page scanned report (300 DPI) | 18 MB | 2.8 MB | 84% |
| 20-page presentation with photos | 32 MB | 7.1 MB | 78% |
| 50-page text report with charts | 8 MB | 3.2 MB | 60% |
| 5-page invoice (text + logo) | 450 KB | 310 KB | 31% |
| Already-compressed export | 3 MB | 2.9 MB | 3% |
Results vary by image resolution, existing compression, and content type. Text-only PDFs compress the least; scanned documents compress the most.
If you generate PDFs from HTML templates (invoices, reports, certificates), PDF4.dev produces compact output by default. No compression step needed. Try it free.
Automating email-ready PDF compression
For teams that send PDFs regularly (weekly reports, monthly invoices, client deliverables), setting up a one-command compression step saves time and prevents "attachment too large" bounce-backs.
A simple shell alias does the job:
# Add to ~/.zshrc or ~/.bashrc
alias compress-email='f() { gs -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -dNOPAUSE -dBATCH -dQUIET -sOutputFile="${1%.pdf}-email.pdf" "$1"; }; f'
# Usage
compress-email quarterly-report.pdf
# Produces: quarterly-report-email.pdfFor a more complete workflow that compresses and checks the output size:
import subprocess
import sys
from pathlib import Path
TARGET_MB = 10 # email-safe limit
def compress_for_email(src: str) -> str:
src_path = Path(src)
out_path = src_path.with_stem(src_path.stem + "-email")
subprocess.run(
["gs", "-sDEVICE=pdfwrite", "-dPDFSETTINGS=/ebook",
"-dNOPAUSE", "-dBATCH", "-dQUIET",
f"-sOutputFile={out_path}", str(src_path)],
check=True,
)
size_mb = out_path.stat().st_size / 1e6
if size_mb > TARGET_MB:
print(f"Warning: output is {size_mb:.1f} MB (still above {TARGET_MB} MB). Consider /screen preset or splitting.")
else:
print(f"OK: {size_mb:.1f} MB — ready for email.")
return str(out_path)
if __name__ == "__main__":
compress_for_email(sys.argv[1])Choosing the right compression level
The right preset depends on how the recipient will use the document:
| Scenario | Recommended preset | DPI |
|---|---|---|
| Email attachment for screen reading | /ebook | 150 |
| Email for archiving (no printing) | /screen | 72 |
| Email that will be printed | /printer | 300 |
| Internal reference document | /ebook | 150 |
| Legal or compliance document | Original or /printer | 300+ |
When in doubt, use /ebook (150 DPI). It hits under 10 MB for most documents while remaining fully legible on screen and acceptable for standard printing.
Summary
To compress a PDF for email:
- Use PDF4.dev's free compress tool for a one-off file (no signup, files stay local)
- Use Ghostscript with
-dPDFSETTINGS=/ebookfor batches and scripts - Target 150 DPI for the right balance of size and quality
- If still too large: split pages or share via a cloud link
For teams generating PDFs programmatically, producing lean output at the source (font subsetting, no embedded thumbnails) is more efficient than compressing after the fact.
Free tools mentioned:
Start generating PDFs
Build PDF templates with a visual editor. Render them via API from any language in ~300ms.