본문 바로가기

파일 형식 백과사전

JSON 한 줄 저장과 들여쓰기 저장, 용량이 얼마나 차이 날까 (실측과 정리 방법)

API에서 받은 JSON을 메모장으로 열었더니 처음부터 끝까지 한 줄로 뭉쳐 있어 어디가 어디인지 읽기 어렵습니다. 반대로 보기 좋게 정리된 JSON을 저장했더니 파일이 부쩍 커져서 전송이 부담스러운 경우도 있습니다.

이 두 가지는 같은 데이터의 양면입니다. JSON은 같은 내용을 한 줄로 압축(minify)해 저장할 수도, 들여쓰기로 정렬(pretty)해 저장할 수도 있고, 둘은 용량이 꽤 다릅니다. 얼마나 다른지 직접 재 보고, 상황에 맞게 바꾸는 방법을 정리하겠습니다.

 

같은 1,000행을 두 방식으로 저장해 재 봤습니다

객체 1,000개가 담긴 배열(필드 5개: id, name, age, city, active)을 만들어 같은 데이터를 여러 방식으로 저장하고 크기를 쟀습니다. 측정 환경은 윈도우 11, 파이썬 3.14.3, 표준 라이브러리 json입니다. name 필드에는 한글 이름이 들어갑니다.

저장 방식 용량 한 줄 대비
한 줄 저장 (minify) 약 67.7 KB 1.00배
들여쓰기 저장 (indent=2, 줄바꿈 LF) 약 102.9 KB 1.52배
들여쓰기 저장 (윈도우 기본 줄바꿈 CRLF) 약 109.7 KB 1.62배

내용이 완전히 같은데도 들여쓰기로 정렬하면 한 줄 저장보다 1.5배가 넘습니다. 들여쓰기 저장이 더해 넣는 것은 데이터가 아니라 사람이 읽기 위한 공백과 줄바꿈입니다. 그래서 값은 1바이트도 안 바뀌고 자리만 늘어납니다.


왜 정렬하면 커질까, 한 객체로 비교

같은 한 사람의 데이터가 두 방식에서 어떻게 적히는지 보면 차이가 분명합니다.

한 줄(minify):
{"id":1,"name":"김민수","age":36,"city":"인천","active":true}

들여쓰기(indent=2):
{
  "id": 1,
  "name": "김민수",
  "age": 36,
  "city": "인천",
  "active": true
}

한 줄 저장은 쉼표와 콜론만으로 값을 붙여 쓰지만, 들여쓰기 저장은 필드마다 줄을 바꾸고 앞에 공백 두 칸을 넣습니다. 콜론 뒤에도 공백이 하나 붙습니다. 객체 하나에 들어가는 이 여분의 공백과 줄바꿈이 1,000개 쌓이면서 용량 차이가 벌어집니다.

여기서 윈도우 사용자는 한 가지를 더 봐야 합니다. 윈도우는 줄바꿈을 두 바이트(CRLF)로 저장하는 것이 기본이라, 줄 수가 많은 들여쓰기 JSON에서는 같은 정렬이라도 용량이 더 붙습니다. 위 표에서 같은 들여쓰기인데 102.9 KB와 109.7 KB로 갈린 것이 그 차이입니다.

정렬과 압축, 코드 한 줄 차이입니다

파이썬 표준 라이브러리 json에서는 저장 옵션 하나로 두 방식을 오갈 수 있습니다. 먼저 보기 좋게 정렬해 저장하는 방법입니다.

import json

# 들여쓰기로 정렬해 저장 (사람이 읽기 좋음)
with open("pretty.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

반대로 공백을 모두 걷어 내고 한 줄로 압축하는 방법입니다. 핵심은 separators 옵션으로 쉼표와 콜론 뒤의 공백까지 없애는 것입니다.

import json

# 한 줄로 압축해 저장 (전송에 가벼움)
with open("min.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, separators=(",", ":"))

이미 한 줄로 뭉친 JSON을 받았다면, 읽어서 다시 indent=2로 저장하면 정렬됩니다. 명령줄에서는 별도 코드 없이 python -m json.tool로도 바로 정리할 수 있습니다.

python -m json.tool input.json output.json --indent 2

옵션 두 개의 실제 효과도 재 봤습니다

저장할 때 자주 보이는 옵션 두 가지가 용량에 어떤 영향을 주는지 같은 데이터로 확인했습니다.

저장 방식 용량 한 줄(UTF-8) 대비
한 줄 저장 (UTF-8 그대로) 약 67.7 KB 1.00배
한 줄 저장 + sort_keys=True 약 67.7 KB 1.00배
한 줄 저장 + ensure_ascii=True 약 82.4 KB 1.22배

sort_keys=True는 키를 알파벳 순으로 정렬해 주는 옵션인데, 용량은 그대로였습니다. 키의 글자 수가 변하지 않고 순서만 바뀌기 때문입니다. 정렬은 두 파일을 비교하거나 결과를 일정하게 만들 때 쓰면 좋고, 용량 부담은 없습니다.

ensure_ascii는 결과가 다릅니다. 이 옵션은 기본값이 True여서, 한글 같은 비영어 문자를 김민수처럼 풀어 쓴 형태로 저장합니다. 한 글자가 여섯 글자로 늘어나니 한글이 많을수록 커집니다. 그래서 한글 데이터라면 ensure_ascii=False로 두는 것만으로 같은 데이터를 22% 더 작게 저장할 수 있었습니다.

직접 재현해 보고 싶다면

아래 코드를 그대로 실행하면 위와 같은 1,000행 데이터를 만들고 네 방식으로 저장해 각 크기를 출력합니다. 추가 설치 없이 파이썬 표준 라이브러리만 씁니다.

import os, json, random
random.seed(7)

sur = ["김","이","박","최","정","강","조","윤","장","임"]
giv = ["민수","서연","지훈","하은","도윤","수아","예준","지우","시우","유진"]
cit = ["서울","부산","대구","인천","광주","대전","울산","수원","성남","고양"]

data = [{
    "id": i,
    "name": random.choice(sur) + random.choice(giv),
    "age": random.randint(19, 65),
    "city": random.choice(cit),
    "active": random.choice([True, False]),
} for i in range(1, 1001)]

def save(fn, **kw):
    with open(fn, "w", encoding="utf-8", newline="") as f:
        json.dump(data, f, **kw)
    return os.path.getsize(fn)

print("min      ", save("min.json", ensure_ascii=False, separators=(",", ":")))
print("pretty   ", save("pretty.json", ensure_ascii=False, indent=2))
print("ascii    ", save("ascii.json", separators=(",", ":")))
print("sort_keys", save("sort.json", ensure_ascii=False,
                        separators=(",", ":"), sort_keys=True))

seed를 7로 고정해 같은 환경이라면 거의 같은 크기가 나옵니다. 위 코드는 줄바꿈 변환을 끄려고 newline=""을 줬습니다. 이 줄을 빼고 윈도우 기본으로 저장하면 들여쓰기 파일은 줄바꿈이 CRLF로 바뀌어 조금 더 커집니다.

자주 묻는 질문

Q. 압축해 저장하면 데이터가 줄어 손상되나요?
아닙니다. 사라지는 것은 공백과 줄바꿈뿐이고 값은 그대로입니다. 한 줄 파일을 다시 indent=2로 저장하면 보기 좋은 형태로 똑같이 복원됩니다.

Q. 어떤 환경에서도 들여쓰기가 한 줄보다 큰가요?
네, 같은 데이터라면 방향은 항상 같습니다. 들여쓰기는 한 줄 저장에 공백과 줄바꿈을 더하는 구조라 줄어들 수가 없습니다. 다만 정확한 배수는 필드 수와 값 길이, 줄바꿈 방식(LF/CRLF)에 따라 달라집니다.

Q. 사람이 읽을 일도 없는데 indent를 왜 쓰나요?
디버깅하거나 깃에서 변경 내역을 비교할 때는 들여쓰기가 편합니다. 사람이 볼 일이 없는 전송용이나 로그 적재용이라면 한 줄 저장이 가볍습니다.

 

지금 다루는 JSON 파일을 메모장에서 열어 한 줄로 뭉쳐 있다면 python -m json.tool로 한 번 정리해 두고, 전송하거나 보관할 큰 파일이라면 separators로 한 줄 저장해 보세요. 같은 데이터라도 용도에 맞게 모양만 바꾸면 읽기와 용량을 둘 다 챙길 수 있습니다.