Yes. Compress PDF shrinks a file entirely inside your browser tab — the bytes never leave your device, there’s no server involved, and no account or email is required. That’s a specific, checkable claim about where the computation happens, not a vague privacy slogan, and it’s worth walking through exactly how the size reduction works, because the mechanism explains both what this is good at and where it genuinely falls short.
How the compression actually works
The size reduction comes from one technique, applied to every single page: rasterize it, then re-encode it as a lower-quality JPEG.
Concretely, step by step:
- Your PDF is read locally via
file.arrayBuffer()— the browser’s File API handing the tab a copy of the bytes already sitting on your disk. - pdfjs-dist — Mozilla’s PDF rendering engine, the same one that powers Firefox’s built-in PDF viewer — opens the file and, for each page, renders it onto an off-screen HTML
<canvas>at a chosen scale. This is the identical rendering pipeline a PDF viewer uses to draw a page on your screen; it’s just being captured into a bitmap instead of shown to you. - That canvas bitmap gets re-encoded as a JPEG via
canvas.toBlob(..., "image/jpeg", quality), at whatever quality value (0 to 1) the compression pass has settled on. pdf-libthen builds an entirely new PDF from scratch — one page per original page, and each page is just that single JPEG, sized back to match the original page’s physical dimensions so nothing changes on screen.
There’s no separate step that hunts for “the embedded images” and leaves the rest alone. The whole page — text, vector art, existing photos, all of it — gets flattened into one picture and re-compressed as that picture. The size savings come entirely from JPEG’s lossy compression doing its job on that flattened image.
Two ways to control the trade-off, both driving the same mechanism underneath:
-
Quality mode (buttons: Low / Recommended / Extreme) uses a fixed render scale and a fixed JPEG quality per preset — roughly 85%, 60%, and 35% — in a single pass. Predictable, no guesswork about what you’ll get.
-
Target-size mode (with presets for common Indian application-portal limits, plus a custom KB field) works backwards from a byte budget you specify: it binary-searches JPEG quality between 5% and 95% over up to six passes at a starting render scale, looking for the highest quality that still lands under your target. If even the lowest quality at that scale wouldn’t fit — or if hitting the target would mean crushing quality below a legibility floor — it steps the render scale down (roughly 1.5x → 1.1x → 0.85x → 0.65x) and re-runs the same search. A smaller image at a decent JPEG quality reads better than a full-size page crushed to near-zero quality, so trading resolution for quality is the deliberate fallback once a fixed size stops being enough. Whatever it lands on — the best fit under target, or the smallest result it could manage if nothing fit — is what you get, and the result screen tells you plainly whether it actually made your target or not. It doesn’t quietly report success when it didn’t.
That search has a real cost worth knowing about: each of the up to four render scales means re-rendering every page from scratch, and at each scale the quality search can run up to seven full passes — render, JPEG-encode every page, measure the result — before it either settles or steps down to a coarser scale. So a long, dense scan pinned to a tight KB limit can take several seconds rather than feeling instant. That’s not lag; it’s the tool actually working through resolutions and quality levels in sequence, on your own CPU, because there’s no server to hand the job to.
The trade-off worth knowing before you use this
Because the mechanism rasterizes the entire page, not just its images, there’s a real cost that’s easy to miss: a compressed page is no longer real text.
For a scanned document, this costs you nothing — a scanned page was already just a photograph with no text layer underneath it, so re-encoding that photograph at a lower quality loses nothing that was searchable to begin with. This is where the tool does its best work: scanned and photo-heavy PDFs routinely shrink to a fraction of their original size with little visible difference.
For a PDF that started as real text — exported from Word, Google Docs, or anything else that stores actual character objects — compressing it means Ctrl+F stops finding anything on that page, and you can no longer select or copy a sentence out of it. The words are still visually there, but only as pixels now, the exact same situation as an unrecognized scan. That’s not a bug to work around; it’s the direct, structural consequence of how this specific compression technique works, and it’s why the tool’s own guidance nudges you toward it mainly for scanned or photo-heavy files rather than presenting itself as a universal shrink-everything button.
What “without uploading” means here, concretely
Every step above — reading the file, rendering pages, re-encoding JPEGs, assembling the new PDF — runs as ordinary code executing on your CPU, using pdfjs-dist and pdf-lib, both shipped as part of this site’s own JavaScript bundle rather than fetched from some processing server at the moment you use the tool. The output comes back as bytes already sitting in your browser’s memory, offered to you as a direct download. At no point does a fetch or XMLHttpRequest carrying your file’s contents get made — not because of a policy promise, but because there’s nothing in that code path that does it.
You don’t have to take that on faith. Open your browser’s dev tools, go to the Network tab, clear it, then run a compression on a real file. You’ll see no outbound request anywhere near the size of your PDF — because nothing is being sent anywhere. (If you want the fuller mechanical picture of how and why this holds for the rest of the toolkit too, this site covers it in more depth separately.)
The honest limits
- Text-only PDFs don’t shrink much, and shouldn’t be pushed hard. A PDF that’s mostly text and vector graphics is already compact — text objects and simple vector paths take up very little space compared to a rasterized JPEG of the same page. Rasterizing a text-heavy document to save a modest amount of space, while destroying its searchability, is usually a bad trade. If a document needs to stay real text, compression generally isn’t the right tool for it.
- A tight target can still fail, and the tool says so. The quality search and the scale step-down only have so much room to work with. A genuinely small target size on a many-page or image-dense document may still land above budget after every fallback — the result screen reports that honestly (closest result achieved, target not met) rather than silently handing you something that doesn’t actually satisfy your limit.
- This isn’t structural PDF optimization. It doesn’t strip unused fonts, deduplicate repeated objects, or recompress internal streams the way some desktop tools do — it’s specifically image re-encoding, applied uniformly. That’s a deliberate, narrow tool, not a general-purpose “clean up this file” pass.
- Password-protected PDFs need unlocking first. The compressor opens your file with pdfjs-dist to read its pages, and that call doesn’t prompt for a password — so it can’t open a PDF that requires one, and the operation just fails. Remove the password first, compress the result, then reapply protection afterward if you still need the file locked.
- Anything that isn’t visible ink gets left behind. Because every page is rebuilt from a flat image, a hyperlink, a fillable form field, or a digital signature object on that page doesn’t come along for the ride — the new PDF is built purely from JPEGs, with nothing else copied over. The page can look pixel-identical and still have lost everything interactive on it. If a file needs to stay fillable, or its links need to stay clickable, keep the original alongside the compressed copy rather than replacing it.
- One file at a time. There’s no batch mode — no multi-file drop zone, no queue. If you’ve got several documents that all need to hit the same size limit (a stack of certificates for one application, say), compressing several PDFs to the same target is quicker than it sounds once you know the target number stays selected between files.
Who actually needs this
The presets in the tool itself are a good tell for the most common real cases: application portals with hard upload caps (scholarship and admission portals with specific KB limits are a recurring pain point), email attachment limits, and general storage or transfer constraints where a large scanned file just needs to be smaller. If your document is a scanned form, a photographed receipt, or a many-page scanned agreement, and something is refusing it for being too large, this is exactly the situation it’s built for.
Where it doesn’t matter: a PDF that’s already comfortably under whatever limit you’re working against doesn’t need compressing at all, and a text-based report or contract that’s a few hundred KB to begin with has little to gain and a real searchability cost to lose. Check the actual file size first — Reduce a PDF’s File Size for Email walks through the same tool from that specific angle if an email attachment limit is what’s blocking you. And if your problem is a large PDF loading slowly on a website rather than being too big to send, that’s a different mechanism entirely — see Why Your PDF Takes Forever to Load on Your Website — compression and linearization solve different problems and can be used together.