How to minify json payloads for cdn cache optimization
- Step 1List the JSON you serve from the edge — Identify the static JSON in your CDN:
products.json,pricing.json, country/currency lists, feature-flag config, and cached API snapshots. Sort by object size — the largest, most-requested files give the biggest storage and egress savings. - Step 2Drop the file or paste its content — Drag the
.jsononto the dropzone above, or paste it. Parsing happens locally in your browser; catalog and pricing data never leave the page. Process one JSON document per run. - Step 3Decide on null removal — Leave Also remove null values off to keep the contract identical and measure pure whitespace savings. Turn it on only if clients consuming the file treat a missing field the same as
null— it permanently drops those fields and null array elements. - Step 4Minify and estimate the cost saving — Click Minify JSON and read
inputBytes → outputBytes · N% smaller. Multiply the byte delta by your monthly request volume for egress, and by your stored-GB rate for storage, to put a dollar figure on it. Storage savings apply even when the CDN compresses on the wire, because objects are stored uncompressed. - Step 5Set content type, caching and compression headers — Serve the file with
Content-Type: application/json, aCache-Controlsuch aspublic, max-age=86400, and edge compression (Content-Encoding: br/gzip) for clients that accept it. Minification reduces both the stored bytes and the bytes the edge must compress per request. - Step 6Use content-hashed filenames for cache busting — Because the minified output is deterministic, name files
products.<contenthash>.jsonwithimmutablecaching. The hash only changes when the data changes, so caches stay warm and you avoid re-fetching unchanged catalogs. Copy/Download the minified file to upload to origin.
Where minification pays off at the edge
Minification reduces stored bytes and the worst-case (uncompressed) transfer. Compression is a separate, larger layer on egress.
| Cost dimension | Does minification help? | Why |
|---|---|---|
| Edge / origin storage (per GB) | Yes | Objects are stored uncompressed, so smaller source = lower storage bill |
| Egress to compression-capable clients | Marginal | Brotli/Gzip already removes whitespace before sending |
| Egress to clients without Accept-Encoding | Yes | IoT/embedded clients may get the raw object — minified is smaller |
| Per-request compression CPU at the edge | Slightly | Fewer bytes to compress on each cache miss / revalidation |
| Cache-key stability | Yes (deterministic) | Identical input → identical bytes → stable content hash |
Caching headers to pair with minified JSON
Recommended header patterns for static JSON served from a CDN. Adjust TTLs to your update frequency.
| Header | Value pattern | Purpose |
|---|---|---|
Content-Type | application/json; charset=utf-8 | Correct MIME so browsers parse, not download |
Cache-Control (versioned file) | public, max-age=31536000, immutable | For name.<hash>.json that never changes in place |
Cache-Control (mutable file) | public, max-age=300, stale-while-revalidate=86400 | Short TTL for pricing.json updated frequently |
Content-Encoding | br / gzip (edge-applied) | Compression on top of minification for capable clients |
ETag | Content hash of the minified bytes | Cheap revalidation; deterministic output keeps it stable |
Cookbook
Real edge-served JSON, before and after. Byte counts are illustrative UTF-8 sizes; these are the stored / uncompressed figures.
Product catalog snapshot compacted
ExampleA catalog exported pretty for human review, then served from the edge as-is. Minifying before upload cuts stored bytes by about a third.
Before (pretty, 318 bytes):
{
"products": [
{
"id": "sku-1",
"price": 19.99,
"stock": 42
}
]
}
After (minified, 214 bytes · 33% smaller):
{"products":[{"id":"sku-1","price":19.99,"stock":42}]}Catalog records padded with nulls
ExampleExports often emit every optional attribute as null. With Also remove null values on, the unset attributes drop out — only enable it if clients treat absent and null identically.
Before:
{"id":"sku-2","name":"Widget","discount":null,"badge":null}
After (removeNulls on):
{"id":"sku-2","name":"Widget"}
Note: clients can no longer read discount/badge as null.Deterministic output for content hashing
ExampleThe same catalog always minifies to the same bytes, so its content hash is stable. Re-minifying an unchanged file produces an identical filename and keeps the cache warm.
products.json (minified, run 1): {"v":3,"items":[1,2,3]}
products.json (minified, run 2): {"v":3,"items":[1,2,3]}
Identical bytes → identical sha256 → products.<samehash>.json
No new cache object created; existing edge cache stays valid.Catch a broken config before it caches
ExampleA feature-flag config with a trailing comma fails here, before it is deployed and cached against you for the full TTL.
Input (trailing comma):
{"flags":{"newCheckout":true,}}
Result: parse error — "Unexpected token } in JSON".
Fix the source (or run json-format-fixer), then minify and deploy.Pricing table with mixed number forms
ExamplePricing data assembled from several sources mixes number forms. Minification canonicalises them; the values are unchanged.
Before:
{"USD":19.990,"EUR":18.50,"discount_pct":10.0}
Minified:
{"USD":19.99,"EUR":18.5,"discount_pct":10}
Numerically identical; only the textual form changed.Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Removing nulls changes the served contract
By designAlso remove null values deletes null fields and null array elements from the file you upload. Clients that read record.discount === null to mean 'no discount' will instead get undefined. Only enable it if every consumer of the cached file treats absent and null the same — otherwise keep it off and let compression handle the whitespace.
Marginal egress gain when the edge compresses
ExpectedBrotli/Gzip at the edge already strips whitespace before sending, so for compression-capable clients the egress saving from minified-vs-pretty is small. The durable wins from minifying are lower storage cost (objects are stored uncompressed) and smaller transfers to clients that do not send Accept-Encoding. Measure the storage delta, not just egress.
Malformed catalog or config
Parse errorThe tool parses before serializing, so a catalog with a trailing comma, comment, or truncated array is rejected — better here than after it is cached at the edge for the full TTL. Repair non-standard JSON with json-format-fixer first, then minify the clean output.
Large integer SKUs or IDs
Precision lossNumeric IDs above 2^53 lose precision on the round-trip. If your catalog carries 64-bit SKUs or order numbers as JSON numbers, store them as strings before minifying so the cached file is byte-exact. This is a JavaScript number limitation, not a CDN-specific one.
Non-deterministic upstream export breaks hashing
Cache thrashMinification itself is deterministic, but if your upstream export reorders keys or array elements between runs, the minified bytes differ each time and the content hash changes even when the data did not — re-fetching unchanged catalogs. Stabilise the export (sort keys/rows at the source) so minification produces a stable hash. The minifier preserves whatever order it receives.
Free-tier 2 MB limit on a big catalog
Upgrade requiredFree accounts accept up to 2 MB. A large product catalog can exceed that; Pro raises the limit to 100 MB. For very large catalogs, consider splitting into per-category files (better cache granularity at the edge) rather than serving one giant JSON object.
NDJSON snapshot of events
Parse errorA .ndjson/.jsonl snapshot with many top-level objects fails — the tool parses the whole input as one JSON value. To serve such data compactly, wrap the records in a single array or minify line by line. The extensions are accepted only when the file content is one valid JSON value.
BOM or non-UTF-8 source file
Parse errorA leading byte-order mark or non-UTF-8 encoding can make the input fail to parse. The tool trims leading whitespace but expects UTF-8 JSON. Re-export the file as UTF-8 without a BOM before minifying; the output is UTF-8 with non-ASCII characters preserved as literals.
Frequently asked questions
Should I minify JSON if my CDN already applies Brotli?
For transfer size to compression-capable clients, Brotli does the heavy lifting — 80–90% vs the 15–30% whitespace removal achieves — so the egress gain from minifying on top is small. But CDNs store objects uncompressed, so minifying lowers your storage bill and reduces the bytes the edge compresses on each cache miss. And clients that do not negotiate compression get the raw object, where minification is a full win. Measure the storage delta here to decide.
Will the minified output be stable across runs for content hashing?
Yes — the minifier is deterministic: the same input always produces byte-identical output. So a content hash over the minified bytes (products.<hash>.json with immutable caching) stays stable until the data genuinely changes. The caveat is upstream: if your export reorders keys/rows between runs, the hash will change for unchanged data — stabilise the export.
How do I cache-bust minified JSON cleanly?
Use content-hashed filenames: pricing.<hash>.json. When the data changes, the minified bytes change, the hash changes, and the new URL bypasses the old cache automatically. Pair versioned files with Cache-Control: public, max-age=31536000, immutable, and use a short TTL with stale-while-revalidate for files you update in place.
Does minification reduce my egress bill?
Partly. To clients that accept Brotli/Gzip, the wire size is already compressed, so the egress saving is marginal. To clients that do not negotiate compression (some IoT/embedded HTTP stacks) the raw object ships and minification is a direct saving. The clearer, always-on benefit is lower storage cost, since CDNs bill stored objects uncompressed.
Can it sort keys so my catalog diffs are clean?
No — this is a minifier (with an optional null removal); it preserves the key order it receives. If you want sorted, indented output for clean diffs in version control, use the json-prettifier, which exposes indent and a sort-keys option. Sorting at the source also stabilises your content hashes.
What headers should I serve minified JSON with?
Content-Type: application/json; charset=utf-8, a Cache-Control matched to how often the file changes (immutable for hashed files, short max-age with stale-while-revalidate for mutable ones), and edge compression (Content-Encoding: br/gzip). An ETag over the minified content gives cheap revalidation, and because the output is deterministic the ETag stays stable until the data changes.
Should I split a big catalog instead of serving one file?
Often yes. One 5 MB products.json means every client downloads the whole catalog and any change invalidates the entire cache object. Per-category files (products/electronics.<hash>.json) give finer cache granularity and smaller transfers. Minify each split file. Note the free tier caps input at 2 MB, so very large single catalogs need Pro or splitting.
Does removing nulls save much in a catalog?
It depends on how null-padded your records are. Catalogs that emit every optional attribute as null (discount, badge, variant fields) shrink noticeably; dense catalogs barely change. Measure both ways. Keep null removal on only if every client reads absent and null identically — otherwise you change the served contract, not just the size.
Why did a numeric price change form after minifying?
The round-trip canonicalises numbers: 19.990 → 19.99, 10.0 → 10. The values are numerically identical; only the text changed, and any JSON-parsing client reads the same number. If your clients compare raw JSON strings (rare), be aware the canonical form is what they will receive.
Can I add this to my deploy pipeline?
For automation, a CLI step like jq -c '.' catalog.json > catalog.min.json minifies in place during the build. This tool is ideal for the measurement and validation step: confirming the saving is worth a pipeline change and catching a malformed catalog before it ships. The output is byte-equivalent to JSON.stringify / jq -c.
What's the largest file I can minify?
2 MB on the free tier, 100 MB on Pro. For catalogs beyond the free limit, either upgrade or — better for edge caching — split the catalog into smaller per-category files that cache and transfer independently.
Is my catalog or pricing data uploaded to JAD Apps?
No. Parsing and minification run entirely in your browser. Product catalogs, prices and configuration never reach a JAD Apps server. Only an anonymous run counter (size and duration, no content) is recorded for signed-in users, and that is opt-out in account settings.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.