목록 API가 작은 데이터에서는 잘 동작해도 수백만 건이 쌓이면 뒤 페이지가 느려지고, 새 데이터가 들어올 때 항목이 중복되거나 빠질 수 있습니다. 페이지네이션은 단순 UI 옵션이 아니라 정렬과 일관성의 계약입니다.
정렬 순서를 완전히 정한다
created_at만으로 정렬하면 같은 시각의 여러 항목 사이 순서가 불안정합니다. 생성 시각과 고유 ID를 함께 써서 모든 항목에 고정된 순서를 부여합니다. 정렬 필드가 자주 바뀌면 페이지 경계가 흔들릴 수 있습니다.
오프셋과 커서의 차이를 이해한다
offset 방식은 구현이 쉬워도 뒤 페이지로 갈수록 건너뛸 행이 많아지고, 앞쪽에 새 항목이 들어오면 중복이 생길 수 있습니다. 커서는 마지막으로 본 정렬 키 다음을 요청합니다. 다만 커서도 삭제·수정에 대한 정책이 필요합니다.
필터와 권한을 커서에 묶는다
같은 커서를 다른 검색어 또는 다른 테넌트에 재사용하면 잘못된 결과가 나올 수 있습니다. 커서에는 정렬·필터의 버전을 포함하거나 서버가 검증 가능한 형태로 인코딩합니다. 테넌트 접근 제어는 커서 내용과 별도로 항상 다시 확인합니다.
전체 개수의 비용을 표시한다
대규모 목록에서 매 요청마다 정확한 총 건수를 계산하면 비쌀 수 있습니다. 다음 페이지 존재 여부가 꼭 필요한지, 총 개수는 지연된 값이어도 되는지 제품 요구를 정합니다. UI에 잠정 개수를 표시한다면 그 의미를 알려 줍니다.
동시 변경 상황을 시험한다
페이지를 넘기는 동안 새 글이 추가되고 기존 글이 삭제되는 테스트를 합니다. 중복·누락을 허용할 수 없는 내보내기라면 단순 목록 커서 대신 시점 고정 스냅샷이나 별도 배치 작업이 필요할 수 있습니다.
현장에 적용할 때의 순서
- 고유한 복합 정렬 키 정의
- 커서·필터·권한 문맥 결합
- 동시 변경·대용량 테스트
주의할 실패: 오프셋만 무한 확장
관찰할 지표: 깊은 페이지 지연과 중복률
적용 전 체크리스트
- 동률을 깨는 고유 정렬 키가 있는가
- 커서가 필터·테넌트 문맥을 벗어나지 않는가
- 동시 추가·삭제 중 중복·누락을 시험했는가
참고 자료
Stripe API Pagination. cursor 기반 목록 조회의 API 예시를 참고했습니다. 대규모 데이터의 성능과 스냅샷 정책은 자체 요구에 따라 검증해야 합니다.
이미지와 도식은 이해를 돕기 위한 개념 시각화입니다. 특정 고객의 실제 설비·데이터·화면을 재현한 것이 아닙니다.
#페이지네이션 #커서기반 #목록API #API설계 #데이터베이스 #성능최적화 #SaaS개발 #정렬안정성 #테넌트보안 #백엔드