왜 지금 dbt Core 1.12를 봐야 하나
dbt Core 1.12가 2026년 7월 16일 공개됐다. 이번 릴리스는 모델 문법 하나를 더하는 성격보다 dbt를 어떻게 설치하고, 어떻게 파싱하고, 어떤 기본 동작을 CI에 고정할 것인가를 다시 정리하는 릴리스에 가깝다.
운영자 관점에서 중요한 변화는 네 가지다.
- v2 Rust parser opt-in: 같은 프로젝트를 더 빠르게 파싱해 볼 수 있지만, partial parsing과 artifact 처리 방식이 달라진다.
- native private packages: 토큰 기반 Git URL 대신 SSH 기반 private package 선언을 쓸 수 있다.
- behavior change flag maturity: 1.9~1.10 시기에 들어온 여러 플래그가 기본값 전환 구간에 들어왔다. 이 구간은 조용한 빌드 차이를 만들기 쉽다.
- experimental 경로 제거:
dbt login, bundleddbt-state,--manage-state,DBT_ENGINE_STATE_*환경변수 같은 실험 경로가 빠졌다.
즉, 1.12는 “새 기능을 하나 더 켠다”보다 파서·의존성·기본 동작을 버전 관리된 운영 규칙으로 옮기는 릴리스라고 보는 편이 맞다.
한눈에 보는 1.12 변화
| 영역 | 무엇이 바뀌었나 | 운영 영향 |
|---|---|---|
| 파싱 | --use-v2-parser로 Rust 기반 Fusion parser를 opt-in 가능 | 대형 프로젝트 parse 시간 단축 가능, 대신 partial parsing 비활성화와 manifest handoff 차이를 검증해야 함 |
| 의존성 | packages.yml / dependencies.yml에서 private: + provider: 지원 | 토큰 배포를 줄일 수 있지만, CI runner의 SSH key·known_hosts가 새 필수 요소가 됨 |
| 기본 동작 | 여러 behavior flag가 maturity 단계에 진입 | 이전 동작을 암묵적으로 기대한 프로젝트는 parse/build 결과가 달라질 수 있음 |
| 실험 기능 | dbt login, bundled dbt-state, manage_state 관련 표면 제거 | 사내 wrapper script, 문서, CI env var가 1.12에서 바로 깨질 수 있음 |
private: org/repo
provider: github
runner deploy key
known_hosts
token 없는 fetch
Python parser
use_v2_parser: true
Fusion Rust parser handoff
partial parsing off
manifest diff 확인
flags: ...
default-on 되는 플래그 존재
모든 핵심 flag를 명시적으로 커밋
v2 parser: 속도보다 먼저 봐야 할 것은 handoff 방식이다
1.12의 가장 큰 구조 변화는 --use-v2-parser다. 공식 문서는 이 플래그가 dbt Core의 Python parser 대신 Fusion의 Rust parser에 parsing을 위임한다고 설명한다. 대형 프로젝트에서 5~10배 빠를 수 있다는 수치도 공식 문서에 함께 나온다.
하지만 운영에서 더 중요한 것은 성능 자체보다 파서 경로가 바뀌면서 생기는 부작용이다.
바뀌는 점
dbt parse --use-v2-parser또는flags.use_v2_parser: true로 켠다.- dbt는 자체 parser를 끝까지 돌리지 않고, Fusion parser가 만든
manifest.json을 읽어 handoff한다. - partial parsing은 비활성화된다.
- 기존
partial_parse.msgpack가 남아 있으면 자동 삭제된다. write_manifest는 이 모드에서 기대대로 동작하지 않는다. canonical artifact는 Fusion parser가 만든 쪽이다.
즉, 1.12의 v2 parser는 parse acceleration feature이면서 동시에 compatibility canary다. 그래서 바로 production job 전체에 켜기보다 dbt parse와 짧은 CI 경로에서 먼저 시험하는 것이 맞다.
flags:
use_v2_parser: true운영 체크 포인트
| 항목 | 왜 확인해야 하나 |
|---|---|
dbt parse 성공 여부 | 가장 가벼운 parser compatibility 확인 경로이기 때문 |
| 선택 집합(selection) 차이 | parser가 만든 manifest가 달라지면 state:modified나 graph selection이 바뀔 수 있기 때문 |
target/manifest.json diff | 다운스트림 도구(문서화, lineage, CI gating)가 artifact를 읽는 경우 영향이 있기 때문 |
| partial parsing 제거 영향 | 개발자 로컬 체감 속도는 빨라져도 반복 parse 패턴은 달라질 수 있기 때문 |
실무적으로는 "속도 향상"보다 "manifest semantics가 바뀌지 않았는가"를 먼저 확인해야 한다.
native private packages: tokenless가 아니라 SSH 의존성으로 옮겨간다
1.12는 packages.yml과 dependencies.yml에서 private: 키를 지원한다. 예전처럼 전체 Git URL이나 토큰 환경변수를 직접 들고 다니지 않아도 된다.
packages:
- private: your-org/analytics_shared
provider: "github"이 변화의 장점은 분명하다.
- package 선언이 짧아진다.
- token 환경변수 배포를 줄일 수 있다.
- dbt Platform에서는 기존 Git integration을 재사용할 수 있다.
- 로컬/CI에서는 provider별 SSH 구성을 그대로 활용한다.
하지만 운영 비용이 사라지는 것은 아니다. 비용의 위치가 token 관리에서 SSH 관리로 옮겨간다.
새로 챙겨야 할 것
- runner에 deploy key 또는 machine user key가 준비돼 있어야 한다.
known_hosts가 없으면 non-interactive job에서 첫 연결이 멈출 수 있다.- GitHub / GitLab / Azure DevOps마다 SSH URL 형태가 달라
provider를 정확히 지정해야 한다. - 토큰 회전 대신 SSH key 회전과 권한 범위를 관리해야 한다.
그래서 native private packages는 보안이 자동으로 쉬워지는 기능이 아니라, 패키지 의존성 표면을 Git 표준 방식으로 정렬하는 기능으로 보는 편이 맞다.
behavior flag maturity: 릴리스 노트 한 줄만 믿으면 안 된다
1.12 릴리스 노트는 “1.9와 1.10에 도입된 flags defaults to true”라고 요약한다. 그런데 behavior change registry를 실제로 보면 상황이 더 세밀하다.
공식 문서는 behavior change flag를 dbt_project.yml의 flags: 아래 두고, pull request와 테스트를 거쳐 버전 관리해야 한다고 명시한다. 이유는 단순하다. 이 플래그들은 CLI 개인 취향이 아니라 프로젝트 코드의 의미를 바꾸는 설정이기 때문이다.
1.12에서 maturity(기본값 전환)로 보아야 할 대표 플래그
| 플래그 | 영향 |
|---|---|
skip_nodes_if_on_run_start_fails | on-run-start 실패 시 build 중단/skip 동작이 달라질 수 있음 |
state_modified_compare_more_unrendered_values | state:modified selection 결과가 CI에서 달라질 수 있음 |
require_batched_execution_for_custom_microbatch_strategy | custom microbatch macro 동작이 새 규칙을 기대함 |
require_nested_cumulative_type_params | parse error 가능 |
validate_macro_args | macro 인자 mismatch가 warning으로 드러나고 --warn-error와 결합 시 실패 가능 |
require_all_warnings_handled_by_warn_error | warn-error 운영 정책에 직접 영향 |
한 번에 전환된 것이 아닌 플래그도 있다
여기서 중요한 점이 하나 더 있다.
require_generic_test_arguments_property는 behavior registry상 maturity가 이미1.10.8로 표기된다.enable_truthy_nulls_equals_macro는 현재 registry에 maturity version이 비어 있다.
즉, 릴리스 노트의 요약 문장은 방향을 알려주지만, 실제 cutover 시점은 플래그별로 다르다. 운영자는 “1.12니까 1.9/1.10 플래그가 전부 같은 날 켜진다”고 가정하면 안 된다. 실제로는 registry 표를 기준으로 현재 프로젝트가 의존하는 플래그를 하나씩 확인해야 한다.
실무 권장안
dbt_project.yml에 현재 의존하는 핵심 플래그를 모두 명시해 두는 편이 안전하다.
flags:
use_v2_parser: false
validate_macro_args: true
require_all_warnings_handled_by_warn_error: true
skip_nodes_if_on_run_start_fails: true
state_modified_compare_more_unrendered_values: true핵심은 값이 true냐 false냐보다 "우리는 이 동작을 의도적으로 선택했다"를 코드로 남기는 것이다.
1.12가 끊어내는 실험 경로: dbt login과 bundled dbt-state
이번 릴리스는 새 기능만 넣지 않았다. release note에 따르면 다음 실험 경로가 제거됐다.
dbt login- bundled
dbt-stateplugin --manage-state/manage_stateDBT_ENGINE_STATE_*환경변수
이 제거는 눈에 띄는 UI 변화보다 사내 wrapper script와 job template를 깨뜨리기 쉬운 변화다.
예를 들어 아래 항목이 있다면 1.12 전환 전에 먼저 정리해야 한다.
- bootstrap script 안에
dbt login호출이 남아 있는가 - CI secret template에
DBT_ENGINE_STATE_*가 남아 있는가 - 내부 문서가
manage_state전제를 깔고 있는가 - devcontainer / onboarding 문서가 더 이상 존재하지 않는 실험 경로를 안내하는가
이 경로를 이미 적극적으로 쓰고 있었다면 1.12는 단순 업그레이드가 아니라 작은 migration 작업이 된다.
같이 챙겨둘 만한 부가 변화
이번 글의 중심은 아니지만, 운영에서 기억해 둘 만한 항목도 있다.
dbt run-operation --sql: 매크로 없이 일회성 SQL 실행 가능. 긴급 grants 조정이나 짧은 data fix에 유용하다.on_error: continue: upstream 모델 실패 시에도 일부 downstream을 계속 실행할 수 있다. 단,--fail-fast가 우선한다.latest_version_pointer: versioned model의 최신 버전을 가리키는 pointer view를 자동 생성할 수 있다.MAXIMUM_SEED_SIZE_MIBconfigurable: seed 크기 제한을 환경에 맞게 조정할 수 있다.
이 항목들은 눈에 띄는 headline 기능은 아니어도, 운영 런북을 조금 더 짧게 만들 수 있다.
권장 업그레이드 순서
- 현행 플래그를 먼저 고정한다. 현재 프로젝트가 기대하는 behavior flag를
dbt_project.yml에 명시한다. - baseline artifact를 남긴다. 업그레이드 전
dbt parse,dbt build, selection 결과, warning 수를 저장한다. - v2 parser는 parse 전용 canary에서 먼저 켠다. 가장 먼저
dbt parse --use-v2-parser를 돌려 parser compatibility만 본다. - manifest diff를 확인한다. docs, lineage, CI selection이 artifact를 읽는다면
target/manifest.json차이를 반드시 본다. - private package는 한 저장소만 먼저 전환한다. SSH key, known_hosts, provider 값이 runner마다 일관되게 준비됐는지 확인한다.
- 실험 경로를 grep으로 제거한다.
dbt login,manage_state,DBT_ENGINE_STATE_문자열이 repo와 CI template에 남아 있지 않은지 찾는다. --warn-errorjob을 따로 본다.validate_macro_args, warning handling 계열 플래그 때문에 기존 warning이 hard failure가 될 수 있다.
운영자 검증 체크리스트
- [ ]
dbt_project.yml에 핵심 behavior flag가 명시돼 있는가 - [ ]
dbt parse --use-v2-parser가 canary 환경에서 통과하는가 - [ ] v2 parser 사용 시 partial parsing 제거가 개발자 경험에 미치는 영향이 허용 가능한가
- [ ]
target/manifest.jsondiff가 selection / docs / lineage에 의도치 않은 변화를 만들지 않는가 - [ ] private package를 쓰는 모든 runner에 SSH key와
known_hosts가 준비됐는가 - [ ]
dbt login,manage_state,DBT_ENGINE_STATE_*가 스크립트·문서·CI 템플릿에서 제거됐는가 - [ ]
--warn-error경로에서 macro argument warning이 새 실패를 만들지 않는가
정리
dbt Core 1.12의 핵심은 “새 semantic 기능이 더 많아졌다”가 아니다. 파서를 Rust/Fusion 쪽으로 시험할 수 있게 했고, private package 인증을 Git 표준 경로로 옮겼고, behavior flag를 더 이상 개인 로컬 설정이 아니라 프로젝트 계약으로 다루게 만들었다는 데 있다.
그래서 1.12 업그레이드는 패키지 하나 올리는 작업으로 끝내기보다, 다음 세 가지를 함께 정리하는 작업으로 보는 편이 좋다.
- parser 결과를 어디까지 신뢰할 것인가
- Git/SSH 자격증명을 어떤 runner 표준으로 굳힐 것인가
- build 의미를 바꾸는 flag를 어느 값으로 고정할 것인가
이 세 가지를 정리하고 나면 1.12는 단순한 minor release가 아니라, dbt 2.0과 Fusion 계열 런타임으로 넘어가기 전 운영 규율을 먼저 다듬는 릴리스가 된다.
References
- dbt Core v1.12.0 release notes (2026-07-16): https://github.com/dbt-labs/dbt-core/releases/tag/v1.12.0
- dbt Docs — Upgrading to v1.12: https://docs.getdbt.com/docs/dbt-versions/core-upgrade/upgrading-to-v1.12
- dbt Docs — Parsing / Opt-in v2 parser: https://docs.getdbt.com/reference/global-configs/parsing#opt-in-v2-parser
- dbt Docs — Native private packages: https://docs.getdbt.com/docs/build/packages#native-private-packages
- dbt Docs — Behavior change flags registry: https://docs.getdbt.com/reference/global-configs/behavior-changes
- dbt Core issue #12713, "flip default for behavior change flags for v1.12": https://github.com/dbt-labs/dbt-core/issues/12713