Skip to content
Published on

InfluxDB 3 Core의 72시간 제한은 사실 432개 파일 제한이다 — Parquet 재작성이 남긴 청구서

공유하기
Authors

들어가며 — 72시간이라는 숫자의 정체

InfluxDB 3를 검토해 본 사람이라면 "오픈소스 Core는 최근 72시간까지만 쿼리할 수 있다"는 문장을 어딘가에서 봤을 겁니다. 커뮤니티 포럼에도, 비교 글에도 반복해서 나옵니다.

그런데 소스를 읽어 보면 72시간을 세는 코드는 없습니다. 시간 범위를 검사하는 로직 자체가 존재하지 않습니다. 실제로 존재하는 것은 이것 하나입니다 — 쿼리 하나가 건드릴 수 있는 Parquet 파일의 개수 상한. 기본값은 432개입니다.

이 구분은 말장난이 아닙니다. 제한의 단위가 시간이 아니라 파일이라는 사실이 이 제한의 성격, 이 제한이 언제 더 빨리 걸리는지, 그리고 애초에 왜 존재하는지를 전부 설명합니다. 그리고 그 답은 곧장 하나의 아키텍처 결정으로 이어집니다 — 저장 계층을 Parquet에 걸었다는 결정 말입니다.

이 글은 그 청구서를 읽습니다. 시계열 DB 진영 전체의 지형도는 시계열 데이터베이스 심층 비교 편에서 다뤘으니, 여기서는 InfluxDB 3 한 곳만 깊게 파겠습니다.

432는 어디서 왔나

InfluxDB 3 Core는 influxdata/influxdb 저장소에 MIT 또는 Apache-2.0으로 공개돼 있습니다. 그래서 이건 추측할 필요가 없는 종류의 질문입니다. 그냥 읽으면 됩니다.

먼저 플래그 정의입니다. influxdb3/src/commands/serve.rs의 주석은 이렇게 말합니다.

/// Set the limit for number of parquet files allowed in a query. Defaults
/// to 432 which is about 3 days worth of files using default settings.
/// This number can be increased to allow more files to be queried, but
/// query performance will likely suffer, RAM usage will spike, and the
/// process might be OOM killed as a result. It would be better to specify
/// smaller time ranges if possible in a query.
#[clap(long = "query-file-limit", env = "INFLUXDB3_QUERY_FILE_LIMIT", action)]
pub query_file_limit: Option<usize>,

플래그는 옵션 타입이고, 값을 안 주면 influxdb3_write/src/write_buffer/mod.rs에서 기본값이 박힙니다. 릴리스 태그 v3.10.0 기준 437번째 줄입니다.

query_file_limit: query_file_limit.unwrap_or(432),

그러면 432는 왜 432일까요. InfluxDB 3는 들어오는 데이터를 타임스탬프 기준으로 일정 길이의 시간 블록에 담아 Parquet 파일로 떨굽니다. 이 블록을 gen1이라고 부르고, 길이는 --gen1-duration으로 정합니다.

/// Duration that the Parquet files get arranged into. The data timestamps will land each
/// row into a file of this duration. 1m, 5m, and 10m are supported. These are known as
/// "generation 1" files. The compactor in Pro can compact these into larger and longer
/// generations.
#[clap(long = "gen1-duration", env = "INFLUXDB3_GEN1_DURATION", default_value = "10m", action)]
pub gen1_duration: Gen1Duration,

기본값 10분이고, 허용값은 1분·5분·10분 셋뿐입니다. 코드에서도 Duration::from_secs(600)이 기본이고, 파서는 60·300·600초만 통과시킵니다.

이제 산수가 맞아떨어집니다.

gen1 블록 = 10분
시간당 파일 = 60 / 10 = 6개
하루 파일  = 6 x 24 = 144개
432 / 144 = 3일 = 72시간

72시간은 입력값이 아니라 파생값입니다. 432라는 파일 개수 상한에 10분이라는 블록 길이를 곱해서 나온 결과일 뿐입니다. 공식 문서도 같은 이야기를 합니다 — 기본값 432와 기본 gen1-duration 10분을 쓰면 쿼리가 최대 72시간 분량의 데이터에 접근할 수 있다고요.

--gen1-duration을 1분으로 낮추면 어떻게 될까요. 432개 파일이 곧 432분, 약 7.2시간이 됩니다. 같은 432인데 조회 가능 범위가 10분의 1로 줄어듭니다. 시간 제한이 아니라 파일 제한이라는 말의 실질적 의미가 이겁니다.

하드 제한에서 소프트 제한으로

원래는 진짜로 시간 제한이었습니다. 초기 InfluxDB 3 Core에는 쿼리와 쓰기 양쪽에 72시간 하드 제한이 걸려 있었고, 이걸 걷어낸 것이 PR #25890입니다. GitHub API로 확인한 메타데이터 기준 2025년 1월 21일에 열려 1월 23일에 병합됐습니다.

PR 본문의 설명이 이 글의 요약이나 다름없습니다.

  • Core의 72시간 쿼리·쓰기 제한을 제거한다
  • 대신 쿼리를 기본 Parquet 파일 개수로 제한한다. 432를 골랐는데, gen1 타임블록 기본 설정 기준 약 72시간에 해당하기 때문이다
  • 이 파일 상한은 올릴 수 있지만, 도움말과 에러 메시지에서 쿼리 성능이 나빠질 것임을 알린다
  • 이 에러를 만나면 가능하면 더 좁은 시간 범위를 쓰라고 경고한다

그리고 마지막 문장이 핵심입니다 — 하드 제한을 없애고 사용자가 성능 손해를 감수하고 선택할 수 있는 소프트 제한을 만들되, 그 손해를 감수할 수 없다면 컴팩터가 내장된 Enterprise로 올라가는 것을 권한다.

이 문장은 2025년 1월에 쓰였고, 2026년 7월 현재까지 그대로 유효합니다.

72시간은 최선의 경우다

여기서부터가 실무에서 사람들이 놀라는 지점입니다. 문서는 432개와 10분을 곱해 72시간이 나온다고 말한 뒤, 곧바로 단서를 답니다 — 다만 주어진 10분 블록의 데이터가 전부 같은 시기에 인제스트됐는지에 따라 그보다 짧을 수 있다고요.

왜 그런지는 파일 경로를 만드는 코드를 보면 명확합니다. influxdb3_write/src/paths.rs입니다.

{host_prefix}/dbs/{db_id}/{table_id}/{YYYY-MM-DD}/{HH-MM}/{wal_seq}.parquet

디렉터리까지가 gen1 블록(날짜 + 시·분)이고, 파일 이름은 WAL 시퀀스 번호입니다. 즉 하나의 10분 블록 안에 서로 다른 WAL 시퀀스로 만들어진 파일이 여러 개 공존할 수 있습니다. 같은 10분에 대해 스냅샷이 두 번 일어나면 파일이 두 개 생기고, 그 블록은 이제 파일 예산 432개 중 2개를 먹습니다.

기본 설정에서 이 일이 잘 안 일어나도록 맞춰져 있긴 합니다. --wal-flush-interval 기본이 1초, --wal-snapshot-size 기본이 600이고, 플래그 설명대로 이 둘을 곱한 값이 스냅샷 주기를 정합니다. 600초 = 10분이니 스냅샷 주기가 gen1 블록 길이와 정확히 맞고, 따라서 블록당 파일 하나가 됩니다.

문제는 데이터가 항상 얌전히 도착하지 않는다는 겁니다. 과거 시점으로 백필을 하거나, 지연 도착 데이터가 이미 스냅샷된 블록으로 들어오면 그 블록에 파일이 추가로 생깁니다. 그러면 432개 예산이 72시간보다 빨리 소진됩니다. 백필이 잦은 워크로드일수록 "72시간"이라는 숫자는 점점 거짓말이 됩니다.

정리하면 72시간은 보장이 아니라 상한선이고, 그것도 데이터가 실시간으로만 들어올 때의 상한선입니다.

제한에 걸리면 무슨 일이 생기나

강제 지점은 write_buffer/mod.rs에서 파일 목록을 세는 곳입니다. 로직 자체는 세 줄 요약이 가능합니다 — 해당 테이블에서 필터를 통과한 Parquet 파일을 모으고, 개수가 상한을 넘으면 DataFusion 에러를 던지고 끝냅니다.

여기서 세 가지를 짚어야 합니다.

첫째, 제한은 테이블 단위입니다. 파일 목록을 가져올 때 데이터베이스 ID와 테이블 ID로 필터링하므로, 432는 "쿼리 전체"가 아니라 "쿼리가 건드리는 테이블 하나"의 예산입니다.

둘째, 이건 스캔 후 실패가 아니라 계획 단계의 거절입니다. 파일을 열어 보고 느려지는 게 아니라, 파일 개수를 세어 보고 아예 실행을 거부합니다. 부분 결과도 없습니다.

셋째, 에러 메시지에 사소한 버그가 있습니다. 메시지의 자리표시자에 넘기는 포맷 인자가 실제로 스캔하려던 파일 수가 아니라 상한값 자체입니다.

format!(
    "Query would scan {} Parquet files, exceeding the file limit. \
     InfluxDB 3 Core caps file access to prevent performance degradation \
     and memory issues. Use a narrower time range, or increase the limit \
     with --query-file-limit ...",
    self.query_file_limit
)

인자가 하나뿐이고 그 값이 상한입니다. 그래서 5,000개짜리 쿼리를 던져도 메시지는 언제나 "Query would scan 432 Parquet files"라고 나옵니다. 내가 얼마나 초과했는지는 이 에러로 알 수 없습니다. 시간 범위를 얼마나 줄여야 하는지 감을 잡으려던 사람에게는 꽤 불친절한 동작입니다.

메시지 본문은 상한을 올리라고 권하지 않습니다. 더 좁은 시간 범위를 쓰거나, 컴팩터가 들어 있는 Enterprise로 올라가라고 안내합니다. 비상업·가정용은 무료이고 상업 평가용 무료 체험이 있다는 문구까지 에러 메시지 안에 들어 있습니다.

올리면 되지 않나 — 오브젝트 스토리지 청구서

--query-file-limit을 4320으로 올려서 30일을 조회하면 안 되나요? 됩니다. 다만 문서가 나열한 부작용이 있습니다.

  • Parquet 파일을 더 많이 읽는 쿼리의 성능 저하
  • 메모리 사용량 증가
  • OOM으로 influxdb3 프로세스가 죽을 가능성
  • 오브젝트 스토리지를 쓴다면 데이터 접근을 위한 다수의 GET 요청 — 문서 표현으로 파일당 최대 2회

마지막 항목이 조용한 킬러입니다. 기본값 432개만 해도 쿼리 한 번에 최대 864회의 GET입니다. 이걸 4320개로 올리면 대시보드가 자동 새로고침할 때마다 쿼리 하나당 최대 8,640회의 GET이 나갑니다. S3 GET 단가는 요청 1,000건 단위로 매겨지므로, 이건 성능 문제이기 전에 청구서 문제입니다.

그리고 이건 Parquet 설계의 직접적 귀결입니다. Parquet 파일 하나를 읽으려면 푸터의 메타데이터를 먼저 읽고, 그다음 필요한 로우 그룹을 읽어야 합니다. 파일이 작고 많을수록 실제 데이터 대비 메타데이터 왕복 비율이 나빠집니다. 10분마다 파일 하나씩 떨어지는 구조는 정확히 그 최악의 형태입니다.

문서가 내리는 권고는 솔직합니다 — 기본 설정을 유지하고 더 짧은 시간 범위를 조회하라. 한 시간 이상을 건드리는 쿼리에서 더 긴 범위나 더 빠른 성능이 필요하면 Enterprise를 쓰라.

컴팩터가 답이고, 컴팩터는 유료다

작은 불변 파일이 쌓이는 문제의 정답은 컴팩션입니다. 작은 파일들을 더 크고 긴 시간 범위의 파일로 다시 써서, 파일 개수를 줄이고 시리즈 기준으로 정렬하고 인덱스를 붙이는 것.

InfluxDB 3에 그 컴팩터가 있습니다. Enterprise에만 있습니다.

이건 문서 구조에서도 그대로 드러납니다. 컴팩터 전용 노드를 띄우는 --mode=compact 설정 예시는 문서 소스에서 Enterprise 전용 블록 안에 들어 있고, mode 옵션 자체가 Enterprise 전용 항목으로 분류돼 있습니다. Core에는 컴팩터 노드라는 개념이 없습니다.

Core 문서의 첫 문장이 이 사실을 에둘러 말합니다 — InfluxDB 3 Core는 실시간 및 최근 데이터에 맞춰 설계·최적화된 오픈소스 시계열 데이터베이스라고요. 이건 마케팅 문구이기 이전에 아키텍처 설명입니다. 컴팩터가 없으니 최근 데이터만 볼 수 있고, 그래서 최근 데이터용이라고 포지셔닝한 겁니다.

같은 구조가 다른 곳에도 반복됩니다. Core의 README가 자랑하는 성능 수치는 last-value 쿼리 10ms 미만, distinct 메타데이터 30ms 미만인데, 이건 일반 쿼리 성능이 아니라 last-value 캐시와 distinct value 캐시의 성능입니다. 두 캐시는 메모리에 얹은 별도 구조물입니다. Parquet 레이아웃 위에서 "이 시리즈의 마지막 값" 같은 포인트 조회가 빠를 수 없기 때문에 따로 만든 것이고, 캐시가 필요했다는 사실 자체가 저장 계층이 그 질문에 약하다는 증거입니다.

2026년, 삭제도 컴팩터의 일이 되다

2026년 6월 17일 릴리스된 v3.10.0에서 Enterprise에 행 단위 삭제가 들어왔습니다. 그런데 구현 방식이 이 글의 주제를 그대로 반복합니다.

문서에 따르면 삭제는 비동기입니다. influxdb3 delete rows를 실행하면 삭제 요청이 기록돼 오브젝트 스토리지에 저장되고, 컴팩터가 해당 데이터를 다시 쓸 때 요청이 적용됩니다. 기본적으로 요청 후 최대 24시간까지 삭제가 반영되지 않으며, 이 지연은 --pt-row-delete-min-age 플래그로 조정합니다. 문서는 못을 박습니다 — 삭제가 컴팩션 중에 적용되므로 컴팩터가 요청을 처리하기 전까지 행은 계속 조회되며, 명령이 반환됐다고 행이 즉시 사라질 것으로 기대하지 말라고요.

술어는 태그 동등 비교만 지원합니다. 필드 값으로는 지울 수 없습니다.

그리고 v3.10.0 문서의 알려진 이슈 목록에 이런 항목이 있습니다 — 행 삭제가 "완료"로 보고된 뒤에도 컴팩션되지 않은 인제스트 꼬리 부분의 행이 살아남아 쿼리에 계속 보일 수 있다. 회피책은 해당 데이터가 컴팩션된 뒤 삭제 요청을 다시 넣고 행 수를 확인하는 것.

이건 우연한 버그가 아니라 설계의 논리적 귀결입니다. 삭제가 파일 재작성으로 구현되면, 아직 재작성되지 않은 영역에서는 삭제가 존재하지 않습니다. Parquet 파일은 불변이니까요.

Core 쪽은 어떨까요. 공식 문서 저장소에서 Core의 관리 문서 목록에는 delete-data.md가 아예 없습니다. Enterprise에만 있습니다. 컴팩터가 없으면 행을 지울 방법도 없습니다. GDPR 삭제 요청이 오는 종류의 데이터를 오픈소스 Core에 넣고 있다면 지금 확인해 보시길 권합니다.

2026년의 진짜 뉴스 — Parquet 위에 새 엔진

여기까지가 배경이고, 이제 올해의 소식입니다.

2026년 4월 2일 릴리스된 v3.9.0에서 InfluxData는 성능 업그레이드 프리뷰(베타) 를 열었습니다. --use-pacha-tree 플래그로 켜고, 릴리스 노트의 표현으로는 새 컬럼 파일 포맷(.pt 파일), 하이브리드 쿼리 모드를 동반한 자동 Parquet 마이그레이션, 넓은 테이블 I/O를 위한 컬럼 패밀리, 그리고 경계가 있는 컴팩션을 포함합니다.

정리하면 InfluxDB가 Parquet에서 부분적으로 나오고 있습니다. InfluxDB 3의 첫 정식 릴리스인 v3.0.0이 2025년 4월 16일이었으니, GA로부터 약 1년 만입니다.

왜인지는 추측할 필요가 없습니다. 벤더가 직접 써 놨습니다. 프리뷰 문서의 "Why these upgrades" 절은 이렇게 시작합니다 — 기존 InfluxDB 3 저장 계층은 Apache Parquet을 사용하며 분석 워크로드에 최적화돼 있다. 그리고 고카디널리티·와이드 스키마·쿼리 집약적 워크로드를 돌리는 고객들은 더 나은 단일 시리즈 쿼리 성능, 더 예측 가능한 리소스 사용량, 그리고 InfluxDB v1과 v2를 인기 있게 만들었던 스키마 유연성을 필요로 한다.

마지막 구절을 다시 읽어 볼 만합니다. v1과 v2를 인기 있게 만들었던 것을 되찾겠다는 문장입니다. v1·v2의 저장 엔진이 바로 시계열 전용으로 만든 TSM이었고, 3.0에서 버린 것이 그 TSM이었습니다.

.pt 포맷의 설명을 보면 그 회귀가 더 분명해집니다. 문서에 따르면 파일 내 데이터는 컬럼 패밀리 키·시리즈 키·타임스탬프 순으로 정렬되고, 데이터 특성에 맞춰 타입별 압축 알고리즘을 씁니다 — 타임스탬프에는 delta-delta RLE, 부동소수점에는 Gorilla 인코딩, 저카디널리티 문자열에는 딕셔너리 인코딩 등.

여기서 Gorilla가 눈에 띕니다. Parquet 포맷 명세의 인코딩 목록을 직접 확인해 보면 PLAIN, 딕셔너리(PLAIN_DICTIONARY / RLE_DICTIONARY), RLE, BIT_PACKED(폐기됨), DELTA_BINARY_PACKED, DELTA_LENGTH_BYTE_ARRAY, DELTA_BYTE_ARRAY, BYTE_STREAM_SPLIT가 전부입니다. 부동소수점 XOR 계열 인코딩, 즉 Gorilla는 명세에 없습니다. 시계열 float 압축의 표준 기법을 쓰려면 Parquet 바깥으로 나가는 수밖에 없었던 겁니다.

압축률에 대해 문서는 일반적으로 5~20배를 달성한다고 적었습니다. 다만 이건 벤더 자체 주장이고, 어떤 데이터셋·어떤 스키마·어떤 비교 대상 기준인지는 문서에 없습니다. 비교 대상이 Parquet인지 원본 line protocol인지조차 명시돼 있지 않으므로, 이 숫자로 용량 계획을 세우면 안 됩니다. 마찬가지로 "고선택도 시계열 쿼리에서 한 자릿수 밀리초 응답"이라는 문구도 측정 조건이 공개돼 있지 않습니다. 목표치로 읽는 편이 안전합니다.

컬럼 패밀리는 line protocol 필드 이름에 :: 구분자를 써서 지정합니다. 첫 :: 앞이 패밀리 이름이고, 지정하지 않은 필드는 자동 생성 패밀리에 100개씩 묶입니다. 넓은 테이블에서 특정 필드만 조회할 때 나머지 패밀리 블록을 아예 읽지 않는 구조입니다.

컴팩션도 바뀝니다. 문서에 따르면 컴팩트된 데이터를 24시간 UTC 윈도로 조직하고 Gen0 파일을 L1부터 L4까지 진행시키며, 바이트 기준 메모리 예산(기본값 시스템 RAM의 절반) 안에서 백그라운드로 계속 돕니다.

프리뷰의 값 — 정직하게

여기서 흥분하기 전에 문서가 붙여 놓은 경고들을 그대로 옮기겠습니다.

베타이고, 프로덕션 금지입니다. 문서의 경고 박스는 이 프리뷰가 Enterprise 체험·상용 사용자에게 베타로 제공되며, 변경이 있을 수 있고 프로덕션 워크로드에 사용해서는 안 된다고 명시합니다. 스테이징·테스트 환경 전용이라고 못 박습니다.

v3.10.0 알려진 이슈에 데이터 손실이 있습니다. --use-pacha-tree를 켠 상태에서 샤드를 2개 이상(--pt-shard-count) 돌리면 데이터 손실과 부트스트랩 데드락이 발생할 수 있습니다. 회피책은 샤드 수를 1로 유지하는 것. 즉 현재 이 프리뷰는 사실상 단일 샤드로만 쓸 수 있습니다.

다운그레이드는 되돌리기가 아닙니다. influxdb3 downgrade-to-parquet은 카탈로그를 갱신하고 모든 .pt 파일을 오브젝트 스토리지에서 지웁니다. 문서 표현으로 업그레이드 이후에 쓰인 데이터까지 포함해서 지우며, 업그레이드 이전에 존재하던 원본 Parquet 파일만 보존됩니다. 프리뷰를 켜고 한 달 데이터를 쌓은 뒤 마음을 바꾸면 그 한 달은 사라집니다.

3.10 업그레이드 자체가 편도입니다. 3.10을 처음 시작하면 온디스크 카탈로그가 v2에서 v3로 자동 마이그레이션되고, 그 뒤로는 3.9.x 이하 바이너리가 같은 클러스터 데이터를 읽지 못해 시작에 실패합니다. 릴리스 노트는 카탈로그 디렉터리와 카탈로그 체크포인트 객체를 미리 백업하라고, 그 객체를 복원하는 것이 3.9.x로 롤백하는 유일한 방법이라고 적었습니다. --use-pacha-tree를 켰다면 .pt 포맷으로 쓰인 데이터도 3.9.x가 읽지 못합니다.

그리고 이 전부가 Enterprise 전용입니다. Core는 .pt도, 컬럼 패밀리도, 경계 있는 컴팩션도 받지 못합니다. Core는 계속 432개 파일 예산 안에서 삽니다.

Core와 Enterprise의 온도 차는 릴리스 노트를 연달아 읽으면 노골적으로 보입니다. 2026년 6월 25일 v3.9.6, 6월 30일 v3.10.2와 v3.9.7 — 이 세 릴리스의 Core 항목은 전부 같은 문장입니다. 유지보수 릴리스이며 빌드와 의존성 업데이트만 포함하고 사용자가 체감할 변경은 없다. 같은 날짜의 Enterprise 항목에는 컴팩션 중복 제거 수정과 프로세싱 엔진 트리거 취소 수정이 들어 있습니다.

그래서, 언제 쓰고 언제 쓰지 말아야 하나

Core로 충분한 경우. Core는 나쁜 제품이 아닙니다. 자기가 하겠다고 말한 일을 합니다.

  • 조회 범위가 최근 몇 시간~며칠인 실시간 대시보드와 알림
  • 엣지·IoT 수집 지점에서 버퍼링 후 상류로 넘기는 용도
  • 최신 값 조회가 중심인 워크로드 — last-value 캐시가 이걸 위해 있습니다
  • 데이터가 실시간으로만 들어오고 백필이 없는 파이프라인

Core로는 안 되는 경우. 아래에 하나라도 해당하면 오픈소스 Core는 답이 아닙니다. 튜닝으로 넘길 수 있는 종류의 벽이 아닙니다.

  • 며칠을 넘는 과거 구간을 정기적으로 조회해야 한다 — 파일 상한을 올리면 GET 요청과 메모리가 같이 올라갑니다
  • 백필이나 지연 도착 데이터가 잦다 — 같은 gen1 블록에 파일이 겹쳐 쌓이고 72시간은 더 빨리 무너집니다
  • 행을 지워야 한다 — Core에는 방법이 없습니다
  • --gen1-duration을 1분으로 줄여야 하는 사정이 있다 — 조회 가능 범위가 7.2시간대로 내려갑니다

Enterprise 프리뷰를 켜 볼 만한 경우. 문서가 권하는 대상은 고카디널리티·와이드 테이블, 시간 범위를 넘나드는 잦은 백필, 낮은 지연이 필요한 쿼리 집약적 접근, 동적으로 컬럼이 생기는 희소 스키마, 그리고 메모리·CPU 사용량의 상한이 중요한 환경입니다. 다만 스테이징에서, 단일 샤드로, 지워도 되는 데이터로 시작하십시오.

대안을 봐야 하는 경우. 오픈소스로 장기 보관과 삭제와 과거 조회를 전부 해야 한다면, 이 선택지는 애초에 InfluxDB 3 Core가 아닐 수 있습니다. Postgres 확장으로 가든 컬럼 스토어로 가든, 비교의 출발점은 시계열 데이터베이스 심층 비교 편에 정리해 뒀습니다.

마치며

정리하면 이렇습니다. "InfluxDB 3 Core는 72시간 제한이 있다"는 문장은 틀린 요약입니다. 정확히는 쿼리 하나가 테이블 하나에서 스캔할 수 있는 Parquet 파일이 기본 432개로 제한되고, 기본 gen1 블록 10분을 곱하면 72시간이 나오며, 그 72시간조차 데이터가 실시간으로만 도착할 때의 최선값입니다.

이 제한은 자의적인 기능 제한이 아닙니다. Parquet 위에 시계열 DB를 지으면 필연적으로 작고 불변인 파일이 대량으로 생기고, 그걸 정리하는 유일한 방법이 컴팩션이며, InfluxData는 그 컴팩터를 상용 경계선으로 삼았습니다. 오픈소스 Core는 그 결정의 모든 결과를 그대로 물려받습니다 — 파일 상한, 파일당 최대 2회의 GET, 그리고 삭제 기능의 부재.

그리고 2026년, 이 아키텍처의 청구서가 벤더 자신에게도 도착했습니다. Parquet이 분석 워크로드에 최적화돼 있다는 것, 그래서 단일 시리즈 쿼리와 와이드 스키마에는 부족하다는 것 — 이건 제가 하는 말이 아니라 InfluxData의 프리뷰 문서에 적힌 말입니다. 그 결과가 .pt이고, 거기에는 Parquet 명세에 없는 Gorilla 인코딩이 들어갑니다. v1과 v2의 TSM이 갖고 있던 바로 그 기법이요.

교훈이 있다면 범용 포맷을 고르는 일의 성격에 대한 것 같습니다. Arrow와 Parquet과 DataFusion을 고른 덕분에 InfluxDB 3는 SQL과 Flight SQL과 생태계 도구를 거의 공짜로 얻었습니다. 그건 진짜 이득이었습니다. 다만 범용 포맷은 범용적인 것에 최적화돼 있고, 당신의 워크로드가 그 평균에서 멀어질수록 차액을 어딘가에서 지불하게 됩니다. InfluxDB 3의 경우 그 차액은 컴팩터라는 이름의 유료 컴포넌트와, GA 1년 만에 자체 파일 포맷을 다시 만드는 일로 청구됐습니다.

기술 선택을 검토할 때 릴리스 노트의 기능 목록보다 이런 걸 먼저 보시길 권합니다 — 이 시스템의 근본 제약이 무엇이고, 그 제약을 푸는 컴포넌트가 어느 라이선스 쪽에 있는가.

참고 자료