Guide

Large numbers in JSON and precision loss

Prevent identifiers and integers above 53 bits from changing while JSON is parsed, formatted, or converted in JavaScript.

by Tools in a Tab · Published on · Reviewed on

Short answer

JSON’s grammar permits integers with many digits, but the program reading them may not represent every value exactly. JavaScript Number uses binary floating-point and preserves every integer only through 9007199254740991 (2^53 - 1).

Loss example

{
  "id": 9007199254740993
}

A parser that immediately converts the token to Number can round it to 9007199254740992. The JSON syntax is valid; the loss occurs in the consumer’s numeric representation.

RFC 8259 notes that integers in [-(2^53)+1, (2^53)-1] are the range where common implementations can agree on the exact value.

When a string is better

If the digits are an identifier, phone number, account, or code rather than a quantity, a string avoids rounding and retains leading zeros:

{
  "id": "9007199254740993"
}

For quantities that require exact arithmetic, agree on a decimal or big-integer type at both ends and define its serialization. JavaScript BigInt is not automatically serialized as a JSON number by JSON.stringify.

Token-preserving tools

The Tools in a Tab JSON formatter preserves numeric lexemes while formatting or minifying instead of rounding them through an ordinary parse. JSON to YAML also keeps the digits, but the final consumer must still support them.

Checklist

  • Decide whether the field is a quantity or an identifier.
  • Test 9007199254740991, 9007199254740992, and 9007199254740993.
  • Check parsing, transformation, database storage, and reserialization.
  • Avoid exponent notation where the consumer requires exact digits.
  • Document the accepted range in the API contract.