NDJSON

Was ist eine NDJSON-Datei?

Ein JSON-Objekt pro Zeile. Was Protokollpipelines und Datenexporte strömen lassen.

Was NDJSON ist

NDJSON ist ein reines Textformat, das sich in jedem Editor öffnen lässt. Eingesetzt wird es für den Austausch zwischen Programmen und das Streaming.

Die Endung lautet .ndjson, der volle Name Newline-Delimited JSON. Beides sagt weniger aus als das, was die Datei halten kann — und davon handelt der Rest dieser Seite.

Woher NDJSON kommt

Es geht auf 2013 zurück.

Das Alter ist aus einem praktischen Grund interessant: je älter ein Format, desto mehr Programme hatten Zeit, es zu lernen.

Die Spezifikation ist öffentlich

Sie ist vollständig veröffentlicht, das Format lässt sich also aus dem Dokument umsetzen statt durch Nachsehen. Deshalb taucht es in so vielen Programmen auf, und deshalb gehen Dateien von vor zwanzig Jahren heute noch auf. Veröffentlicht heißt allerdings nicht lizenzfrei: Wo ein Format einen Codec einpackt, ist die Patentfrage eine eigene, die der Standard nicht mitbeantwortet.

Es wird nichts weggeworfen

NDJSON speichert seinen Inhalt exakt. Erneutes Speichern ändert nichts, es lässt sich also beliebig oft öffnen, bearbeiten und wieder ablegen, ohne dass sich Schaden ansammelt — genau das macht es zu einem Arbeitsformat und nicht zu einem Ausgabeformat.

Was es sonst noch tragen kann

NDJSON kann einen Aufbau, mit dem es losspielen kann, bevor es vollständig angekommen ist halten.

Wichtig wird das vor allem beim Umwandeln: Was das Ziel nicht halten kann, fällt weg, meist ohne Warnung.

Für eine Notiz ist kein Platz

NDJSON hat keine Kommentarsyntax. Alles Erklärende muss außerhalb der Datei leben — gut zu wissen, bevor man sie für etwas wählt, das ein Mensch von Hand pflegt.

Was NDJSON öffnet

jq und pandas lesen es, und die meisten Programme derselben Art ebenfalls.

Wenn eine Datei nicht aufgeht, liegt es selten am Format — häufiger daran, dass das Programm älter ist als das Format. Die Umwandlung in etwas Älteres ist der verlässliche Weg daran vorbei, und dafür gibt es den Rest dieser Website.

Im Browser öffnen

Kein Browser liest es.

Das ist der häufigste Grund, es umzuwandeln: nicht dass das Format schlecht wäre, sondern dass die Stelle, an der die Datei erscheinen soll, es nicht lesen kann.

Es ist ein Arbeitsformat

NDJSON ist zum Öffnen und Ändern gedacht. Behalte die Datei in diesem Format, solange die Arbeit läuft, und exportiere daraus, wann immer eine fertige Fassung gebraucht wird.

Ein JSON-Array lässt sich erst lesen, wenn es endet

Genau dafür wurde das Format erfunden. Ein JSON-Dokument ist erst gültig, wenn die schließende Klammer da ist, also muss ein Parser bei einem zehn Gigabyte großen Array alle zehn Gigabyte einlesen, bevor er auch nur den ersten Datensatz herausgeben kann. Bei einem Log-Strom, der nie endet, kann er überhaupt nie etwas zurückgeben.

NDJSON entfernt das Array. Jede Zeile ist ein vollständiges, eigenständiges JSON-Objekt, durch einen Zeilenumbruch beendet und von nichts umschlossen. Eine lesende Anwendung nimmt eine Zeile, parst sie, verarbeitet sie und vergisst sie wieder — der Speicherbedarf entspricht damit dem größten einzelnen Datensatz statt der gesamten Datei, und die Verarbeitung kann sofort beim ersten Datensatz beginnen.

Anhängen ist die andere Hälfte des Arguments

Einen Datensatz an ein JSON-Array anzuhängen heißt, die Datei neu zu schreiben: Die schließende Klammer sitzt am Ende, und davor muss etwas eingefügt werden. Einen Datensatz an eine NDJSON-Datei anzuhängen heißt, eine Zeile zu schreiben.

Das macht sie zum natürlichen Format für alles, was sich über Zeit ansammelt — Anwendungsprotokolle, Ereignisströme, Prüfpfade, gecrawlte Daten, Telemetrie. Es macht sie außerdem sicherer bei gleichzeitigem Zugriff, als ein JSON-Array es je wäre: Ein einzelner Zeilenschreibvorgang unterhalb der atomaren Schreibgröße des Systems verschränkt sich nicht mit dem einer anderen schreibenden Anwendung, sodass mehrere Prozesse dieselbe Datei ohne Beschädigung erweitern können.

Ein Absturz beschädigt genau eine Zeile

Ein durch einen Absturz oder eine volle Festplatte abgeschnittenes JSON-Array ist als Ganzes ungültig — eine fehlende schließende Klammer, und ein Parser weist die gesamte Datei zurück, einschließlich der 99 Prozent, die einwandfrei angekommen sind.

Eine mitten im Schreiben abgeschnittene NDJSON-Datei verliert nur die letzte Zeile und sonst nichts. Jede vollständige Zeile davor lässt sich weiterhin einlesen, und eine lesende Anwendung kann die beschädigte überspringen und fortfahren. Bei Daten, die über Wochen gesammelt und auf Hardware gespeichert werden, die irgendwann ausfällt, ist dieser Unterschied nicht akademisch.

Wo einem das Format begegnet

Beim Log-Versand und in der Observability-Welt: Elasticsearchs Bulk-API, Logstash, Fluentd, Vector und fast jede strukturierte Logging-Bibliothek sprechen es. Datenexporte von APIs, die mehr Zeilen liefern, als in eine Antwort passen. Machine-Learning-Datensätze, bei denen ein Trainingsbeispiel eine Zeile ist und die Datei in einer Streaming-Schleife gelesen wird.

Auch als Übertragungsformat für lang laufende Anfragen, bei denen ein Server ein JSON-Objekt pro Zeile schreibt, sobald Ergebnisse verfügbar sind, und die Gegenstelle sie verarbeitet, während sie eintreffen, statt auf die vollständige Antwort zu warten.

Die Regeln, die es funktionsfähig halten

Ein Objekt pro Zeile, und darin kein Zeilenumbruch. Ein JSON-String darf einen maskierten Zeilenumbruch enthalten, aber niemals einen wörtlichen — ein hübsch formatiertes, über mehrere Zeilen verteiltes Objekt zerstört das Format vollständig, und das ist bei Weitem die häufigste Art, wie eine NDJSON-Datei falsch entsteht.

UTF-8, kein Byte-Order-Mark, und am Ende der letzten Zeile ein Zeilenumbruch statt eines fehlenden oder eines leeren Anhängsels. Die Zeilenenden sollten die einzeilige Variante sein: Ein Wagenrücklauf vor jedem Zeilenumbruch, wie unter Windows üblich, wird von den meisten Lesern toleriert und von manchen abgelehnt — genau die Art von unregelmäßigem Fehler, den niemand gern diagnostiziert.

NDJSON, JSON Lines und JSONL

Drei Namen für dieselbe Sache. NDJSON ist die Spezifikation mit eigenem Medientyp; JSON Lines ist eine separat verfasste Beschreibung desselben Formats; JSONL ist die Endung, die vor allem im Machine-Learning-Umfeld verwendet wird.

Die Unterschiede zwischen den Spezifikationen sind kosmetisch — eine Anmerkung zu Zeilenenden hier, eine erlaubte Erweiterung dort — und kein Werkzeug in der Praxis unterscheidet sie. Eine Datei mit der einen Endung lässt sich problemlos an alles übergeben, das die andere erwartet.

Umwandlung, und was dabei mit verschachtelten Feldern passiert

Nach JSON, wenn ein einziges Dokument gebraucht wird: die Zeilen in eckige Klammern packen und mit Kommas verbinden — trivial, aber es bringt das Speicherproblem zurück, das der Grund war, warum die Datei überhaupt NDJSON war.

Nach CSV oder XLSX werden verschachtelte Objekte in Spalten mit Punktnotation aufgelöst, weil eine Tabelle keine Verschachtelung kennt, und Arrays trifft dasselbe Schicksal: Jedes Element bekommt seine eigene nummerierte Spalte statt in einer Zelle zusammengefasst zu werden — bei drei Tags in einem Datensatz entstehen drei Spalten, bei einem anderen mit sieben Tags entsprechend mehr, und die Tabelle wird entsprechend breit. Für einen Report vertretbar, für ein Archiv ein echter Verlust an Struktur. Nach JSON, YAML, TOML und XML dagegen bleibt die Baumstruktur unangetastet erhalten, weil diese Formate selbst Verschachtelung kennen. Für alles Analytische ist Parquet das bessere Ziel: spaltenorientiert, typisiert, komprimiert, und deutlich schneller für die Abfragen, die man an Ereignisdaten tatsächlich stellt.

Die Eckdaten auf einen Blick

Kennungen und Herkunft des Formats NDJSON.
Endung.ndjson, .jsonl
Medientypapplication/x-ndjson
Erstmals veröffentlicht2013