Huny's Dev Blog
huny.dev

D1 쿼리 결과 50 MB 제한 예고: 컬럼 축소와 페이지네이션 점검하기

Cloudflare D1이 11월 4일부터 적용할 쿼리 결과 크기 제한을 정리한다. LIMIT의 행 수와 바이트 크기를 구분하고, 로컬 SQLite 예제로 커서 순회와 export 예외·제약을 확인한다.

Hun Jang
Hun Jang Oct 31, 2026

큰 데이터 묶음을 작은 페이지로 나누는 과정을 표현한 생성형 개념 이미지다. 실제 Cloudflare 화면이 아니다.

D1에서 목록 조회나 관리자용 전체 다운로드가 갑자기 실패하지 않으려면, 반환하는 데이터의 크기를 먼저 점검해야 한다. Cloudflare는 2026년 10월 30일 공지를 통해 11월 4일부터 쿼리 결과가 50 MB를 초과하면 오류를 반환한다고 밝혔다. 필요한 컬럼만 가져오고 결과를 작은 페이지로 나누는 것이 기본 대응이다. 공식 발표

저장 용량과 조회 결과 용량을 구분한다

이번 변경은 DB 전체의 저장 용량 한도가 아니라 한 쿼리가 반환하는 결과의 크기 제한이다. 큰 본문이나 JSON을 포함한 테이블에서 SELECT *로 전체 행을 읽는 코드가 우선 점검 대상이다.

공식 오류 문구는 다음과 같다.

발표는 대부분의 요청이 영향을 받지 않을 것으로 설명한다. 그렇더라도 평균적인 목록 화면만 확인해서는 드물게 실행하는 대량 조회의 안전성을 판단하기 어렵다. 관리자 화면, 배치 조회, 데이터 내려받기를 따로 살펴보는 편이 좋다.

공식 문서에는 정확한 시행 시각이나 내부 크기 계산식이 제시되지 않았다. 50 MB를 임의의 바이트 수로 환산해 경계까지 채우는 설계보다 충분한 여유를 두는 것이 낫다. D1 제한과 시행일 각주

먼저 컬럼을 줄이고, 정렬 기준을 고정한다

목록에는 ID와 제목만 필요한데 상세 본문까지 가져온다면, 페이지를 나누기 전부터 불필요한 데이터가 발생한다. 다음은 가상의 events 테이블을 대상으로 한 SQL 예시다.

Cloudflare도 컬럼 선택과 LIMIT·OFFSET을 권고한다. 다만 LIMIT 100은 최대 100행을 뜻한다. 각 행의 내용이 크거나 길이 편차가 크면 같은 행 수라도 결과 크기가 달라진다. 특정 LIMIT 값만으로 50 MB 미만임을 보장할 수 없다. SQLite LIMIT·OFFSET

오래 순회한다면 마지막 ID를 커서로 사용한다

깊은 페이지까지 순차적으로 읽는 작업에는 keyset 방식도 검토할 수 있다. 아래 예시는 고유하고 NULL이 없으며 변경되지 않는 정수 기본키 id를 전제로 한다.

커서는 마지막 행의 실제 id에서 얻는다. 행 개수만큼 ID를 더하면 삭제된 행이나 ID 간격 때문에 잘못된 커서를 만들 수 있다. 적절한 인덱스도 필요하다. 정렬 키가 중복될 수 있는 created_at 같은 값이면 고유 ID를 함께 사용하는 복합 커서를 설계해야 한다. SQLite의 scrolling window 설명

이 방식은 전체 순회를 하나의 스냅샷으로 만들어 주지는 않는다. 순회 중 데이터가 추가·수정·삭제된다면 어떤 버전의 데이터를 보여 줄지 별도로 정해야 한다. 또한 서버에서 페이지들을 다시 하나의 거대한 배열로 합치면 애플리케이션의 메모리와 응답 크기 문제는 남는다.

작은 합성 데이터로 동작을 확인한다

다음 코드는 Python 표준 라이브러리만 사용한다. 메모리 SQLite에 가짜 데이터 12행을 만들고, 전체 조회와 컬럼을 줄인 첫 페이지의 JSON UTF-8 크기를 비교한다. 운영 DB에 연결하지 않는다.

로컬 SQLite 3.53.1에서 실제 실행한 결과다.

이는 합성 데이터에서 SQL 순회와 JSON 크기 차이를 확인한 결과다. D1의 50 MB 차단을 재현하거나 성능을 측정한 것은 아니다. 이 JSON 크기는 애플리케이션 측 관찰값이며 D1 내부 제한 판정과 동일한 계산이라고 볼 수 없다.

전체 백업은 export 경로를 따로 검토한다

공식 공지는 REST API를 통한 import·export가 이번 결과 크기 제한의 예외라고 명시한다. 그렇다고 일반 쿼리를 REST API로 보내면 제한을 피할 수 있다는 뜻은 아니다.

백업이나 이관이라면 전용 export 기능이 맞는지 검토한다. 다만 공식 문서에 따르면 export 실행 중에는 대상 D1 DB의 다른 요청이 차단되며, 가상테이블이 포함된 DB의 export도 지원되지 않는다. 운영 시간과 데이터 구조를 확인하지 않은 채 전환해서는 안 된다. Import·export 문서

11월 4일 전에 확인할 항목

  • 전체 조회, 긴 본문·JSON·BLOB 반환, 관리자 다운로드 경로를 찾는다.
  • 응답에 필요한 컬럼만 남기고 페이지 단위를 작게 시작한다.
  • 최대 길이 데이터, 빈 페이지, 마지막 페이지, ID 간격을 테스트한다.
  • 동시 데이터 변경 시 허용할 일관성을 정한다.
  • 운영과 같은 경로의 응답 크기·메모리·지연을 검증 환경에서 확인한다.
  • 결과 크기 오류는 같은 요청을 반복하기보다 컬럼이나 페이지 크기를 줄여 해결한다.

D1 오류표도 이 오류에 대해 결과 축소와 페이지네이션을 안내한다. 일시적인 연결 오류와 구분하여 처리해야 불필요한 재시도를 줄일 수 있다. 공식 오류 목록

이 글에서는 실제 Cloudflare 계정의 설정 변경, 원격 쿼리, export를 실행하지 않았다. 적용 일정과 제품 제약은 공식 문서 설명이며, 페이지 크기·커서·검증 절차는 이를 바탕으로 한 구현 제안이다.

추천 글