Every SOAP integration, every RSS import, every docx file is built on XML — and every one of them pays a tax the equivalent JSON does not. We generated identical data in both formats and measured the difference. The numbers below are reproducible with the XML Formatter and JSON tools linked at the end.
Executive summary
- Weight tax: the same 1,000 records weigh 236 KB as XML vs 162 KB as compact JSON — a 46% premium.
- Parse tax: XML parses 2.6× slower than the equivalent JSON (3.27ms vs 1.26ms per parse on 1,000 records).
- The 81% trick: writing the same XML with attributes instead of child elements shrinks it from 236 KB to 46 KB — a saving most XML authors never use.
Tax 1: The Weight Tax — Every Value Is Named Twice
XML names every value twice: <field>value</field>. JSON writes it once: "field":value. With repeated records, the tag names are repeated thousands of times. Our measurement on identical data:
| Representation | 1,000 records | vs JSON compact |
|---|---|---|
| JSON (compact) | 161,930 B | baseline |
| JSON (pretty) | ~250 KB | +54% |
| XML (elements) | 235,944 B | +46% |
The tax scales with record count — every row re-pays the tag-name overhead. For a 1,000,000-row export, that is 74 MB of pure tag-name markup that JSON never pays.
Tax 2: The Parse Tax — Nested Context Costs Cycles
XML parsers must track element nesting and namespace resolution; JSON is a flat token stream. On 1,000 identical records (Python 3.13 standard library, 50-run median):
| Format | Parse time (per run) | vs JSON |
|---|---|---|
JSON (json.loads) | 1.26 ms | baseline |
XML (ET.fromstring) | 3.27 ms | 2.6× |
Two forces compound: the 46% extra bytes and the structural overhead of element context tracking. Native parsers narrow the gap but never close it — and on low-end mobile CPUs both multipliers are paid at once.
Tax 3: The Attribute Trap — 81% of Your XML Is Optional
Here is the part most XML authors miss. XML has two ways to carry a value — child elements and attributes — and they are not equivalent in cost:
| Style (1,000 records) | Size | Saving |
|---|---|---|
Child elements (<id>7</id>) | 235,944 B | baseline |
Attributes (id="7") | 45,795 B | -81% |
The rule: attributes for scalar metadata, elements for structured or repeatable content. An id, a flag, a code is metadata — put it in an attribute. A list of tags, a nested address, a collection — keep it as elements. Hybrid XML following this rule is nearly as compact as JSON while keeping schema validation and namespaces.
Why XML Hasn't Died (And Won't)
JSON is a data format. XML is a document technology with data capabilities. Three structural features keep it alive in the enterprise:
- Schemas (XSD): contract validation JSON does not have natively — SOAP exchanges in banking, telecom, healthcare rely on it.
- Namespaces: mixing vocabularies without name collisions — RSS extensions, SVG + XHTML embedding.
- Attributes: metadata separate from content, which JSON simulates with conventions like
@-prefixed keys.
Add the installed base — Office documents, Apple plists, RSS/Atom, Android manifests — and XML is not going anywhere. The question is never "which is better" but "which fits the contract you inherited."
Decision Framework: When to Convert
| Situation | Verdict |
|---|---|
| SOAP responses consumed only by your own frontend | Convert to JSON — save 30%+ bytes and 2.6× parse |
| RSS feeds ingested into a database | Convert to JSON at ingest, keep XML source if you must re-publish |
| Third-party XSD-governed exchange | Keep XML — the contract is schema-validated |
| docx/xlsx/plist files | Keep XML — the format IS the contract |
| Bandwidth-sensitive internal XML | Rewrite scalars as attributes — 81% savings without leaving XML |
Related
Related: The JSON.parse Tax · The Bundle Tax · The Base64 Inflation · The Image Weight Tax · The Layout Tax · The Animation Tax
Tools: XML Formatter & Validator · JSON Formatter · JSON Minifier · JSON →CSV · CSV →JSON · YAML ↔JSON