# Git을 데이터베이스로 사용하는 패키지 관리자들, 결국 실패한다

> Clean Markdown view of GeekNews topic #25365. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=25365](https://news.hada.io/topic?id=25365)
- GeekNews Markdown: [https://news.hada.io/topic/25365.md](https://news.hada.io/topic/25365.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-12-27T09:42:06+09:00
- Updated: 2025-12-27T09:42:06+09:00
- Original source: [nesbitt.io](https://nesbitt.io/2025/12/24/package-managers-keep-using-git-as-a-database.html)
- Points: 7
- Comments: 2

## Summary

여러 패키지 관리자가 **Git을 데이터베이스처럼 사용**하며 버전 관리의 편리함을 얻고자 했지만, 시간이 지나며 인덱스 비대화와 성능 저하 문제에 부딪혔습니다. Cargo·Homebrew·CocoaPods는 결국 **HTTP 기반 인덱스나 CDN 구조**로 전환해 속도와 유지보수를 개선했고, Go 모듈 시스템은 GOPROXY와 체크섬 데이터베이스로 Git 의존성을 완전히 제거했습니다. Git은 협업에는 탁월하지만, 대규모 패키지 메타데이터 관리에는 구조적으로 부적합하다는 사실이 반복적으로 확인되고 있습니다.

## Topic Body

- 여러 **패키지 관리자**들이 버전 관리와 협업의 편리함 때문에 **Git을 데이터베이스처럼 사용**했지만, 규모가 커질수록 성능과 유지보수 문제에 부딪힘  
- **Cargo**, **Homebrew**, **CocoaPods** 등은 Git 인덱스의 크기 증가와 느린 업데이트 속도, CI 환경의 비효율로 인해 결국 **HTTP 기반 인덱스나 CDN**으로 전환  
- **vcpkg**는 여전히 Git 트리 해시를 기반으로 동작하며, 얕은 클론(shallow clone) 환경에서 **빌드 실패와 복잡한 우회 방법**이 발생  
- **Go 모듈 시스템**은 GOPROXY와 **체크섬 데이터베이스(sumdb)** 를 도입해 Git 의존성을 제거하고 보안성과 속도를 개선  
- Git은 코드 협업에는 탁월하지만, **패키지 메타데이터 질의나 대규모 레지스트리 관리에는 부적합**하다는 점이 반복적으로 드러남  

---

### Git을 데이터베이스로 사용하는 시도의 반복적 실패
- Git은 **버전 이력, 분산 구조, 무료 호스팅** 등의 장점으로 매력적이지만, 데이터베이스로 사용하면 확장성 한계에 부딪힘  
- 여러 패키지 관리자가 Git을 인덱스로 채택했으나, 시간이 지나며 **성능 저하와 인프라 부담**이 심화됨  

### Cargo
- **crates.io 인덱스**는 Git 저장소로 시작했으며, 모든 클라이언트가 전체 복제(clone)를 수행  
  - 저장소가 커지면서 delta resolution 단계에서 **libgit2의 성능 병목**이 발생  
  - CI 환경에서는 매 빌드마다 전체 인덱스를 다운로드해 낭비 심각  
- **RFC 2789**를 통해 **sparse HTTP 프로토콜**이 도입되어 필요한 메타데이터만 HTTPS로 가져오도록 개선  
  - 2025년 4월 기준, 요청의 99%가 sparse 모드 사용  
  - Git 인덱스는 여전히 존재하지만 대부분의 사용자는 접근하지 않음  

### Homebrew
- GitHub은 Homebrew에 **얕은 클론 사용 중단**을 요청, 업데이트가 “매우 비싼 연산”으로 지적됨  
  - homebrew-core의 `.git` 폴더는 1GB에 육박, 업데이트 시 delta resolution으로 지연 발생  
- 2023년 2월 **Homebrew 4.0.0**에서 tap 업데이트를 **JSON 다운로드 방식**으로 전환  
  - Git fetch 제거로 업데이트 속도 향상, 자동 업데이트 주기도 5분에서 24시간으로 변경  

### CocoaPods
- iOS/macOS용 패키지 관리자 **CocoaPods**는 수십만 개의 podspec으로 구성된 **Specs 저장소**가 지나치게 커짐  
  - 클론 및 업데이트에 수분 소요, CI 시간 대부분이 Git 연산에 소비  
- GitHub은 **CPU rate limit**을 적용, shallow clone이 서버 부하의 원인으로 지목  
- 팀은 **자동 fetch 중단, 풀 클론 전환, 저장소 샤딩** 등 임시 조치 시행  
- **1.8 버전부터 CDN 기반 HTTP 배포**로 전환, 사용자 디스크 공간 약 1GB 절약, 설치 속도 대폭 향상  

### Nixpkgs
- Nix는 클라이언트 측에서 이미 **tarball 기반 채널**을 사용해 Git 복제를 피함  
  - 패키지 표현식은 S3와 CDN에서 HTTP로 제공  
- 그러나 GitHub의 인프라가 **83GB 규모의 저장소와 20,000개 포크**로 인해 부담  
  - 2025년 11월, GitHub은 **복제 간 합의 실패 및 유지보수 작업 오류**를 보고  
  - 로컬 클론은 2.5GB지만, 포크 네트워크 전체가 GitHub 저장 공간을 압박  

### vcpkg
- Microsoft의 C++ 패키지 관리자 **vcpkg**는 **Git 트리 해시**로 버전 관리  
  - `builtin-baseline`을 통해 특정 커밋 시점의 포트를 재현하려면 전체 히스토리가 필요  
- **얕은 클론 환경(GitHub Actions, DevContainers)** 에서는 빌드 실패 발생  
  - 해결책으로 `fetch-depth: 0` 설정 필요, 전체 히스토리 다운로드 요구  
- Git 트리 해시 구조상 **커밋 추적 불가**, 구조적 한계로 인한 수정 불가능  
- 여전히 Git 저장소 기반 레지스트리만 지원, **HTTP나 CDN 대안 없음**  

### Go 모듈 시스템
- Grab 엔지니어링 팀은 **모듈 프록시 도입 후 `go get` 시간이 18분 → 12초**로 단축  
- 기존 방식은 각 의존성의 저장소 전체를 클론해야 `go.mod`를 읽을 수 있었음  
- Go 팀은 **VCS 도구 의존성과 보안 취약점**을 우려  
- **Go 1.13**부터 **GOPROXY**가 기본, 모듈 소스와 `go.mod`를 HTTP로 제공  
  - **sumdb(체크섬 데이터베이스)** 로 모듈 무결성과 영속성 보장  

### Git을 데이터베이스로 사용할 때의 일반적 문제
- **Git 기반 위키(Gollum)** 는 대규모 저장소에서 디렉터리 탐색과 페이지 로딩이 느려짐  
  - GitLab은 Gollum 사용 중단 계획  
- **Git 기반 CMS(Decap)** 는 GitHub API 요청 한도(5,000회)에 걸림  
  - 약 10,000개 항목 이상에서 성능 저하, 빈 캐시 상태의 신규 사용자는 요청 폭주  
- **GitOps 도구(ArgoCD)** 는 저장소 클론 시 디스크 공간 초과 문제 발생  
  - 단일 커밋이 전체 캐시를 무효화, 대형 모노레포는 별도 스케일링 필요  

### Git이 데이터베이스로 부적합한 구조적 이유
- **디렉터리 한계**: 파일 수가 많아질수록 느려짐  
  - CocoaPods는 16,000개 디렉터리로 인해 거대한 트리 객체 생성, 해시 기반 샤딩으로 해결  
- **대소문자 구분 문제**: Git은 구분하지만 macOS·Windows는 비구분  
  - Azure DevOps는 충돌 방지를 위해 서버 측 차단 기능 추가  
- **경로 길이 제한**: Windows의 260자 제한으로 `git status` 오류 발생  
- **데이터베이스 기능 부재**:  
  - CHECK/UNIQUE 제약, 잠금, 인덱스, 마이그레이션 기능 모두 없음  
  - 각 패키지 관리자가 자체 검증·색인 시스템을 구축해야 함  

### 결론
- Git은 **소스 코드 협업**에는 탁월하지만, **패키지 메타데이터 질의나 대규모 레지스트리 관리**에는 부적합  
- 대부분의 패키지 관리자는 결국 **HTTP 기반 인덱스나 데이터베이스**로 전환  
- Git의 장점(버전 이력, PR 워크플로)은 매력적이지만, **데이터베이스 대체로는 실패**  
- 새로운 패키지 관리자를 설계할 때 Git 인덱스가 매력적으로 보이더라도, **Cargo·Homebrew·CocoaPods·vcpkg·Go의 사례처럼 동일한 한계에 도달함**

## Comments



### Comment 48343

- Author: lamanus
- Created: 2025-12-28T10:37:58+09:00
- Points: 2

기여자들의 기여를 받기위해 시스템을 별도로 만들기보단 git이 간편하니까 쓰는거죠. 한계라고 하는데 별로 공감은 안되고, 현실적인 문제에 대한 대안은 전혀 안보이네요.

### Comment 48311

- Author: neo
- Created: 2025-12-27T09:42:06+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=46391514) 
- 이건 일종의 **공유지의 비극**처럼 보임. GitHub은 무료이고 훌륭한 기능이 많으니 다들 쓰려 함. 하지만 이런 의사결정은 **외부효과**가 있을 때 항상 발생함  
  내가 가장 중요하게 생각하는 외부효과는 **사용자 시간**임. 대부분의 소프트웨어 회사는 엔지니어링 시간의 비용만 신경 쓰고, 사용자 시간을 무시함. 기능 개발에는 열중하지만 사용자 상호작용 시간은 최적화하지 않음. 예를 들어, 내가 앱을 1초 빠르게 만드는 데 1시간을 쓴다면, 백만 명의 사용자가 매년 277시간을 절약함. 하지만 사용자 시간은 외부효과라서 이런 최적화는 거의 이루어지지 않음  
  결국 사용자는 쓸데없이 데이터를 더 다운로드하고 기다리게 되며, 개발자는 그 낭비에 책임을 지지 않음
  - “소프트웨어 하우스”라는 표현이 정확히 뭘 의미하는지 모르겠지만, 내가 일한 대부분의 **소비자용 소프트웨어 제품**은 시작 속도나 지연 시간 같은 지표를 핵심적으로 추적했음. 이런 건 수십 년 전부터 상식이었음. 예를 들어, **Amazon**이 페이지 로딩 몇 밀리초 차이로 수백만 달러를 잃는다는 얘기도 자주 들었음
  - 이건 “속도도 하나의 **기능(feature)** ”이라는 말과 같은 맥락임. 다만 사용자 시간은 단순한 성능뿐 아니라 **UI 설계**에도 크게 좌우됨
  - “공유지의 비극”은 아니라고 생각함. GitHub은 **Microsoft의 소유**이므로, 그들이 감당할 수 있다고 판단한 것임. 진짜 공유지는 아무도 소유하지 않고 모두가 혜택을 보는 구조여야 함
  - 이 문제를 깊이 생각하다 보면 Alan Kay의 말이 떠오름 — “진짜로 소프트웨어를 중요하게 여긴다면 **하드웨어도 직접 만들어야 한다**”. 네트워크를 통한 로딩은 본질적으로 나쁜 사용자 경험임. 진정으로 사용자를 존중하려면 **로컬 우선(native-first)** 애플리케이션을 만들어야 함. 하지만 이렇게까지 사용자 경험을 존중하는 회사는 극히 드묾
  - Andy Hertzfeld의 글 [“Saving Lives”](https://www.folklore.org/Saving_Lives.html)을 보면 흥미로움 — “Macintosh 부팅이 너무 느리다. 더 빠르게 만들어야 한다!”는 일화가 있음

- 나는 C용 **Cargo/UV**를 만들고 있음. 좋은 글이라 깊이 공감함.  
  처음 시작할 때 **레지스트리 운영**은 정말 어려운 일임. 코드 작성과 도구 품질 확보, 커뮤니티 확산뿐 아니라 전 세계 트래픽을 감당할 인프라까지 고민해야 함. 이런 상황에서 git 기반 솔루션은 매력적임  
  하지만 문제는 **sparse checkout**임. git으로 패키지 매니페스트를 버전 관리하고 싶지만, 임의의 커밋을 추적해야 해서 비효율적임. 결국 두 번의 커밋을 푸시해야 하는 구조라 현실적으로 불가능함  
  **Conan**의 접근이 가장 실용적이라 생각함. 완벽한 재현성 대신 조건부 로직을 매니페스트에 넣는 방식임. 버전 범위별 매니페스트 매핑도 가능함. 완벽하진 않지만 **실용적이고 유용한 절충안**임.  
  물론 진짜 해결책은 데이터베이스를 쓰는 것이지만, 누가 서버비와 유지비를 대신 내줄 것도 아니니 현실적으로 어렵음
  - 관점을 바꿔보면, 성공한 패키지 매니저 대부분이 처음엔 **Git 기반**으로 시작했다가 필요할 때 더 효율적인 구조로 옮겨갔음
  - **Arch Linux AUR** 방식도 고려할 만함. 각 패키지가 독립된 git 저장소를 갖고, 매니페스트만 포함함. 이렇게 하면 **monorepo 문제**나 참조 악몽을 피할 수 있음
  - S3 같은 단순한 **HTTP 백엔드**로 저장소를 운영하는 것도 매력적임. 초기에 단일 서버로 시작하고, 인기가 생기면 스폰서를 찾아 클라우드로 옮기면 됨.  
    돈과 독립성이 문제라면 **P2P 방식**도 가능함. 다만 CI 캐싱이 안 되면 트래픽이 폭증할 수 있음
  - 아직 사용자가 많지 않다면 전 세계를 대상으로 한 인프라를 미리 준비하는 건 **시기상조**임
  - 굳이 모든 **히스토리 데이터**를 사용자에게 보여줄 필요는 없음. post-commit hook으로 HEAD 상태만 정적 파일로 렌더링해 **GitHub Pages**처럼 제공하면 됨.  
    Debian, Fedora, openSUSE 같은 리눅스 배포판의 **미러 구조**도 참고할 만함

- 이 글은 두 가지 문제를 혼동하고 있음. 하나는 **git을 패키지 인덱스 데이터베이스로 쓰는 것**, 다른 하나는 **각 패키지 코드를 git으로 가져오는 것**임. 둘은 별개임.  
  인덱스는 git으로, 패키지는 zip/tar로 할 수도 있고, 반대도 가능함. Go의 경우는 아예 인덱스가 없는 구조임
  - 글쓴이가 약간 혼란스러워 보임. “모든 사용자가 데이터베이스를 복제하지 말라”는 주장에는 동의하지만, 그렇다고 git 그래프를 데이터 인코딩에 못 쓸 이유는 없음.  
    GitHub의 백엔드 구현이나 2만 개 포크 같은 얘기는 본질과 무관함. git 워킹트리 없이도 효율적인 **key-value 조회**가 가능함.  
    “git 히스토리 리라이트가 DB 마이그레이션과 같다”는 주장도 이상함. 차라리 **Postgres 하나 돌리는 게 낫지 않겠음?** 
  - 글의 요지는 코드 자체가 아니라 **go.mod 파일**을 가져오는 과정에 있음. 그래서 해결책으로 go.mod를 별도로 호스팅한 것임
  - git에서도 필요한 **단일 파일만 가져오기**는 가능하지만, 여전히 구조적으로 어색함

- “작동할 때는 쉬운 방법을 쓰고, 안 되면 고치자”는 접근은 현실적임.  
  **Julia**도 같은 방식을 쓰고 있고, Rust보다 패키지가 1/7 수준이라 아직 문제 없음.  
  최상위 [Registry.toml](https://github.com/JuliaRegistries/General/blob/master/Registry.toml) 파일만 받아 필요한 패키지만 다운로드하도록 개선할 수 있음. 큰 문제는 아님
  - Julia는 git 레지스트리를 **공식 원장(ledger)** 으로만 쓰고, 실제 클라이언트는 [Pkg Protocol](https://pkgdocs.julialang.org/dev/protocol/)을 사용함
  - 이 접근을 “**FAFO(해보고 망해보자)** ” 정신이라 부를 수도 있음. 실용적이긴 하지만 개인적으로는 선호하지 않음
  - 이런 태도는 **비윤리적**이라 생각함. “일단 쉽게 만들고 나중에 고치자”는 사고방식은 결국 기술 부채를 키움.  
    “Move fast and break things” 문화가 낳은 결과가 지금의 느리고 버그 많은 소프트웨어임
  - 문제를 나중에 고치면 **비용이 기하급수적으로 증가**함. 결국 “조금 고장난 채로 그냥 쓰자”는 결론이 됨. 글에서도 vcpkg 사례가 그 예임
  - 누군가 **UUID를 의도적으로 조작**한 것처럼 보이는 예시가 있는데, 그게 가능한 게 좀 걱정스러움

- “Git은 패키지 매니저의 시작점으로 훌륭한 데이터베이스”라는 결론에 동의함
  - 다만 클라이언트는 전체 저장소를 받지 않고 **캐시나 DB 계층**을 두는 게 좋음. CI/CD 환경에서는 특히 효율성이 중요함
  - **Nixpkgs**도 Git 덕분에 성공했음. 스케일 문제는 나중의 사치스러운 고민임
  - 하지만 Git을 찬양하기 전에 **데이터베이스 연구**를 조금이라도 찾아보는 게 좋음
  - Git은 공급망 악몽을 초래할 수도 있음. **Leftpad 사태**가 매주 반복될 수도 있음
  - Git은 패키지 매니저용 DB로는 **형편없음**. 다만 GitHub이 무료로 호스팅해주니 다들 쓰는 것뿐임

- “결국 잘 됐잖아”라는 입장임. 초기 운영에는 충분히 도움이 됐고, 스케일 문제는 나중에 해결 가능했음
  - 하지만 일부 프로젝트는 **아키텍처적 한계** 때문에 git에서 벗어나지 못하고 있음
  - git처럼 **파일 시스템 기반 스토어**로 시작하면 나중에 프로토콜 전환이 거의 불가능함. 처음부터 **API 중심 설계**로 가야 함
  - 오히려 git을 더 효율적으로 활용할 기회가 있음. 대안을 제시하지 않고 git을 버리자는 건 **반쪽짜리 결론**임
  - “0에서 1조 사용자까지 스케일 안 됐다고 쓰레기라니”라는 반어적 농담도 있음

- 여기엔 **생존자 편향(survivorship bias)** 이 있음. Cargo가 성공했기에 git 인덱스가 커져 문제가 된 것임.  
  대부분의 작은 프로젝트는 git을 데이터 배포 프로토콜로 잘 쓰고 있음.  
  스케일이 불확실한 초기에는 git과 GitHub을 활용해 **핵심 문제에 집중**하는 게 합리적임
  - 너무 이른 **최적화**를 경계해야 함. Cargo나 Homebrew도 쉬운 길을 택해 성장했고, 스케일 문제는 나중의 “좋은 문제”였음

- HN 첫 페이지에서 “지금 네가 하는 게 잘못됐다”는 글을 보면 늘 겸손해짐.  
  나도 몇 번 그런 경험이 있음. 이번엔 **PG Notify** 관련 글이 그랬음.  
  하지만 지금은 혼자 개발 중이고, 프로젝트가 성공할지조차 모르니 **git으로 플러그인 배포**하는 게 가장 현실적임.  
  그래도 나중에 스케일 문제가 생기면 이 글을 참고할 예정임
  - 지금도 몇 가지 **함정은 피할 수 있음**. GitHub 의존성 같은 **벤더 락인**이 더 큰 문제일 수도 있음

- 나는 개인적으로 **Forgejo**로 코드를 호스팅함. 외부 노출 없이 **mTLS**로 보호함.  
  하지만 Go 모듈은 인증서를 요구해서 내 Forgejo 인스턴스를 인식하지 못함.  
  SSH를 써도 HTTPS 접근이 필요하다고 해서 결국 **replace directive**로 로컬 복제본을 사용함. 꽤 번거로움
  - 모듈 경로 끝에 `.git`을 붙이고 `$GOPRIVATE`를 설정하면 HTTPS 요청 없이 **git 명령어 인증**을 쓸 수 있음. [공식 문서](https://go.dev/ref/mod#vcs-find) 참고
  - 인스턴스의 **TLS 인증서(CA)** 를 신뢰 저장소에 추가하면 HTTPS 다운로드도 가능함
  - “HTTP 접근이 필요하다”는 건 사실이 아님. **로컬 프록시**로 해결 가능함
  - **Tailscale DNS와 인증서**를 쓰면 외부 노출 없이 Let’s Encrypt 인증서를 받을 수 있음

- 패키지 매니저뿐 아니라 많은 작은 프로젝트가 데이터를 **git 저장소에 크라우드소싱**함.  
  대부분은 규모가 작아 기술적 한계에 부딪히지 않음.  
  다만 이런 구조는 **비개발자 참여 장벽**을 높임. 패키지 매니저는 예외지만 일반 프로젝트엔 문제임  
  나는 이런 문제를 돕기 위해 [Datatig](https://www.datatig.com/)이라는 오픈소스 라이브러리를 만들었음.  
  관련 발표 자료는 [여기](https://www.datatig.com/2024/12/24/talk.html)에 있음. 앞으로 이 글을 참고해 **스케일링 관련 내용**도 추가할 예정임
