Open Your Export in the Browser Without Uploading It: How a Local Viewer Streams a 4GB export.xml Without Sending a Byte

You tap Export All Health Data, wait, and end up with a file that is embarrassingly large. The default reflex is to find a website that will convert it for you, which means handing a decade of your health record to a server you know nothing about. You do not have to. A browser can read a multi-gigabyte export on your own machine, if the reader is built the right way.

By MetricBridge · Published 12 November 2026 · ~8 min read

AI-assisted, human reviewed. How we use AI

Quick answer

A local export viewer reads your export.xml or export.zip from your own disk inside the browser tab and never sends it anywhere, so there is no upload step and no copy on someone else's server. It can handle a 4GB file because it streams: a background worker reads the XML in chunks, holds a fixed-size buffer, and emits one record at a time, so the tab never has to fit gigabytes into memory. The reason a server-side converter exists at all is that a reader which builds a full document object model of the whole file is the thing that freezes the tab, and uploading is one way around that. The better fix is to stream, not to upload.

Why the file is so big, and why that is the whole story

Your export is not one file. It is a zip, and inside it export.xml is the giant: a record for basically every health sample you have ever logged, in plain text XML. Apple does not publish a size limit, but the file grows with how long and how often you have tracked. A few years of an Apple Watch on your wrist lands you in the hundreds of megabytes. Years of that, with workouts and heart rate and sleep, and you are looking at gigabytes. Rates around 500MB to 4GB for a real multi-year export are common, and the number only goes up.

That size is why the upload reflex exists. Most tools were built by someone who wrote an XML reader, ran it against a file they had lying around, and discovered that loading the whole document into memory is exactly what their library does. The file gets big, the tab hangs, and the obvious workaround is "let our server do it, our server has more memory." Which is a fix for the tool, paid for with your data.

The actual difference: streaming versus loading the whole thing

There are two ways to parse XML and they are not close in what they cost.

  1. Load the whole document. The parser reads the entire file, builds a tree of objects in memory for every element, and only then can your code ask a question of it. The in-memory cost is a multiple of the file size, not the file size, because each XML element becomes an object with overhead. At 4GB of text you are now asking the tab for tens of gigabytes. This is the freeze, and it is also why someone with a small export thinks their code is fine.
  2. Stream it. A streaming, SAX-style parser reads the file in chunks and fires a callback per element as it arrives. It never builds the document, never keeps the whole string, and holds only the record it is on. The published apple-health-parser (MIT) describes its own behaviour the same way: constant memory, never builds a document model, and it parses a 1GB export with a few megabytes of memory. The number that matters is not "how big is your file", it is "how big is the buffer", and a streaming parser keeps that number small and fixed.

So the capability is not exotic. Browsers have had the pieces for years: read the file with a stream reader, hand the chunks to a streaming parser, do the work in a worker so the interface thread stays free. The tools that do this say so plainly. The local viewers that stream a multi-gigabyte export in a background worker so the tab does not freeze are the same trick, and it is the reason "nothing is uploaded" and "no size limit that bites" belong in the same sentence.

A one-minute check. Open the viewer, start the parse, and watch your browser's network panel. A local reader shows no request carrying your file. If the tool's first step is a progress bar labelled "uploading", it is a server-side converter and your record just left the machine, whatever the privacy page says.

What "no upload" does and does not buy you

Be precise about the claim, because it is easy to oversell. No upload means the parsing happened on your device and no copy of the file went out over the network for that. It does not mean the data can never leave: if you then download a CSV and email it to yourself, or the export folder lives in iCloud Drive, you moved it, and moving a file is your right and your choice. It does not mean every website you use with your data is safe either. It means one specific thing, and it is the thing worth checking: reading the file did not require sending it to anyone.

That is a narrower promise than "we never see your data", and it is more useful because you can verify it. A data-path claim you can watch happen in a network panel beats a policy you have to trust.

Where this fits in the bigger picture: viewing is step one

Opening the file to see what is in it is the front door. The reason people export at all is usually the next step: they want an AI, or an agent, or a coach, to actually read the numbers and answer questions about them. That is where the same architecture question comes back, just one layer up, and it is the layer most people never audit.

Our own path keeps the file where it is and works from there. The iOS app reads Apple Health read-only and writes clean JSON or CSV to a destination you pick: iCloud Drive, a local folder, your LAN, or a webhook. Nothing is uploaded by default, there is no destination on unless you turn one on, and the app itself has no server of ours in the path. Then the free health-export-mcp server, version 1.10.2, runs as a local process on your machine and reads that folder over stdio. It has 22 tools (20 read-only) and 194 metrics, ships with zero dependencies, and makes no outbound network calls, so you can clone it, grep the read path for a network call, and find nothing. The only socket in the repository is an optional inbound LAN receiver, and you have to start it yourself.

Stated exactly, because "private" is a word people overreach with: your health data never reaches us or a cloud AI. The export goes only where you point it, and once it leaves as a file, it travels wherever you send it, because a file you own is a file you can move. The iOS app reports install, trial-start and purchase events to Meta for ad attribution, never health data, and only if you allow tracking when iOS asks.

Why this is the shape and not a website

A converter on a domain is less work for the person using it, and that is its entire advantage. Everything else is worse for the thing you are handling. It has to receive your history, hold it while it runs, and choose a retention period, and none of those choices are yours. When the service closes, the copy it kept is a question rather than a fact. Reading the file in place has none of those failure modes, because there is no second copy and no account.

So the honest summary: if you have a 4GB export and you want to look at it, a local viewer that streams will open it instantly and send nothing. If you want an agent to reason over it, keep the file local and give the agent a local reader. Both are the same decision, which is not "trust us more", it is "do not add a place for the data to sit".

And the boundary that applies to all of it: this is a wellness tool, not a medical one. It reads your own data and describes it against your own baseline. It does not detect, treat or monitor a condition, and it should never be asked to.

FAQ

Does a local export viewer upload my Apple Health data?

It does not have to. A local viewer reads the file from your disk inside the browser tab and never sends it over the network, so there is no upload step to trust. You can confirm it by opening the browser's network panel: during a local parse you should see no request carrying your data. If a tool needs you to upload first, it is a server-side converter and the file leaves your machine.

How can a browser open a 4GB export.xml without freezing?

By never loading the whole file at once. A streaming parser reads the XML in chunks, keeps a fixed-size buffer, and emits one record at a time, so the tab never has to hold gigabytes in memory. A parser that builds a full document object model does the opposite: it reads the entire file and a large object tree before it can show you anything, which is what freezes the tab or crashes it.

Is there a size limit on an Apple Health export?

There is no fixed limit from Apple, but the file grows with how long and how often you have tracked. A multi-year export commonly runs from hundreds of megabytes into a few gigabytes, and export.xml is the big one because it is plain text XML while the zip is compressed. The right question is not the size but whether the reader streams, because a constant-memory parser does not care how large the file is.

Why not just upload the export to a converter?

Because the upload is the whole cost and the whole risk. A server-side converter has to receive your history, hold it while it works, and decide on its own how long to keep it, and your health record is then on a machine you do not control. Reading the file where it already sits removes that step rather than promising to be careful with it. It is a different architecture, not a stronger promise.

Keep the file where it is, then point an agent at it

Export all 194 metrics on the iPhone to a folder you choose, then let Claude, Cursor or any MCP client read that folder locally over stdio. No upload, no URL, no server of ours in the middle.

Where it goes: the app reads Apple Health read-only and writes JSON to a folder you pick. Your health data never reaches us or a cloud AI; the MCP server makes zero network calls. What you get: all 194 metrics, on-device Ask with a provenance card on every answer, the Weekly Brief, and the Mac and Apple Watch apps. Price: $24.99 one time after a 7-day free trial, not a subscription. Wellness, not medical advice.