Your files never leave your device
Every tool on this site runs inside your browser tab. There is no server that receives files, because there is no server that does any work: the site is a set of static pages and a PDF engine that your browser downloads once and runs itself.
How it works
The engine is PDFium, the same code Chrome uses to display PDFs, compiled to WebAssembly (version 2.15.1 of the @embedpdf/pdfium build, 4.6 MB), together with pdf-lib (version 1.17.1) for assembling documents. Both come from this site's own address and run in a Web Worker in your tab. When you drop a file, the bytes go from your disk into that worker and back to your disk as a download. Nothing in between is a network.
One more piece of code is fetched only when it is needed: the HEIC decoder (libheif version 1.23.2, 2 MB, LGPL), the first time you drop an iPhone photo. It, too, comes from this site's own address and runs in the worker; the photo does not go anywhere to be decoded.
OCR works the same way. On the OCR page, when you start reading a file, the tab fetches Tesseract (tesseract.js version 7.0.0, about 1.5 MB, Apache-2.0) and the language file you picked (0.7 to 3 MB each) from this site's own address. Tesseract runs in a worker of its own inside your tab; the pages it reads are handed to it there and never leave the device. Its files are kept by the browser's ordinary cache, not stored anywhere else.
The editor fetches fonts from this site's own address when a change needs one: Liberation Sans, Serif or Mono (SIL Open Font Licence) for text with letters the standard PDF fonts lack, such as ł or ř, and Caveat for a typed signature, which is then drawn as outlines, so the font itself never goes into your file. A signature you draw, type or upload is kept in the tab only and forgotten when you close it.
Turn Wi-Fi off and try it
The engine is fetched the first time you drop a file, and from then on a service worker keeps it and the pages on your device. So: use any tool once, switch the connection off, open the site again and drop a file. It works the same, which is the simplest proof that it never needed a server.
What the browser enforces
Every page is served with a Content Security Policy whose connect-src is 'self': the browser refuses any connection from this page to any address but this site's own. That is not a promise in a policy document; it is a rule the browser applies to every line of code on the page, ours or a dependency's. There are no third-party scripts, no font service, no CDN, and no cookies: your browser talks to this site and nothing else.
What is counted, and what goes to Google Analytics
After a tool finishes, the page sends one small message to this site: the tool's id, whether it succeeded, and two buckets (how long it took, how big the input was, each from a short fixed list). No file name, no file size in bytes, no address, no identifier, no cookie. The Worker that receives it drops anything that is not one of the fixed values. The running total is public at /status. The code that sends it is src/app/counter.ts; the code that receives it is worker/index.ts.
When a page is shown, it sends one more small message to this site: the page's address and title on this site (such as /merge-pdf), the name of the site that linked here (such as www.google.com, without the page or search), and any campaign tags in the link. This site's server passes it on to Google Analytics as a page view, so we can see which pages people find and from where. Your browser never connects to Google: there is no Google script on the page and no cookie. Google receives the page and its title, the linking site, your country, the kind of device, browser and system, your language, and an id that is a one-way scramble of your internet address and browser with a random key that changes every day and is deleted the next. It does not receive your address, and tomorrow the same visit counts as someone new. No file, file name or anything typed into a tool is ever part of it. The code is src/app/counter.ts and worker/pageview.ts.
Passwords
A password you type to open or protect a file is used by the engine in your tab and discarded. It is not stored anywhere, not in this browser and not on a server, because there is no server.
What stays on your device
The site's own files and the engine, in the browser's cache, so it works offline. When you send files from the home page to a tool page, they pass through this browser's IndexedDB for the moment of navigation and are deleted when the tool page reads them.
While a document is open in the editor and has changes, a recovery copy of it (the edited file, and any areas marked for redaction) is kept in the same IndexedDB, a moment after each change, so a closed tab or a crash does not lose the work. Only this site's pages in this browser can read it, and it is never sent anywhere. Closing the file in the editor deletes it, and so does Discard on the notice that offers it back. Files over 200 MB get no copy. Clearing this site's data in the browser removes it too. Nothing else is written.
Who runs this
getPDF is made by the same person as getSVG, getPNG and getReport, on the same promise. Hosting is paid by optional tips. Questions: hello@getpdfs.app.