Before dropping a contract, an ID photo or an API log full of keys into an unfamiliar online converter, most people wonder whether the file is being sent to a server. “We do not keep your files” sounds reassuring, but you cannot verify it. The value of browser-local processing is that it turns “do you trust them” into “can you check”.
This guide starts from the data path and explains why a browser is able to do this work locally. It then gives you a set of checks you can run yourself (the Network panel, an offline test, a console snippet), lists which network requests are normal and which should worry you, and ends with what local processing does not protect against and which jobs do not belong in a browser at all. The numbers and behaviors cited here come from the ToolGarden source code, not from marketing copy.
1. The key difference: which road does the file take?
A traditional online converter works like this: the browser uploads the file, the server processes it, and the result is sent back for download. Browser-local processing works differently: the page downloads its program code (HTML, JavaScript, WebAssembly and, when needed, model files), then uses that code to read the file you picked, compute on your machine and hand the result back for saving. There is only one test that matters: after processing starts, does your file content appear in any network request?
| Dimension | Server-side processing | Browser-local processing |
|---|---|---|
| File path | Upload, server, download | Read, compute locally, save; no network in between |
| Privacy exposure | Server logs, buckets, queues and third-party services may touch the file | The file lives in the tab’s memory; what you must trust is the page code itself |
| Speed bottleneck | Upload and download bandwidth | Local CPU, memory and browser limits |
| File size | Server quota | Device memory; tools set caps (ToolGarden’s image tools cap at 50 MB) |
| Offline | Not possible | Some tools work offline once the page and resources are cached |
| Verifiability | You can only trust the privacy policy | You can observe network requests in developer tools |
| Compute power | GPU clusters and large models | Limited to the user’s device; only smaller models are practical |
2. What a browser can actually do locally
All of these are standard browser interfaces and need no plugins:
- File and Blob: read files from a picker, drag and drop or paste; the content goes straight into page memory. Previews use temporary local addresses from URL.createObjectURL, not network addresses.
- Canvas: decode images, resize, overlay text and re-encode as JPG, PNG or WebP. ToolGarden runs image format conversion in a Web Worker first and falls back to the main thread only if needed; the page itself notes that the local Worker is preferred and files are not uploaded.
- Web Workers: move heavy computation to a background thread so the page stays responsive.
- WebAssembly and ONNX Runtime: bring decoders, encoders and AI models that used to run on servers into the browser. ToolGarden’s watermark removal uses the MI-GAN and LaMa ONNX models for local inference; the first run downloads the model files (about 28 MB for MI-GAN), after which inference sends your image nowhere.
- MediaDevices: the QR decoder can open the camera and decode frames locally with jsQR; video frames do not leave the device.
- IndexedDB and Cache Storage: cache models and static assets so the second visit is faster, which is also the basis of offline use.
3. A three-step audit: prove “no upload” with the Network panel
Do not trust a privacy badge on the page; checking for yourself takes two minutes. The key is to let the page finish loading all of its program resources first, clear the log, and only then pick a file, so that everything left in the list was caused by the processing.
- Open developer tools (F12 on Windows and Linux, Option + Command + I on macOS), go to the Network panel and tick Preserve log.
- Load the page and the tool fully, wait for requests to settle, then click the clear button (the circle with a slash).
- Run a conversion on a harmless sample file and watch for new requests. Filter by Fetch/XHR and WS, then look at All again.
| What you see | What it means | Suspicious? |
|---|---|---|
| No new requests | Processing happened locally | Ideal |
| GET for .wasm, .onnx, .js, fonts | On-demand download of code, a model or fonts | Normal; note the direction is download |
| POST/PUT with a body close to your file size | The file content was sent out | That is an upload |
| Content-Type multipart/form-data | A classic form file upload | Highly suspicious unless you submitted a form |
| WebSocket with continuing frames | Data may be streaming out | Inspect frame content and size |
| Small requests of type ping or beacon | Analytics or error reporting | Check whether the payload contains file names or content |
Example: testing with a 20 MB image
Test with an image of around 20 MB. If a POST appears after you select the file and its request body is also around 20 MB, that is an upload. If the list shows either nothing new or only a tiny analytics ping of a few hundred bytes, then 20 MB of data did not leave this page. Compare the request body (Request payload and the Size column in the Network panel), not the page’s overall traffic.
Add a safety net with a console snippet
Some uploads happen at any moment after you pick the file, and a long Network list is easy to skim past. Paste the script below into the console to print the payload type and size for fetch, XMLHttpRequest and sendBeacon calls on the main thread.
const describe = (b) =>
b == null ? 'none'
: b instanceof Blob ? 'Blob ' + b.size + 'B'
: b instanceof ArrayBuffer ? 'ArrayBuffer ' + b.byteLength + 'B'
: typeof b === 'string' ? 'string ' + b.length + ' chars'
: b.constructor.name;
const _fetch = window.fetch;
window.fetch = (input, init) => {
console.log('[net] fetch', input.url ?? String(input), describe(init?.body));
return _fetch(input, init);
};
const _send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function (body) {
console.log('[net] xhr', describe(body));
return _send.call(this, body);
};
if (navigator.sendBeacon) {
const _beacon = navigator.sendBeacon.bind(navigator);
navigator.sendBeacon = (url, data) => {
console.log('[net] beacon', url, describe(data));
return _beacon(url, data);
};
}The limitation matters: this only covers the main thread. If processing happens in a Web Worker (ToolGarden’s image conversion does), requests made inside the Worker are not caught by the script, although the Network panel still lists them. Treat the script as a supplement, never a replacement for the panel.
The offline test: the cleanest evidence
Load the page and the tool (and wait for any model download to finish), then set throttling to Offline in the Network panel or simply disconnect Wi-Fi, and process a file. If you still get a result, the processing does not depend on a server. If it fails with a connection error, work out whether it needed a first-time download of a model or page resource, which you can fix by loading once online and testing again, or whether the processing itself requires a server, which means server-side processing.
4. Which requests are normal, and are not uploads
Local processing does not mean zero network activity. The following are normal; the point is to tell “downloading the program” from “sending your data”.
- The page and code chunks: HTML, JS and CSS downloaded when you open a tool.
- Models and WebAssembly: some of ToolGarden’s models and runtimes sit in the site’s own directories (OCR, image enhancement, upscaling), while the watermark-removal MI-GAN and LaMa models are downloaded from Hugging Face, with MI-GAN at about 28 MB on first use. These are downloads and carry none of your image.
- Third-party scripts: if a site includes analytics or ads, the page makes extra requests. They should not contain file content, which you can verify with the method above instead of guessing.
- Fonts and icons: usually GET requests with no request body.
5. What local processing protects, and what it does not
| Risk | Mitigated by local processing? | Notes |
|---|---|---|
| Files left in server logs, buckets or queues | Yes | The file never reached a server |
| Interception in transit | Largely | There is no file transfer to intercept, though the page code itself is still served over HTTPS |
| Tampered page code or injected malicious scripts | No | A tampered page can read any file you select, so confirm the correct domain over HTTPS |
| Malicious browser extensions | No | Extensions can read page content; more extensions mean more risk |
| Shared or untrusted computers | No | Files may remain in the Downloads folder, browser cache or system thumbnails |
| You sharing the result with someone else | No | Local processing covers the processing only, not what you do afterwards |
6. The real resource limits
A browser tab does not have a server’s compute and memory, so a well-built local tool sets explicit caps instead of letting the page freeze. These numbers come from the ToolGarden source:
| Scenario | Limit |
|---|---|
| Image conversion, watermark removal, watermarking and similar | Up to 50 MB per file and 40 million pixels |
| QR code decoding | Up to 12 MB per image and 24 million pixels |
| AI upscaling and image enhancement | Source image up to 4 million pixels |
| QR code logo | Up to 4 MB and 4 million pixels |
| Audio stem separation model | A large model; a comment in the service worker mentions a separate cache of about 130 MB |
When you hit a limit, do not read it as a broken tool. Shrink the image first, or process in batches, rather than dragging a whole folder in at once.
7. How far offline use really goes
The site registers a service worker and a web app manifest, so it can be installed as a PWA. The cache strategy is: build assets (/_next/static/) are read from cache first, page routes go to the network first and fall back to the cache when the network fails, and other GET requests are also network first. In practice, pages and static resources you have visited usually still open when you are offline, but tools you never opened and models you never downloaded will not appear out of thin air. To use a tool offline, open it while online and run a complete job once.
8. When not to use browser-local processing
- Compliance work that needs an audit trail: if policy requires traceable server logs for processing, local processing leaves no record.
- Multi-gigabyte files or long batch jobs: browser memory and per-tab compute are limited, so desktop software or a controlled backend fits better.
- High-fidelity Office layout: converting a complex document in a browser is often less reliable than professional desktop software.
- Collaboration and shared state: local processing is inherently single-machine.
- Untrusted devices: in an internet cafe or on someone else’s computer the privacy advantage is cancelled out by device risk.
A checklist for choosing a tool
- Verify once with a sample file and the Network panel that no request carries your file content.
- Confirm that the output format keeps the details you need, such as transparency, fonts or metadata.
- Before a large batch, read the tool’s file-size and browser-compatibility limits.
- For sensitive files, use a private window, turn off unnecessary extensions, and clean the Downloads folder afterwards.