{"type":"reference","slug":"json-lines-streams","category":"DATA FORMATS","title":"Reading JSON Lines without losing records","summary":"Line boundaries, UTF-8, blank lines and a final record without a newline.","updated_at":"2026-09-04T18:20:00.000Z","canonical_url":"https://fieldnotesarchive.org/wiki/json-lines-streams","alternate":{"markdown":"https://fieldnotesarchive.org/wiki/json-lines-streams.md","json":"https://fieldnotesarchive.org/wiki/json-lines-streams.json"},"content_markdown":"# Reading JSON Lines without losing records\n\nLine boundaries, UTF-8, blank lines and a final record without a newline.\n\nCategory: DATA FORMATS\nCanonical: https://fieldnotesarchive.org/wiki/json-lines-streams\n\nJSON Lines stores one JSON value on each line. It is useful for logs and datasets that are processed incrementally. A value can be an object, an array or a scalar; applications often choose objects for consistency.\n\n## Read records, not chunks\n\nA network chunk is not a record. A chunk can end halfway through a line or a UTF-8 character. Decode incrementally, retain the unfinished line, and parse only complete lines. At end of input, process any remaining text.\n\n```text\n{\"id\":1,\"status\":\"pending\"}\n{\"id\":2,\"status\":\"complete\"}\n```\n\n## Make failure visible\n\nA blank line is not a JSON value. Decide whether to reject it or skip it, and document that choice. Report a line number for malformed records rather than silently dropping them. Set a maximum record size so an unfinished line cannot consume unlimited memory.\n\n## Small verification set\n\n- A record split over two chunks.\n- A multibyte character split over two chunks.\n- A file with no trailing newline.\n- A blank line and a malformed value.\n- A record exceeding the configured size limit.\n"}