Cloudflare D1은 2022년 알파, 2024년 4월 정식 출시된 서버리스 SQL 데이터베이스입니다. SQLite 엔진을 기반으로 Cloudflare 엣지 네트워크에 통합되어, Workers·Pages·Astro 같은 Cloudflare 환경과 한 줄 binding으로 연결됩니다. 사용 시간이 아니라 읽은 행·쓴 행·저장 용량만 과금하는 구조라 사용량이 적을 때는 사실상 무료이고, 무료 등급도 영구 제공됩니다.
그런데 D1을 처음 접한 개발자가 반드시 마주치는 질문이 두 가지 있습니다. 첫째, 데이터베이스 하나당 왜 10GB 한도가 있는가. 둘째, 한도를 넘으면 어떻게 확장해야 하는가. 이 질문에 대한 답을 모르면 D1을 본격적으로 도입했다가 1~2년 뒤 한도에 부딪쳐 대규모 재설계를 해야 하는 상황이 발생합니다.
이 문서는 D1의 아키텍처, 한도, 샤딩 전략, Time Travel·Read Replication 같은 주요 기능, 가격 구조, 실제 운영 노하우를 사실 기반으로 정리합니다. 공식 한도 페이지의 수치, 실제 운영 사례에서 보고된 비용, Cloudflare 블로그에 공개된 내부 작동 원리를 종합해 D1을 본격적으로 도입할지 결정하는 데 필요한 모든 정보를 한곳에 모았습니다.
결론을 먼저 짚으면 D1은 수많은 작은 데이터베이스를 수평으로 분산하는 아키텍처를 전제로 설계됐고, 단일 DB의 10GB 한도는 버그가 아니라 설계 그 자체입니다. 이 패러다임을 받아들이면 계정당 1TB 저장, 5,000만 행 처리, 글로벌 저지연 응답을 합리적인 비용으로 운영할 수 있고, 받아들이지 못하면 PostgreSQL이나 Turso 같은 다른 제품이 더 적합한 선택이 됩니다.
1. D1은 무엇이고 어떻게 작동하는가
D1은 SQLite를 분산 환경에 맞게 재구축한 Cloudflare의 서버리스 SQL 데이터베이스입니다. SQLite는 전 세계에서 가장 널리 배포된 SQL 엔진으로, Android·iOS·Chrome·Firefox·MacOS·Windows에 모두 내장되어 있고 매년 수십억 개 디바이스에서 검증됩니다. Cloudflare는 이 안정성과 단순함을 가져오되, 서버에 묶이지 않는 서버리스 형태로 재구성했습니다.
1.1 Durable Objects 기반의 분산 구조
각 D1 데이터베이스는 하나의 Durable Object 위에서 동작합니다. Durable Object는 Cloudflare의 강일관성 상태 저장 객체로, 전 세계 어느 PoP에서 호출하든 동일한 인스턴스로 라우팅되어 트랜잭션 일관성을 보장합니다. 이 구조 덕분에 D1은 SQLite의 단일 라이터 모델을 그대로 유지하면서도, 글로벌 엣지에서 접근 가능한 데이터베이스가 됩니다.
Durable Object 기반이라는 사실이 단일 DB의 한도가 10GB인 이유와 직결됩니다. Durable Object는 한 시점에 하나의 물리 노드에서만 실행되므로, 단일 DB가 너무 커지면 그 노드의 메모리·디스크·CPU에 부담이 집중됩니다. 그래서 Cloudflare는 작고 많은 DB를 전제로 설계했고, 단일 DB 크기를 의도적으로 제한합니다.
1.2 SQLite의 장점을 그대로 계승
D1은 SQLite의 모든 표준 SQL 문법, JSON 파싱·쿼리, 전체 텍스트 검색(FTS5) 트리거, CTE, 윈도우 함수, 트랜잭션, 외래키 제약을 지원합니다. Drizzle, Kysely, Prisma, better-sqlite3 같은 익숙한 ORM·드라이버를 거의 그대로 사용할 수 있어 학습 곡선이 매우 낮습니다. PostgreSQL이나 MySQL에서 옮겨오는 경우 대부분의 SQL은 수정 없이 동작하고, 일부 함수만 SQLite 방언으로 바꾸면 됩니다.
1.3 데이터 영속성 보장 방식
D1은 단순히 SQLite 파일을 들고 있는 게 아닙니다. 모든 쓰기 작업은 여러 위치에 내구성 있게 영속화됩니다. Cloudflare 블로그가 공개한 내부 구현에 따르면, 쓰기는 Write-Ahead Logging과 다중 PoP 복제를 거쳐 단일 노드 장애에도 데이터가 손실되지 않습니다. 사용자는 이 복잡한 메커니즘을 신경 쓸 필요 없이 평범한 SQL 쿼리만 던지면 됩니다.
2. 10GB 한도의 정체와 정확한 수치
공식 한도 페이지에 명시된 D1의 핵심 제약은 다음과 같습니다. 이 수치를 정확히 이해하는 것이 D1 도입 의사결정의 출발점입니다.
2.1 Workers Paid 플랜 기준 한도
| 항목 | Workers Paid | Workers Free |
|---|---|---|
| 계정당 데이터베이스 수 | 50,000개 | 10개 |
| 단일 DB 최대 크기 | 10 GB | 500 MB |
| 계정당 총 저장 용량 | 1 TB | 5 GB |
| Time Travel 보존 기간 | 30일 | 7일 |
| Worker 호출당 쿼리 수 | 1,000개 | 50개 |
| 단일 SQL 최대 시간 | 30초 | 30초 |
| 단일 행/문자열/BLOB 최대 크기 | 2 MB | 2 MB |
| 테이블당 컬럼 수 | 100개 | 100개 |
| SQL 문장 최대 길이 | 100 KB | 100 KB |
| 쿼리 바인딩 파라미터 수 | 100개 | 100개 |
| Worker 스크립트당 binding 수 | 약 5,000개 | 약 5,000개 |
d1 execute 파일 import 최대 |
5 GB | 5 GB |
특히 주목할 부분은 두 가지입니다. 첫째, 단일 DB 10GB 한도는 증액 불가입니다. Enterprise 계약을 맺어도 단일 DB 크기는 늘릴 수 없습니다. 둘째, 계정당 DB 개수 50,000개와 총 1TB 저장 한도는 요청 시 증액 가능합니다. Enterprise 플랜에서는 수백만~수천만 개 DB까지 지원받을 수 있다고 공식 문서에 명시되어 있습니다.
2.2 왜 10GB로 제한했는가
앞서 설명한 Durable Object 기반 단일 라이터 구조가 핵심 이유입니다. 단일 노드에서 처리되는 DB는 크기보다 동시성과 쿼리 효율이 핵심 성능 지표가 됩니다. Cloudflare 공식 문서는 다음과 같이 설명합니다.
- 단일 D1 DB는 본질적으로 single-threaded이며 쿼리를 순차 처리한다
- 평균 1ms 쿼리라면 초당 약 1,000건, 100ms 쿼리라면 초당 10건 처리 가능
- DB가 너무 많은 동시 요청을 받으면 큐에 쌓이다가 overloaded 에러 반환
- 따라서 큰 DB 1개보다 작은 DB 여러 개가 훨씬 빠르고 안정적
이 설계 철학은 PostgreSQL·MySQL 같은 전통 RDB와 정반대입니다. 전통 RDB는 큰 한 덩어리를 잘 다루도록 진화했고, D1은 작은 여러 덩어리를 잘 다루도록 처음부터 설계됐습니다.
2.3 쿼리 단위의 추가 제약
쿼리 자체에도 미세한 제약이 있습니다. 한 쿼리에서 결과로 반환할 수 있는 데이터는 사실상 메모리·CPU 한도 안에서 동작하며, 수십만 행을 한 번에 UPDATE·DELETE하는 작업은 30초 실행 한도에 걸려 실패합니다. 공식 문서는 1,000행 단위 청크로 나눠 처리하라고 권장합니다. 대규모 데이터 마이그레이션은 Queue·Workflow와 결합한 배치 처리가 표준 패턴입니다.
핵심 포인트: D1의 10GB 한도는 제약이 아니라 설계 의도입니다. 큰 DB 하나가 아니라 작은 DB 수천 개를 운영하는 방향으로 애플리케이션을 설계할 때 D1의 진짜 가치가 드러나고, 그렇지 않을 때는 Turso·Neon·Hyperdrive 같은 다른 옵션이 더 적합합니다.
3. 샤딩이란 무엇이고 D1에서 어떻게 적용하는가
샤딩(Sharding) 은 거대한 데이터셋을 여러 개의 작은 조각으로 나눠 여러 데이터베이스에 분산 저장하는 기법입니다. 한 곳에 데이터가 몰리면 발생하는 용량 한계, 동시성 병목, 백업·복구 부담을 동시에 해결하는 표준 패턴입니다.
3.1 샤딩이 필요한 이유
전통 RDB에서 샤딩은 마지막 수단에 가까웠습니다. PostgreSQL 단일 인스턴스가 수 TB까지 처리할 수 있고, MySQL 클러스터링·복제로도 상당 부분 해결되기 때문입니다. 샤딩을 도입하려면 애플리케이션 코드 수정, 분산 트랜잭션 포기, 운영 복잡도 증가라는 큰 비용을 감수해야 했습니다.
D1은 이 패러다임을 뒤집습니다. 샤딩이 옵션이 아니라 기본 운영 방식입니다. 단일 DB가 작은 대신, 수만 개의 DB를 계정 하나에서 운영할 수 있도록 binding·과금·관리 도구가 처음부터 샤딩을 전제로 만들어졌습니다.
3.2 D1의 주요 샤딩 전략
실제 D1을 TB 단위로 확장한 사례에서 사용된 샤딩 패턴은 네 가지로 정리됩니다.
- 테넌트 기반 샤딩: SaaS 서비스에서 고객사 1곳당 DB 1개를 할당하는 방식. 각 고객의 데이터가 완전히 격리되어 보안·격리성이 뛰어나고, 한 고객의 데이터가 커져도 다른 고객에 영향이 없다
- 사용자 기반 샤딩: 사용자 ID를 해시해 50개·100개 등 고정 수의 샤드에 분배. 사용자 단위로 모든 쿼리가 끝나는 소셜 앱·게임 프로필·개인 노트 같은 워크로드에 적합
- 시간 기반 샤딩: 분기별·연도별로 새 DB를 생성하고, 오래된 DB는 읽기 전용으로 두거나 R2로 아카이브. 로그·이벤트·시계열 데이터에 적합
- 지역 기반 샤딩: 사용자의 국가·대륙을 기준으로 DB를 나누는 방식. GDPR 같은 데이터 지역성 규제에 대응할 때 효과적
3.3 샤딩 라우터 구현 방법
샤딩을 실제로 동작시키려면 어떤 요청이 어떤 DB로 가야 하는지 결정하는 라우터가 필요합니다. D1에서는 다음 단계로 구현합니다.
- 모든 샤드 DB를 Worker에 binding으로 등록 (약 5,000개까지 가능)
- 요청에서 샤드 키(user_id, tenant_id, timestamp 등) 추출
- 해시 함수 또는 매핑 테이블로 어떤 binding을 쓸지 결정
- 결정된 DB에 쿼리 전송
- 결과 반환
매핑 테이블 자체는 별도의 메타 DB에 보관하거나 KV에 캐시하는 패턴이 일반적입니다. 신규 샤드를 추가할 때 기존 데이터를 재분배해야 하는 리밸런싱 부담을 줄이려면 Consistent Hashing이나 샤드 키-DB ID를 직접 매핑하는 방식이 권장됩니다.
3.4 샤딩의 비용과 효과
실제 운영 사례에서 D1을 50개 샤드로 확장해 500GB 데이터셋을 처리한 보고가 공개되어 있습니다. 단일 DB 10GB 한도 안에서도 충분한 데이터 분배 키만 있다면 사실상 무제한 확장이 가능합니다. 다만 다음 비용을 감수해야 합니다.
- 크로스 샤드 JOIN 불가: 서로 다른 DB의 테이블을 SQL JOIN으로 묶을 수 없음. 애플리케이션 레벨에서 두 번 쿼리하고 메모리에서 합쳐야 함
- 글로벌 집계의 어려움: 전체 사용자 수, 전체 매출 같은 집계는 모든 샤드에 쿼리를 보내고 결과를 합산해야 함
- 운영 도구의 복잡도 증가: 마이그레이션·백업·모니터링이 샤드별로 반복됨
- 트랜잭션 경계 제한: 한 트랜잭션 안에서 여러 샤드를 동시에 쓸 수 없음
이 비용들이 감당 가능한 워크로드(주로 사용자별·테넌트별·시간별로 데이터가 자연스럽게 분리되는 경우)에서는 D1 샤딩이 압도적으로 저렴하고 빠릅니다.
4. 한도 극복의 다른 방법들
샤딩이 부담스럽거나 워크로드 특성상 맞지 않는다면 다른 극복 전략도 있습니다. 실무에서는 여러 방법을 조합해 한도를 우회합니다.
4.1 Hot·Warm·Cold 데이터 계층화
전체 데이터를 D1에 두지 않고, 접근 빈도와 최신성을 기준으로 3계층으로 나눕니다.
- Hot 데이터 (최근 90일, 자주 조회): D1에 그대로 저장
- Warm 데이터 (90일~1년, 가끔 조회): 일별·시간별 rollup으로 압축해 D1에 저장하거나 별도 DB로 이전
- Cold 데이터 (1년 이상, 거의 조회 안 함): Parquet·JSONL.gz로 R2에 아카이브, 필요 시 DuckDB로 조회
Cron Trigger로 매일 자동 이동·삭제하는 워크플로를 짜두면 D1 용량이 일정 수준으로 유지됩니다. 1년에 5GB씩 쌓이는 로그가 있어도 90일 후 R2로 옮기면 D1엔 1.2GB 정도만 남습니다.
4.2 본문은 R2, 메타데이터만 D1
위키 페이지, 블로그 글, 상품 설명 같은 긴 본문 콘텐츠는 R2에 저장하고, D1에는 제목·슬러그·태그·발행일·R2 키 같은 메타데이터만 둡니다. 본문이 평균 10KB라면 10만 페이지가 1GB가 되지만, 메타데이터만 두면 같은 10만 페이지가 D1에서 50MB 안팎으로 줄어듭니다.
4.3 시계열 데이터는 Analytics Engine으로
페이지뷰·클릭·이벤트 같은 append-only 시계열 데이터는 D1이 아니라 Cloudflare Analytics Engine에 적재하는 것이 표준입니다. Analytics Engine은 사실상 무제한 용량에 GraphQL Analytics API로 빠른 집계를 지원합니다. D1에는 시간별·일별 rollup 결과만 저장합니다.
4.4 Read Replication으로 읽기 부하 분산
Cloudflare는 2025년 5월 D1 Global Read Replication을 베타로 공개했습니다. 단일 라이터 DB에 읽기 전용 복제본을 전 세계 여러 지역에 자동 생성해, 사용자에게 가까운 지역에서 응답합니다. 추가 사용량 과금 없이 기존 rows_read·rows_written 비용만 청구되며, 복제본 설정은 자동입니다.
Read Replication의 핵심은 순차 일관성(sequential consistency)을 유지한다는 점입니다. 쓰기를 한 직후 읽기는 항상 최신 데이터를 반환하도록 세션 토큰 메커니즘이 동작합니다. 일관성 트레이드오프 없이 글로벌 저지연을 얻을 수 있는 드문 솔루션입니다.
5. Time Travel과 백업 메커니즘
D1의 가장 차별화된 기능 중 하나가 Time Travel입니다. 별도 설정 없이 지난 30일 어느 분 단위로든 DB를 복원할 수 있는 PITR(Point-In-Time Recovery) 기능입니다.
5.1 Time Travel의 동작 원리
D1은 모든 쓰기 작업을 WAL(Write-Ahead Log) 형태로 기록합니다. Time Travel은 이 WAL을 특정 시점까지 재생해 그 시점의 DB 상태를 복원합니다. 별도의 백업 스냅샷을 만드는 게 아니라 로그 재생 방식이라 추가 저장 비용이 거의 없고, 복원 시점도 분 단위로 정밀합니다.
공식 한도에 따르면 Workers Paid는 30일, Free는 7일까지 거슬러 올라갈 수 있고, 복원 작업은 DB당 10분 안에 최대 10회로 제한됩니다. 실수로 DROP TABLE을 했거나, 잘못된 UPDATE로 데이터를 손상시켰을 때 즉시 복구가 가능합니다.
5.2 백업 vs Time Travel
| 항목 | 전통 백업 | D1 Time Travel |
|---|---|---|
| 복구 단위 | 백업 시점(일·시간) | 분 단위 |
| 추가 비용 | 백업 저장 비용 발생 | 추가 비용 없음 |
| 설정 부담 | 백업 정책 수동 설정 | 자동 활성화 |
| 보존 기간 | 정책에 따라 다양 | 최대 30일 |
| 복원 속도 | 백업 크기에 비례 | 즉시 |
Time Travel은 재해 복구가 아니라 운영 실수 복구에 최적화되어 있습니다. 1개월 이상 보존이 필요한 장기 백업은 별도로 R2에 SQL dump를 주기적으로 저장하는 방식이 권장됩니다.
6. 가격 구조 상세 분석
D1의 과금은 세 가지 축으로만 이루어집니다. 사용 시간·인스턴스 크기·연결 수 같은 전통적 DB 과금 항목이 모두 없습니다.
6.1 과금 항목 표
| 과금 항목 | Workers Free | Workers Paid |
|---|---|---|
| Rows read (행 읽기) | 일 500만 행 무료 | 월 250억 행 무료, 초과 시 100만 행당 0.001달러 |
| Rows written (행 쓰기) | 일 10만 행 무료 | 월 5,000만 행 무료, 초과 시 100만 행당 1.00달러 |
| Storage (저장 용량) | 5 GB 무료 | 5 GB 무료, 초과 시 GB당 월 0.75달러 |
| Egress (데이터 송신) | 무료 | 무료 |
| 컴퓨팅 시간 | 과금 없음 | 과금 없음 |
Workers Paid 플랜은 월 5달러의 기본료가 있고, 그 안에 D1 무료 사용 한도가 포함됩니다. 유휴 상태에서는 한 푼도 청구되지 않는 scale-to-zero 구조라, 트래픽이 없는 사이드 프로젝트는 사실상 0원으로 운영됩니다.
6.2 행 단위 과금의 의미
rows read는 쿼리가 스캔한 행의 수를 의미합니다. SELECT * FROM users로 5,000행 테이블 전체를 스캔하면 5,000 rows read가 카운트됩니다. 인덱스가 없는 컬럼으로 WHERE 필터링을 하면 결과는 1행이지만 rows read는 여전히 5,000입니다. 따라서 인덱스 설계가 비용 효율에 직결됩니다.
rows written은 INSERT·UPDATE·DELETE로 기록된 행의 수입니다. 인덱스가 있는 컬럼에 INSERT하면 테이블 1행 + 인덱스 1행 = 2 rows written이 됩니다. 인덱스 추가는 쓰기 비용을 증가시키지만, 거의 모든 워크로드에서 읽기 비용 감소가 훨씬 크기 때문에 적절한 인덱스는 비용을 절감합니다.
6.3 실제 워크로드 비용 예시
월 100만 PV의 위키 사이트 기준 추정 비용입니다.
- 페이지뷰당 평균 5쿼리 = 월 500만 쿼리, 쿼리당 평균 10행 스캔 = 5,000만 rows read → 무료 한도 250억 안에 포함, 0원
- 페이지뷰당 0.1행 쓰기(로그·통계) = 월 10만 rows written → 무료 5,000만 안에 포함, 0원
- DB 크기 3 GB → 무료 5 GB 안에 포함, 0원
- D1 비용 합계: 0원 (Workers Paid 기본료 5달러 별도)
쿠팡 파트너스급 고트래픽 사이트(월 1억 PV) 기준으로도 D1 비용은 보통 월 10~50달러 수준에 머무릅니다. 같은 워크로드를 AWS RDS PostgreSQL로 돌리면 월 200~500달러, GCP Cloud SQL은 월 150~400달러가 나옵니다.
7. 다른 데이터베이스와의 비교
D1을 선택할지 다른 옵션을 선택할지 결정할 때 비교 대상이 되는 주요 제품들입니다.
7.1 서버리스 SQL 비교
| 제품 | 엔진 | 단일 DB 한도 | 글로벌 분산 | 가격 모델 |
|---|---|---|---|---|
| Cloudflare D1 | SQLite | 10 GB | Read Replica 자동 | 행 읽기·쓰기·저장 |
| Turso | libSQL(SQLite 포크) | 사실상 무제한 | 멀티 리전 복제 | 행 읽기·쓰기·저장 |
| Neon | PostgreSQL | TB급 | 단일 리전 | 컴퓨팅 시간·저장 |
| Supabase | PostgreSQL | TB급 | 단일 리전 | 인스턴스 기반 |
| PlanetScale | MySQL Vitess | TB급 | 멀티 리전 | 행 읽기·쓰기 |
| AWS Aurora Serverless | MySQL/PostgreSQL | 64 TB | 리전 제한 | ACU·저장·I/O |
7.2 어떤 워크로드에 D1이 최적인가
- 콘텐츠 중심 웹사이트: 블로그·위키·문서·뉴스. 글로벌 사용자가 빠르게 읽어야 하고, 쓰기는 적음
- 테넌트별 SaaS: 고객사 1곳당 DB 1개 패턴. 데이터 격리가 자연스럽게 보장됨
- 단축 URL·리다이렉트: 짧은 키-값 매핑에 인덱스 검색이 핵심
- 사용자 프로필·세션: 사용자 ID로 자연스러운 샤딩이 가능
- 에지 가까운 메타데이터 조회: 상품 정보, 설정값, 권한 등 자주 읽지만 거의 안 바뀌는 데이터
7.3 어떤 경우 D1이 부적합한가
- 대규모 OLAP·BI 분석: 수억 행을 한 번에 집계하는 워크로드 → BigQuery·Snowflake·DuckDB가 적합
- 복잡한 JOIN 중심 트랜잭션 시스템: 금융 코어 뱅킹·ERP → PostgreSQL·Oracle이 적합
- 수십 TB 단일 데이터셋: 샤딩이 자연스럽지 않은 거대 그래프·관계 데이터 → Aurora·Spanner가 적합
- MySQL/PostgreSQL 호환이 필수: 기존 시스템을 그대로 옮겨야 하는 경우 → Hyperdrive 등 외부 DB 가속이 더 나음
8. 운영 시 주의 사항과 베스트 프랙티스
D1을 실제 도입할 때 자주 마주치는 함정과 권장 패턴입니다.
8.1 마이그레이션은 forward 전용
D1의 권장 마이그레이션 도구는 Drizzle ORM 또는 Wrangler D1 migrations입니다. 둘 다 forward migration을 기본으로 하며, destructive migration(테이블 DROP, 컬럼 제거)은 별도 플래그·승인 절차로 보호하는 것이 권장됩니다. 한 번 실수하면 Time Travel로 분 단위 복구는 가능하지만, 더 안전한 패턴은 new 컬럼 추가 → 데이터 복사 → 코드 전환 → old 컬럼 제거의 4단계 절차입니다.
8.2 인덱스 설계가 비용을 결정
행 단위 과금이라 인덱스 없는 풀 스캔은 비용을 빠르게 소진합니다. 자주 쓰는 WHERE 조건의 컬럼에는 반드시 인덱스를 만들고, EXPLAIN QUERY PLAN으로 SCAN TABLE 키워드가 나오는지 정기적으로 점검합니다. 복합 인덱스는 쿼리 패턴에 맞춰 컬럼 순서를 정해야 효과가 납니다.
8.3 대량 쓰기는 batch로
D1의 batch API는 최대 100,000건의 statement를 하나의 atomic 트랜잭션으로 묶어 전송합니다. 1만 행 INSERT를 1만 번 HTTP 요청으로 보내면 비용·시간 모두 폭증하지만, 100건씩 100배치로 묶으면 대부분 1초 안에 완료됩니다.
8.4 에러 핸들링과 retry
D1은 동시 요청이 많으면 overloaded 에러를 반환합니다. 클라이언트 측에서 지수 백오프 재시도와 circuit breaker 패턴을 구현해두는 것이 안정 운영의 핵심입니다. Queue 기반 비동기 처리로 부하를 분산하는 패턴도 권장됩니다.
8.5 모니터링 지표
관찰해야 할 핵심 지표는 rows_read, rows_written, duration, size_after입니다. 모든 쿼리 결과의 meta 객체에 포함되며, Cloudflare 대시보드와 GraphQL Analytics API로도 조회 가능합니다. 비정상적으로 높은 rows_read 쿼리를 찾아 인덱스를 보강하는 것이 운영 최적화의 표준 작업입니다.
9. 마무리
위에서 살펴본 Cloudflare D1 데이터베이스의 핵심 내용을 정리하면 다음과 같습니다.
핵심 요약:
- D1은 SQLite 기반 서버리스 SQL 데이터베이스로, 각 DB가 단일 Durable Object 위에서 동작하기 때문에 단일 DB는 10GB로 의도적으로 제한된다.
- 계정당 50,000개 DB, 총 1TB 저장이 기본 한도이며 Enterprise 요청 시 수천만 개까지 증액 가능하다.
- 샤딩은 D1의 기본 운영 방식이며, 테넌트별·사용자별·시간별·지역별로 DB를 나누는 패턴이 표준이다. 실제 50개 샤드로 500GB까지 확장된 운영 사례가 공개되어 있다.
- Time Travel로 분 단위 30일 PITR이 추가 비용 없이 제공되고, Global Read Replication으로 글로벌 저지연 읽기가 자동 활성화된다.
- 가격은 rows_read·rows_written·storage 세 가지로만 청구되며, scale-to-zero 구조라 트래픽이 없으면 비용도 0이다. 월 100만 PV 위키 기준 D1 비용은 사실상 0원이다.
- 대규모 OLAP, 복잡한 다중 JOIN, MySQL/PostgreSQL 호환 필수 워크로드에는 부적합하며 이 경우 Turso·Neon·Hyperdrive 같은 다른 옵션이 더 낫다.
신규 프로젝트에서 D1을 도입할지 결정할 때는 데이터 자연 분할 가능성, 글로벌 사용자 분포, 트래픽 패턴, 운영 인력 규모를 기준으로 판단해야 한다. 사용자·테넌트·시간 같은 자연스러운 샤드 키가 존재하고 콘텐츠 중심 워크로드라면 D1이 압도적으로 저렴하고 빠르다. 반대로 거대한 단일 데이터셋을 복잡한 트랜잭션으로 다뤄야 한다면 D1보다 전통 RDB가 더 적합하다.