JSON vs YAML: Choosing a Config Format

5 min read

Where each format actually wins, beyond personal preference.

JSON and YAML represent the same underlying data model - objects, arrays, strings, numbers, booleans, null - so a converter can move between them losslessly in almost every practical case. The real difference is what each format optimises for.

JSON optimises for machines. Its syntax is small and unambiguous: every structure is delimited by brackets and braces, so a parser never has to guess where a block ends. That same rigidity makes it the default for APIs, where every client and server needs to agree exactly.

YAML optimises for humans editing files by hand. Indentation replaces most punctuation, comments are allowed, and multi-line strings are far more readable - which is why Kubernetes manifests, CI pipelines and Docker Compose files favour it. The tradeoff is that YAML has more ways to go subtly wrong: inconsistent indentation, or values like "no" and "on" being parsed as booleans instead of strings, are frequent bug sources.

A reasonable default: use JSON for anything machine-to-machine, especially API payloads, where strict validation prevents ambiguity. Use YAML for configuration files a person edits directly and needs to read comments in, and validate it with a linter before deploying, since its flexibility is also where mistakes hide.

1. Syntax Architecture: Strict Delimiters vs Whitespace Indentation

JSON (JavaScript Object Notation) and YAML (YAML Ain't Markup Language) represent two ubiquitous serialization formats in modern software engineering. While both serialize structured nested data objects, they reflect contrasting engineering philosophies: - **JSON Philosophy:** Prioritizes machine parsability, unambiguous parsing grammars, and universal language interoperability. JSON enforces strict curly braces `{}` for objects, square brackets `[]` for arrays, double quotes `""` around all keys and strings, and prohibits trailing commas. - **YAML Philosophy:** Prioritizes human authoring ergonomics and visual readability. YAML utilizes Python-style indentation, eliminates quotes around simple strings, supports comments natively, and allows complex multi-line text blocks with folding operators (`>` and `|`).

2. Comments and Configuration Ergonomics

The single most significant operational difference for DevOps engineers is **comment support**: - **JSON:** The official RFC 8259 JSON specification explicitly excludes comments. Douglas Crockford removed comments from the specification to prevent developers from parsing environment-specific pragmas. This makes JSON frustrating for configuration files (like CI/CD pipelines or server configs) where documentation of settings is essential. - **YAML:** Supports native hash `#` comments at any line position, making it the industry standard for Kubernetes manifests, GitHub Actions workflows, Docker Compose files, and Ansible playbooks.

3. The YAML Parsing Hazards: The Norway Problem and Code Execution

YAML's permissive syntax introduces notorious software bugs: - **The Norway Problem (`NO` issue):** In YAML 1.1, unquoted `NO` (the country code for Norway) was automatically coerced into the boolean `false`! Developers writing country configuration tables discovered Norway was parsed as boolean false instead of string 'NO'. - **Arbitrary Code Execution Vulnerabilities:** YAML supports custom type tags (such as `!!python/object/apply`). Parsing untrusted user-supplied YAML without safe loader configurations (e.g. `yaml.safe_load()`) has led to catastrophic remote code execution (RCE) vulnerabilities in Python and Ruby environments. - **Invisible Whitespace Drift:** Accidental mixing of tabs and spaces or indentation misalignment can alter nested object hierarchies without throwing syntax errors.

4. Performance Benchmarks: Serialization Speed and Payload Size

In high-throughput microservices and RESTful API data exchange, JSON remains undefeated: - Modern JSON parsers (V8 JSON.parse, simdjson) leverage CPU vector SIMD instructions, parsing gigabytes per second. - YAML parsing is significantly slower—frequently 10 to 100 times more CPU-intensive due to complex recursive type-sniffing rules. - JSON payloads are compact, gzip effectively, and deserialize natively in JavaScript browser runtimes with zero overhead.

5. Frequently Asked Questions on JSON and YAML

Is JSON a valid subset of YAML? Yes. Under the YAML 1.2 specification, JSON is formally a valid subset of YAML. Any valid JSON string can be parsed by a compliant YAML 1.2 parser. ### What is JSON5 or JSONC? Community extensions: JSONC (used in VS Code `settings.json`) allows comments; JSON5 allows comments, unquoted keys, single quotes, and trailing commas while maintaining JSON-like structure. ### Which format should I choose for an internal REST API? Always choose JSON (or binary protocols like Protocol Buffers) for network APIs. Reserve YAML strictly for human-edited infrastructure configuration files.

6. Strategic Takeaways

Use YAML where human beings must author and comment on configuration files (Kubernetes, Docker, GitHub Actions). Use JSON where microservices, web browsers, and automated APIs transmit structured data at scale.