Delta Kernel의 설계, 릴리스 주기, 기여 문화가 안고 있는 과제와 2026년 개선 방향을 살펴봅니다.
Delta Kernel은 제가 작업해 본 오픈 소스 프로젝트 가운데 가장 기술적으로 어렵고 야심 찬 프로젝트 중 하나입니다. Kernel은 본질적으로 Delta Lake 구현체에 대해 우리가 가진 모든 필요와 요구를 하나의 일관되면서도 플러그인 방식으로 확장 가능한 API 표면으로 통합하는 일입니다. 2025년 말, TD는 delta-rs 같은 프로젝트에서 kernel의 채택을 좌절시키거나 늦추고 있는 문제들을 적어 달라고 제게 요청했습니다. 프로젝트 초기에 우리는 미지의 영역으로 나아가며 무엇이 실제로 가능할지 우려를 논의했습니다. 여러 면에서 우리는 성공했고, 다른 면에서는 실패했습니다.
역사를 되돌아보면, 저는 Zach에 이어 이 프로젝트에 코드를 커밋한 두 번째 개발자였습니다. 모든 오픈 소스 프로젝트와 마찬가지로 Delta Kernel은 무언가를 함께 이루기 위해 시간을 쏟아부은 수많은 사람의 작업입니다. 저는 delta-rs와 delta-kernel-rs를 더 낫게 만들기 위해 Robert, Zach, Nick, Ryan, Steve와 정기적으로 협업합니다.
우리 모두에게 개인적인 동기가 있지만, 경우에 따라 고용주가 제시하는 방향도 따릅니다. 이는 Databricks가 kernel에 바라는 목표가 제 고용주인 Scribd나 프로젝트의 다른 참여자들과 일치하지 않을 수 있음을 의미합니다. 이는 개인적, 직업적, 취미적 동기가 교차하는 많은 오픈 소스 프로젝트에서 절충안을 결정하는 일을 복잡하게 만듭니다.
제가 바라는 것은 kernel의 약점을 규정하여, 2026년에 kernel의 기술적 설계뿐 아니라 kernel을 둘러싼 _커뮤니티_와 문화까지 함께 개선할 수 있도록 하는 것입니다.
제 관점에서 kernel의 초기 설계 절충안은 대체로 두 가지 핵심 요인에 의해 이끌렸습니다.
무엇보다도 이 두 요인이 delta-kernel-rs 설계에서 제가 원래부터 구조를 떠받치는 죄악이라고 생각하는 여러 요소에 기여했습니다.
이러한 절충안은 Rust를 사용하는 중요한 장점 대부분을 포기하는 Rust 기반 프로젝트를 낳았습니다.
언어와 런타임을 넘나드는 상호 운용성을 지원하는 일은 끔찍하게 어렵습니다. 과거에 Ruby와 Python 프로젝트를 위해 언어 간 지원을 많이 했는데, 어느 시점에는 어딘가에서 한 세계의 포인터가 다른 세계로 전달됩니다. 객관적으로 끔찍합니다.
delta-rs가 이어져 오는 동안, 우리가 이를 위해 어떤 편의도 제공하지 않았음에도 사람들은 여기에 FFI 훅을 추가하려 해 왔습니다. 진심으로, 바로 이번 달에도 누군가 delta-rs 위에 또 다른 Golang FFI 바인딩 묶음을 들고 나타났습니다.
우리가 Delta kernel로 의도적으로 걸어 들어간 지옥입니다. 익숙하지 않은 분들을 위해 말하자면, FFI는 기본적으로 여러 언어가 C ABI 계층에서 만나 포인터를 주고받을 수 있도록 하는 규약입니다. 메모리 레이아웃과 다른 어처구니없는 요소가 조금 더 있지만, 본질적으로 모두가 C 스타일 인터페이스 수준으로 자신을 낮추는 방식입니다.
FFI는 어리석기도 하지만 Python, Ruby, JavaScript, Golang, Rust 등 모든 고수준 언어가 작동하는 방식이기도 합니다. 스택 아래 어딘가에서는 포인터가 여러분의 기기에서 C 기반 시스템 호출로 전달됩니다. 괴물이 도사리고 있습니다.
FFI 기반 엔진을 수용하기 위해 일찍이 벌어진 설계상의 의견 충돌 중 하나는 Future 기반 인터페이스 대신 Iterator 기반 인터페이스를 채택한 일이었습니다. 저는 이전에 이 설계 절충안에서 비롯된 병렬성 문제에 관해 쓴 바 있습니다.
논쟁은 Tokio 같은 이벤트 리액터를 kernel 내부에 숨겨 FFI 호출자로부터 감출 것인가, 아니면 호출자가 이벤트 기반으로 동작하게 만들 책임을 지도록 할 것인가였습니다. 여기서 DuckDB의 초기 영향력이 저울추를 기울였고, kernel 내부에 Tokio를 내장하지 않기로 결정했습니다.
Rust 생태계가 비동기 방식이 되기까지는 _오랜 시간_이 걸렸습니다. 지난 5년 동안 시스템 프로그래밍 생태계 전반에서 Rust가 폭발적으로 확산한 이유가 궁금했다면, 그 이유는 Rust 생태계가 비동기 방식이기 때문입니다.
제가 프로덕션에 배포한 첫 Rust 애플리케이션은 처음부터 async/await를 사용했고, 어떤 프로파일링도 없이 대체한 시스템보다 한 자릿수 배수만큼 빨랐습니다.
async/await는 애초에 delta-rs가 성공할 수 있었던 이유입니다!
Delta kernel의 Iterator 기반 API가 가진 한계를 우회하는 방법은 있지만, 오르막은 매우 가파르며, 일부 Delta kernel 구성 요소를 병렬 읽기 및 스캔이 가능했을 경우만큼 빠르게 만들려면 상당한 투자가 필요합니다.
async/await는 공짜로 놀라운 성능을 제공하지만, Delta kernel의 설계 선택은 이를 활용할 수 없게 만들며 그 대가를 치러야 합니다.
EngineData저는 EngineData의 영리함 때문에 Delta kernel의 일부를 작업할 만큼 똑똑하지 않습니다. arrow-rs의 RecordBatch 및 ArrayData 구현체와 비슷하게, EngineData는 _물건_과 _것들_을 담는 불투명한 타입 소거 컨테이너입니다.
제가 Rust를 배우기 어려워했지만 결국 이 언어를 사랑하게 된 이유 중 하나는, 문제의 전체 범주를 방지하는 데 도움이 되는 강력한 타입 시스템입니다. 강력한 타입 시스템은 제가 코드를 다룰 때 이를 추론하기도 훨씬 쉽게 해 줍니다.
Delta kernel의 모든 것은 어떤 형태로든 EngineData입니다. 이 인터페이스가 처음 다듬어질 당시 저는 다른 일에 꽤 매여 있었기에 그 결정의 역사를 잘 알지 못합니다. 하지만 EngineData와 그에 대응하는 RowVisitor, GetData, TypedGetData의 API는 작업하기에 매우 불쾌하다고 생각합니다.
저는 RecordBatch 역시 작업하기 불쾌하다고 생각합니다. Rust 데이터 생태계에서 이보다 더 사용자에게 불친절한 API를 떠올리기 어렵습니다. arrow의 RecordBatch의 경우, 제 동료들 중 일부가 Apache Arrow 코드에 만연한 배열 오프셋과 인덱스의 어처구니없음을 겪지 않고 RecordBatch를 다루기 위해 전체 datafusion 의존성을 끌어오는 모습을 봤습니다.
제가 RecordBatch를 불쾌하게 여기는 것과 별개로, 그 API와 지원 인프라에는 수천 명의 개발자가 투자하고 있습니다. EngineData에는 비슷한 수준의 도구가 없지만, 똑같이 날카로운 모서리 일부를 공유합니다.
EngineData 설계는 Delta kernel 코드베이스 전체에 많은 취약한 고정 배열 오프셋이 흩어지는 결과를 낳았습니다. 이 “게터”와 방문자 API는 Delta kernel에서 Rust 타입 검사기가 더 관습적으로 구조화된 Rust 프로젝트보다 훨씬 덜 유용하게 만듭니다. 또한 컴파일 시점 검사 대신 런타임 오류가 발생할 가능성도 훨씬 커집니다.
EngineData의 타입 소거된 불투명한 바이트 양동이 설계는 Delta kernel 내부에서 또는 함께 작업할 때 Rust 언어의 가장 중요한 특성 중 하나인 타입 검사기를 희생하게 만듭니다.
솔직히 말해 제가 발을 찧지 않기 때문에 언급할 수 없는 좋은 설계 요소도 있습니다. Ryan과 저는 더 높은 성능을 달성하기 위해 kernel에서 가능한 한 오랫동안 작업을 미루는 일의 중요성을 길게 논의했습니다. 일부 Expression 및 Transform API는 작업을 미루거나 아예 피할 수 있을 때 더 낮은 메모리 사용량과 더 빠른 로그 재생을 가능하게 합니다.
Delta kernel을 채택한 이후 delta-rs에서 확인한 성능 결함 일부는 kernel 설계 결정이라기보다 상호 운용 코드와 더 관련이 있습니다. delta-rs 프로젝트는 거대합니다. 범용 Delta Lake 구현체로서, Robert가 오늘날의 위치에 이르기까지 손대야 했던 변경 범위는 그야말로 영웅적이었습니다.
Delta kernel 프로젝트는 Databricks와 함께 작업한 프로젝트 중 주간 운영에 관해 어느 정도 투명성이 있는 첫 번째 프로젝트입니다. kernel Rust 커뮤니티는 개발자들이 개발자들과 대화하는 주간 회의를 엽니다. Denny와 나눈 초기 대화 상당수는 Databricks가 기정사실로서 Delta 프로젝트에 코드를 밀어 넣는 경향에 관한 것이었습니다. 특히 심각했던 한 상황에서는 Databricks 직원들이 검토, 승인, 병합한 프로토콜 및 Delta/Spark 변경 사항이 Data and AI Summit에서 발표되기 일주일 전에 이미 존재했습니다. Kernel은 이 부분을 제대로 해내고 있습니다.
kernel 커뮤니티의 모든 주간 통화에 참석할 수는 없지만, 참석할 수 있을 때면 정말 좋습니다.
kernel 주간 통화에 항상 참석하는 것은 아니지만, 참석하면 다음 릴리스가 언제인지 묻습니다.
아무도 제대로 이해하지 못하는 이유로 Delta kernel은 매우 느리게 움직입니다. delta-rs가 프로토콜 구현을 위해 Delta kernel에 의존하기 시작했으며, 따라서 우리의 새 버그 중 많은 부분이 어떤 식으로든 Delta kernel과 관련되기 때문에 패치 릴리스는 제게 특히 중요합니다.
2025년 릴리스는 평균적으로 약 3주에 하나였습니다. crates.io에 게시된 30개 버전 중 9개가 패치 수정이었으므로, 게시된 릴리스의 **70%**에는 API 호환성을 깨는 변경 사항이 포함되어 있었습니다. 개발자들이 서로 다른 API의 적절한 형태를 찾아가는 과정에서는 일부가 불가피합니다. 그러나 이 릴리스 주기의 하위 소비자인 제게 이는 끊임없이 바뀌는 API에 맞추기 위한 개발 노력 없이는 버그 수정을 받을 가능성이 매우 낮다는 뜻입니다.
공짜 점심은 없습니다.
delta-rs 프로젝트에서 이는 우리의 릴리스가 자주 막히는 대상이 다음과 같다는 뜻입니다.
Delta kernel은 Apache Arrow의 메이저 버전에 의존하는 기본 엔진과 함께 제공되며, Apache Arrow 역시 패치 릴리스를 피하는 프로젝트입니다. 이러한 복합 효과는 새 arrow가 릴리스될 때 우리(delta-rs)가 그것이 datafusion과 delta_kernel 모두에 통합되고, 두 크레이트가 모두 릴리스될 때까지 기다려야 함을 의미합니다.
Arrow 또는 Delta kernel 변경이 필요한 delta-rs에 보고된 모든 문제는 일반적으로 해결에 1-2개월이 걸립니다.
어제까지 최신 deltalake 크레이트 릴리스는 Delta kernel 0.16.0에 의존하는 0.29.4였습니다. 이 버전은 3개월 전 것이며, 안타깝게도 패치 릴리스를 한 번도 받지 못했습니다. 이는 delta-rs의 0.29.x 릴리스 네 개 모두가 이 버전에 의존한 이유 중 하나입니다.
크레이트 다운로드 통계를 매우 비과학적인 척도로 사용한다면, delta-rs가 Delta kernel 다운로드 대부분을 이끈다고 추측하겠습니다.

0.18.0 릴리스는 11월 20일에 나왔고 소폭 상승이 있었지만, 12월 초의 큰 급증은 이 풀 리퀘스트가 0.18.x를 delta-rs 저장소에 가져온 시점과 강하게 연관됩니다.
완전성을 위해 덧붙이면, deltalake 크레이트의 다운로드도 매우 비슷한 형태입니다. 하지만 0.29.x의 릴리스 주기가 더 길기 때문에 어떤 버전이 많이 다운로드되는지 판단하기는 어렵습니다.

안정적인 API를 유지하는 일은 고통스럽지만, 의존성이 스택의 아래쪽에 있을수록 훨씬 더 중요해집니다.
한 가지 접근법은 필요에 따라 변경 사항을 체리픽하는 릴리스 브랜치를 만드는 것입니다. 이는 릴리스 엔지니어링 작업을 더 늘리며 어려울 수 있습니다. 제 목적을 위해 저는 이렇게 해 왔고, 2~3주마다 불안정한 릴리스로 바다를 끓일 수 없는 고객을 지원하기 위해 여러 형태로 Delta kernel과 delta-rs 양쪽의 수정을 백포트했습니다.
Scribd에서 API 변경이 전혀 없는 delta-rs 패치 릴리스에도 최소한 다음이 필요합니다.
모든 일이 순조롭게 돌아갈 때 이는 처음부터 끝까지 개발자 시간 약 두 시간이지만, 이는 API 변경이 전혀 없을 때의 이야기입니다.
Delta-rs, Delta kernel 또는 Apache Arrow에서 발생하는 모든 API 변경 묶음은 업데이트와 업그레이드를 수행하는 데 필요한 알 수 없는 개발자 시간을 추가합니다. 이러한 의존성 중 어느 것이라도 새 릴리스가 상당한 성능 또는 품질 개선을 제공하지 않는 한, 비즈니스는 이 업그레이드를 불필요한 비용으로 간주하고 대신 단순히 업데이트하지 않는 쪽을 선호합니다.
그 결과, 특정 Delta kernel 릴리스가 나온 지 몇 달 뒤에야 프로덕션에서 버그가 발견될 수 있습니다. 예를 들어 Delta kernel의 이 성능 버그는 실제로 릴리스된 크레이트에 수개월 동안 존재했습니다. delta-rs가 Delta kernel을 더 많이 채택한 뒤에야 저는 업그레이드를 프로덕션까지 가져갈 수 있었고, delta-rs와 Delta kernel에서 몇 가지 심각한 성능 문제를 발견했습니다.
이 타임라인은 저에게도 조금 혼란스러워지고 있으니, 정리해 봅시다.
0.4.0으로 릴리스되었습니다.0.13.0을 처음으로 본격 채택하여 릴리스되었습니다.0.16.0에 통합된 추가 개선 사항을 갖춘 delta-rs 0.29.x가 릴리스될 때까지 빠르게 되돌렸습니다.제 관점에서 성능 문제에만 투자한 시간은 Delta kernel이 제공한 개선으로 아직 “회수되지” 않았습니다.
참고: 인사 부서에서는 성장 사고방식을 받아들이라고 저에게 상기시키고 싶어 합니다.
Delta kernel 통합의 개선 사항은 투자한 시간을 아직 회수하지 못했습니다.
1년이 넘는 기간 동안 성능 문제가 main과 릴리스된 kernel 크레이트에 남아 있었습니다.
kernel에서 변경이 이루어진 시점과 그 변경이 실제 워크로드에 사용되는 시점 사이의 시간 지연은 깁니다. 개발을 위한 건설적인 피드백 주기로 유용하기에는 너무 깁니다.
이를 개선할 유일한 방법은 더 빠른 릴리스와 더 빠른 피드백이라고 믿습니다.
릴리스된 변경 사항에서 사용자 피드백 루프가 매우 긴 문제는 Delta kernel을 괴롭히는 속도 문제의 절반에 불과합니다. 저는 야크 털 깎기가 꽤 심할 수 있어서 개인적으로 너무 많이 기여하지 않았습니다.
제가 최근 제안한 성능 개선은 개인 최고 점수를 새로 기록했습니다! 네 명의 서로 다른 메인테이너와 주고받으며 _84개의 댓글_을 받았습니다. 이는 패치에서 바뀐 줄 수보다 많은 풀 리퀘스트 댓글입니다.
메인테이너로서 때때로 기억하기 어려운 점은 풀 리퀘스트가 기여자의 투자 시간이 시작되는 지점을 나타내지 않는다는 것입니다. 풀 리퀘스트는 대개 그들의 시간 투자가 끝나는 지점입니다. 이 경우 저는 변경을 만들기 전에 이미 문제를 프로파일링하고 이해하는 데 5-8시간을 투자했습니다.
야크 털 깎기 속에는 유용한 피드백이 있었습니다. 그러나 과정이 너무 좌절스러워서 총 약 12시간을 투자한 뒤 결국 포기하고 Nick에게 넘겨달라고 요청했습니다.
현재 열려 있는 풀 리퀘스트 중 댓글이 가장 많은 것은 99개입니다. 닫힌 풀 리퀘스트에서 제 화가 나는 84개 댓글의 여정은 “댓글 최다” 풀 리퀘스트 첫 페이지에도 들지 못합니다. 최상위는 이 풀 리퀘스트가 차지하고 있으며, 369개 댓글이 달렸고 열림부터 병합까지 두 달 이상 걸렸습니다. 이 괴물은 Delta kernel의 역사 초기에 상당한 변경을 나타내므로 다소 예외 사례이지만, 다른 여러 변경도 수백 개 댓글 범위에 속합니다.
Delta kernel의 풀 리퀘스트 문화는 근본적으로 기여자에게 적대적입니다.
이를 개선하는 방법으로 Nick에게 제안한 내용은 다음과 같습니다.
CODEOWNERS). 메인테이너가 아닌 이의 풀 리퀘스트에 여러 사람이 서로 다른 의견을 제시하는 것은 상대적으로 이점이 적습니다.떠오르는 다른 생각은 다음과 같습니다.
많은 개발자는 main의 코드에 무슨 마법이 일어나기라도 하듯 코드가 “안정화된다”고 믿습니다. 모든 코드에는 빠르게 감소하는 반감기가 있으며, 특히 열린 풀 리퀘스트에 머무는 코드가 그렇습니다. 무엇이 좋거나 나쁜지를 입증하는 유일한 방법은 그것이 사용되는 것입니다. 안정성은 _사용_에서 나옵니다.
저 자신을 포함해 Delta kernel 프로젝트에 참여하는 모두는 Delta 기반 애플리케이션을 구축할 안정적이고 고성능인 기반을 원한다고 생각합니다. Jez Humble과 David Farley가 Continuous Delivery에 관한 책에서 썼듯, 긴 사이클 타임은 대개 안정성과 신뢰성에 _정반대_입니다.
맙소사, 정말 많은 말을 했습니다. 현명한 사람의 말을 인용하자면:
Delta Kernel은 가장 기술적으로 어렵고 야심 찬 오픈 소스 프로젝트 중 하나입니다
저는 Delta kernel의 비전을 믿으며, 그렇지 않았다면 분명 여기 있지 않았을 것입니다. 생태계에서 제가 보는 파편화는 문제만 일으킵니다. 이 글을 쓰기 시작한 뒤, 저는 Delta kernel이 지원하도록 만들어진 일을 하도록 delta-rs 코드를 억지로 만들려는 새롭고 기묘한 파생물 _두 개_를 만났습니다. 실제로 Delta kernel의 현 상태는 제가 우연히 발견한 두 사용 사례를 지원합니다!
안정적이고 고성능인 기반을 갖는다는 것은 kernel에 추가되는 기능과 개선이 모두에게 이득이 된다는 뜻입니다! 얼마나 멋진 일입니까? 핵심은 모두가 kernel을 사용하게 하는 것입니다!
Kernel의 성공은 Delta Lake 생태계와 그 밖의 수많은 곳에 중요합니다. 하지만 kernel이 성공하려면, FFI보다 async/await를 중심에 두고 Rust 구현체를 지원하는 데 초점을 맞춰 인터페이스에서 Rust 생태계의 강점을 더 많이 활용하는, 더 관용적인 Rust 코드를 도입함으로써 2026년에 방향을 조정해야 한다고 믿습니다.
Rust 개발자에게 더 익숙한 방식으로 구축하면 새로운 관점과 함께 더 많은 새 기여자를 맞이할 수 있습니다. 릴리스 주기와 변경 관리를 명확하고 예측 가능한 형태로 개선해야 합니다. 새 개발자가 환영받고 자신의 기여가 가치 있다고 느끼게 하는 일은 생태계의 기반으로서 kernel의 위치를 굳힐 것입니다.
2026년에 더 강한 기술 그리고 더 강한 커뮤니티를 갖추면 Delta kernel은 오늘 우리가 마주한 과제를 극복하는 데 도움이 될 것입니다.