Skip to main content

JSON Analyzer

Know what is actually in your data.

The analyzer profiles a document and reports what it finds: how big it is, how deep it goes, how many objects, arrays and values of each type — and, more usefully, where the data is inconsistent.

Input JSON

Size: 0 BLines: 0

Paste JSON to get started

Try an example:

No JSON entered.

What gets measured

The structural pass walks every node once and reports size in bytes, total node count, maximum nesting depth, the number of objects, arrays, strings, numbers, booleans and nulls, how many keys exist and how many of them are distinct.

Depth and distinct-key count are the two worth reading first. Depth tells you how painful this document will be to query and render — anything past ten is usually an API that grew rather than an API that was designed. A distinct-key count far below the total key count means you are looking at repeated records, which is the shape everything else here works best on.

Ten checks, on every document

The findings are heuristics with explicit thresholds rather than opinions. Here is every check, and exactly what triggers it.

CheckTriggers whenSeverity
Inconsistent typesOne field holds more than one non-null type across records.Warning
Duplicate identifiersA field named id, _id, uuid, guid, key, slug, code or sku repeats a value within an array.Warning
Mixed date formatsOne field uses more than one of six recognised date shapes.Warning
Mixed array contentsOne array holds items of more than one type.Warning
Null-heavy fieldA field seen at least 5 times is ≥30% null.Info, or Warning past 80%
Missing fieldA field is absent from some sibling objects but present in others.Info
Overall nullsAny nulls exist; escalates when they exceed 25% of all values.Info, or Warning
Empty stringsAny "" values exist.Info
Empty arraysAny [] values exist.Info
Deep nestingMaximum depth exceeds 15.Info

Findings are sorted by severity and then by how many values they affect, so the check that touches the most data appears first within its band. Nothing is hidden — an empty findings list means all ten checks passed.

A worked example

Three user records, each slightly wrong in a different and entirely realistic way:

Input
{ "users": [
  { "id": 1, "name": "A", "signed_up": "2024-01-02", "score": 10,   "note": null, "tags": [] },
  { "id": 2, "name": "B", "signed_up": "03/04/2024", "score": "20", "note": null },
  { "id": 2, "name": "C", "signed_up": "2024-01-05", "score": 30,   "note": null, "nickname": "" }
] }
Findings
warning  Consistency   $.users[].score has inconsistent types
                       66.7% number, 33.3% string
warning  Consistency   $.users[].signed_up uses multiple date formats
                       ISO 8601 date (2), MM/DD/YYYY (1)
warning  Consistency   $.users[].id contains 1 duplicate value
                       First repeated value: "2"
info     Data quality  3 null values detected — 13.6% of all values
info     Completeness  $.users[].nickname is missing from 2 of 3 objects
info     Completeness  $.users[].tags is missing from 2 of 3 objects
info     Data quality  1 empty string detected
info     Data quality  1 empty array detected

Every one of those is a real problem in waiting. The string "20" sorts and sums wrong. Two date formats mean whatever parses them is guessing. The repeated id breaks any code that builds a lookup keyed on it — including the diff tool, which needs unique identifiers to match array items properly.

Field profiles

Alongside the findings, every field is profiled: how many times it was seen, the breakdown of types it held, how many of its values were null or empty, its dominant type, and up to three real sample values. Fields are listed most-frequent first.

This is the fastest way to answer "what is actually in this response?" for an API whose documentation you do not trust. The sample values matter more than they sound — seeing three real values of a field usually tells you in a second what a type name never could.

From a finding to a fix

FindingUsual causeWhat to do
Inconsistent typesA serializer that emits numbers as strings for large values, or a nullable column mapped inconsistently.Fix at the source. Failing that, coerce at the boundary and never in business logic.
Duplicate identifiersA join that fanned out, or pagination that overlaps.Check the query before you check the data.
Mixed date formatsTwo code paths writing the same field.Normalise to ISO 8601 with an explicit offset.
Null-heavy fieldA feature that was never populated, or an optional relation.Decide whether it belongs in the response at all.
Missing fieldA genuinely optional field — usually fine.Make sure your generated types mark it optional.
Mixed array contentsA polymorphic collection.Add a discriminator field, or split the array.

Behaviour on very large documents

Every traversal is iterative with an explicit stack, so depth cannot overflow the call stack no matter how nested the input is. Per-field data is stored as counters rather than value lists, which keeps memory bounded as row counts grow.

  • Up to 5,000 distinct field paths are profiled; past that the shape is established and new paths are not tracked.
  • Up to three sample values are kept per field.
  • Duplicate-identifier scanning covers up to 200 identifier fields.
  • Analysis runs in a Web Worker, so the page stays responsive while a large document is processed.

The analyzer never modifies your document — it only reads. And like everything else here, it runs in your browser: no upload, no stored copy, nothing transmitted.

Frequently asked questions

Does the analyzer change my JSON?
No. It reads the parsed document and produces statistics and findings. Your text is untouched.
What does “inconsistent types” actually mean?
One field held more than one non-null JSON type across the records it appeared in — for example score was a number in two records and a string in a third. The finding shows the percentage split so you can tell an occasional anomaly from an even mix.
Why is a field reported as missing when it is optional?
Because the analyzer cannot tell those apart, and both are worth knowing. The finding is filed as info rather than a warning, and it tells you the exact proportion — present in 33% of records is a very different signal from present in 99%.
Which date formats are recognised?
ISO 8601 date-time, ISO 8601 date, MM/DD/YYYY, DD.MM.YYYY, RFC 1123 HTTP dates, and Unix timestamps stored as strings. A field using more than one of them is flagged.
How does it handle very large documents?
Traversal is iterative so nesting cannot overflow the stack, per-field aggregates are counters rather than value lists, and up to 5,000 distinct field paths are profiled. Analysis runs in a Web Worker so the interface stays responsive.
Are the findings sent anywhere?
No. Analysis runs entirely in your browser and the results exist only in the page.