jsonperformancedatabasesadvanced

JSON Size Limits: What Browsers, Databases and APIs Actually Allow

·8 min read·Performance

"How big can a JSON document actually be?"

The JSON specification itself (RFC 8259) sets no size limit on documents, strings, numbers, or nesting depth — but every real system that stores or transmits JSON imposes its own practical ceiling, and these limits are scattered across vendor docs, GitHub issues, and hard-won production incidents rather than one obvious place. Here's what actually caps you, system by system.

Browser JavaScript strings and JSON.parse

V8 (Chrome, Node.js, Edge) caps a single string at just over 1 GB (String.length max is 2^29 - 24 characters on 64-bit builds) — in practice, you'll hit memory pressure and UI-freezing parse times long before that theoretical ceiling. JSON.parse is synchronous and blocks the main thread for its entire duration, so a multi-hundred-MB payload can visibly freeze a browser tab for seconds even if it technically parses successfully.

javascript
// A large synchronous parse blocks the main thread entirely
const data = JSON.parse(hugeJsonString); // UI frozen until this returns

For genuinely large payloads in the browser, stream and parse incrementally (see our guide on parsing large JSON files) rather than one blocking JSON.parse call.

localStorage and sessionStorage

Browsers cap localStorage at roughly 5–10 MB per origin (the exact number varies by browser — Chrome and Firefox default to 10MB, Safari to 5MB), and since it only stores strings, every read/write is a full JSON.stringify/JSON.parse round trip of the *entire* stored value — there's no partial update. Exceeding the quota throws a QuotaExceededError, not a silent truncation:

javascript
try {
  localStorage.setItem("cache", JSON.stringify(largeObject));
} catch (e) {
  if (e.name === "QuotaExceededError") {
    // Handle gracefully — don't let this crash the app
  }
}

PostgreSQL JSONB

PostgreSQL's jsonb column type has a hard ceiling of 1 GB per value (shared with PostgreSQL's general field size limit), but the practical limit is far lower — indexing and querying deeply nested or very large JSONB documents gets noticeably slower well before 1GB, and GIN indexes on JSONB columns work best on documents that are large in *count* (many rows) rather than large in *individual document size*. A JSONB column holding a handful of KB per row, queried across millions of rows, is the pattern PostgreSQL is actually optimized for.

MongoDB

MongoDB enforces a hard 16 MB per document limit (BSON document size, which JSON documents are stored as internally) — this is a deliberate design constraint, not a bug, meant to keep individual documents fitting comfortably in memory during processing. Documents that would naturally exceed this (a chat history, a large activity log) are expected to be split — the recommended pattern is GridFS for large binary content, or restructuring so unbounded arrays live in a separate, referenced collection instead of embedded in one ever-growing document.

javascript
// Anti-pattern: an array that grows without bound risks the 16MB ceiling
{ _id: "chat_1", messages: [ /* thousands of embedded messages */ ] }

// Better: messages in their own collection, referenced by chatId
{ _id: "msg_1", chatId: "chat_1", text: "..." }

API gateways and web servers

Most API gateways and frameworks impose a default request body size limit specifically to prevent memory-exhaustion attacks — and these defaults are smaller than most developers expect:

SystemCommon default limit
AWS API Gateway10 MB (hard limit, not configurable)
Nginx (client_max_body_size)1 MB (must be raised explicitly)
Express.js (body-parser/express.json)100 KB
Cloudflare (free/pro plans)100 MB (varies by plan)

A request exceeding these returns 413 Payload Too Large — worth checking explicitly in your error handling, since a generic error handler that doesn't distinguish this from a validation failure makes an easy problem look like a mystery.

Number precision: a "limit" that isn't about size at all

Separate from document size, JSON's number type has its own ceiling: JavaScript can only exactly represent integers up to Number.MAX_SAFE_INTEGER (2^53 - 1, about 9 quadrillion). A 64-bit database ID or a large financial value serialized as a JSON number beyond that silently loses precision on parse — the fix, covered in more depth elsewhere, is to serialize very large integers as strings, not numbers.

A practical checklist before you hit a wall

  • Browser-bound JSON: keep well under a few MB for anything parsed synchronously on the main thread; stream or paginate beyond that.
  • localStorage: budget for 5MB total per origin, not per key — check current usage before writing a new large value.
  • PostgreSQL JSONB: fine up to low tens of MB per document in practice; beyond that, reconsider whether it should be a document at all versus normalized rows.
  • MongoDB: hard 16MB ceiling — design around it early rather than hitting it in production with a document that's grown organically.
  • APIs: check your gateway/framework's actual configured limit (not just the library default) and return a clear, distinguishable error when a request exceeds it.

Frequently asked questions

The write is rejected outright with an error — MongoDB does not truncate or silently split the document. You need to restructure the data (typically moving an unbounded array into its own referenced collection) before the write will succeed.

The spec doesn't mandate one, but many parsers impose their own limit to guard against stack-overflow attacks from maliciously deep nesting — Node.js's JSON.parse, for instance, has practical (if very high) recursion limits tied to available stack space rather than a fixed documented number.

Your request body exceeded the server or gateway's configured size limit before your application code (and its validation logic) ever ran — check the web server, framework, or CDN's body-size configuration rather than your endpoint's own validation code.

Paste it into JSONKit's JSON Size Analyzer to see the exact byte count and which keys contribute the most to it, or the JSON Minifier to see how much whitespace alone is inflating the size.

Try JSONKit — JSON Developer Tools

Format, validate, convert and diff JSON. Instant, accurate and 100% private.