Difference between JSON and JSONB. Which should you almos… — Cracked Java
// PostgreSQL · JSON & JSONB
MidTheory

Difference between JSON and JSONB. Which should you almost always use?

json stores the original text; jsonb stores a parsed binary tree — and you should almost always reach for jsonb. The names hide a fundamental representation difference that decides indexing, query operators, and read performance.

What json actually stores

The json type keeps the input exactly as written: whitespace, the order of keys, and even duplicate keys are all preserved. It validates that the text is well-formed JSON and then stores the string. Every time you extract a field, PostgreSQL re-parses the whole document.

SELECT '{"b": 1,   "a": 2, "a": 3}'::json;
-- {"b": 1,   "a": 2, "a": 3}   <- whitespace, order, duplicate "a" all kept

What jsonb stores

jsonb parses the input once on insert into a decomposed binary format. Consequences:

  • Keys are deduplicated — the last value wins.
  • Whitespace is dropped and key order is not preserved (it stores keys in a canonical order).
  • Reads don't re-parse, so field access is fast.
  • It supports GIN indexes and the containment (@>, <@) and existence (?, ?&, ?|) operators.
SELECT '{"b": 1, "a": 2, "a": 3}'::jsonb;
-- {"a": 3, "b": 1}   <- deduped (last wins), reordered, normalized

The trade-off

jsonjsonb
Storageoriginal textbinary tree
Insert costcheap (just validate)slightly higher (parse)
Read/extractre-parses each timefast, no parse
IndexingnoneGIN (and expression B-tree)
Containment / existence opsnoyes
Preserves whitespace / order / dupesyesno

When json is the right call

Only when byte-for-byte fidelity matters and you won't query inside it: storing the exact webhook or API payload for an audit trail where you must reproduce what the client sent, including key order or duplicates. Even then, many teams store the raw string in a text column and keep a separate jsonb for querying.

Mark your status