Files
llm-wiki/raw/company-tech-blogs/planetscale-nanoid-api.md
T

9.5 KiB

title, source_type, url, archive_url, vendor, related_branches, related_projects, tags, created, status, confidence, last_reviewed
title source_type url archive_url vendor related_branches related_projects tags created status confidence last_reviewed
company-tech-blog / Why PlanetScale Chose NanoIDs for Its API company-tech-blog https://planetscale.com/blog/why-we-chose-nanoids-for-planetscales-api PlanetScale
feature-resource-identifier-contract
ca-skeleton
company-tech-blog
ca-skeleton
api-design
nanoid
resource-identifier
public-id-separation
2026-05-31 raw medium 2026-05-31

company-tech-blog / Why PlanetScale Chose NanoIDs for Its API

Layer: raw/company-tech-blogs/ — 외부 기업 기술 블로그 원문 발췌·출처 기록. PlanetScale 엔지니어링 블로그. source_type: company-tech-blog = 사례/관점. 공식 best practice 또는 normative standard 로 취급 금지. 검증된 요약은 /ingestwiki/concepts/ 또는 wiki/projects/ 에 별도 작성.

Parent / 활용 branch (필수)

이 자료는 feature-resource-identifier-contract branch 의 구현 결정 근거로 보관됨.

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-resource-identifier-contract D1 (resource ID default 형식) — NanoID 실세계 채택 사례: URL-safe 21자 alphanumeric, UUID 대비 가독성·더블클릭 선택성 이점
raw/branch-notes/feature-resource-identifier-contract D2 (charset / encoding) — NanoID 의 URL-safe alphabet (0-9a-z 또는 configurable) 실사용 근거
raw/branch-notes/feature-resource-identifier-contract D10 (DB primary key) — API-facing ID 와 DB internal PK 를 분리한 실제 구현 패턴 (Rails public_id column + BigInt PK)
raw/branch-notes/feature-resource-identifier-contract D11 (Public ID vs Internal Sequence) — public_id (NanoID) + auto-increment BigInt PK 의 Dual 컬럼 패턴 사례

출처 / Source

왜 저장했는지 / Why archived

PlanetScale 이 UUID 대신 NanoID 를 API 식별자로 채택한 이유와 구체적인 구현 방식을 설명한 기술 블로그. feature-resource-identifier-contract branch 의 D1 (형식 결정), D2 (charset), D10 (DB PK 정책), D11 (Public vs Internal 분리) 결정을 실제 production 사례로 뒷받침하는 증거 자료.

핵심 인용 / Key quotes (verbatim, 5개)

[§ 도입부 — 동기] "we wanted to avoid using integer IDs so that we wouldn't reveal the count of records in all our tables"

[§ UUID 문제점 — UX] "Try double clicking on that ID to select and copy it. You can't. The browser interprets it as 5 different words."

[§ NanoID 선택 — 충돌 확률] "This gives us a 1% probability of a collision in the next ~35 years if we are generating 1,000 IDs per hour."

[§ 구현 — Public ID vs Internal PK] "For all public-facing models, we have added a public_id column to our database. We still use standard auto-incrementing BigInts for our primary key."

[§ 결론 — 개발자 경험 철학] "These seemingly small details, like being able to quickly copy an ID, all add up."

Claims Extracted / 추출된 주장

이 자료가 직접 말하는 것만 claim 으로 분리한다. PlanetScale 의 engineering blog = company-case-study strength. 공식 best practice 또는 normative recommendation 으로 취급 금지 — 이 자료만으로 "NanoID 가 UUID 보다 항상 낫다" 는 증명 불가.

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
PLANETSCALE-NANOID-C1 PlanetScale 은 integer ID 가 테이블 레코드 수를 노출한다는 이유로 integer ID 를 거부하고 opaque ID 를 선택했다 "we wanted to avoid using integer IDs so that we wouldn't reveal the count of records in all our tables" company-case-study Sequential integer ID 를 외부 API 에 직접 노출하는 설계 Integer ID 가 모든 시스템에서 보안 위협임을 증명하지는 않음; UUID 이외 대안(ULID, CUID2 등) 의 비교 우위는 미언급
PLANETSCALE-NANOID-C2 UUID 의 하이픈 구분자로 인해 브라우저 더블클릭 선택이 불가능하고, 이것이 개발자 경험(UX)에서 실질 불편이다 "Try double clicking on that ID to select and copy it. You can't. The browser interprets it as 5 different words." company-case-study 브라우저에서 사용자가 ID 를 복사해야 하는 API / admin UI 가 있는 시스템 UUID dashed format 이 모든 환경에서 사용 불가임을 증명하지 않음; 터미널·로그 환경에서는 더블클릭 이슈 없음
PLANETSCALE-NANOID-C3 NanoID 12자 + 0-9a-z alphabet 기준, 시간당 1,000개 생성 시 35년 내 충돌 확률 1% — PlanetScale 이 이를 수용 가능한 수준으로 판단했다 "This gives us a 1% probability of a collision in the next ~35 years if we are generating 1,000 IDs per hour." company-case-study 동일한 12자 / 36-char alphabet / 시간당 1,000 ID 이하 생성 조건 이보다 높은 생성 빈도(예: 시간당 100만 개)에서의 충돌 확률; 다른 length 또는 alphabet 에서의 안전성; NanoID 의 공식 사양은 별도 검증 필요
PLANETSCALE-NANOID-C4 PlanetScale 은 외부 공개 모델에 public_id 컬럼을 추가하고, DB PK 는 기존 auto-increment BigInt 를 유지했다 "For all public-facing models, we have added a public_id column to our database. We still use standard auto-incrementing BigInts for our primary key." company-case-study API-facing ID 와 DB internal PK 를 분리해야 하는 시스템 (Dual 컬럼 패턴) BigInt PK + public_id 가 ca-skeleton 의 최적 패턴임을 증명하지 않음; External-only (PK=NanoID) 패턴의 trade-off 는 미언급
PLANETSCALE-NANOID-C5 ID 의 복사 편의성 같은 작은 UX 디테일이 누적되어 전반적인 개발자 경험에 영향을 준다는 것이 PlanetScale 의 철학이다 "These seemingly small details, like being able to quickly copy an ID, all add up." company-case-study 외부 API 식별자 설계 시 개발자 경험(DX)을 고려 기준으로 포함하는 맥락 이 철학이 보편적으로 적용 가능하거나 다른 trade-off(DB 성능, 보안)보다 우선해야 함을 증명하지 않음

Usage Boundaries / 적용 경계

이 자료가 직접 증명하는 것

  • PLANETSCALE-NANOID-C1: Sequential integer ID 의 레코드 수 노출 위험 — PlanetScale 사례 수준
  • PLANETSCALE-NANOID-C2: UUID dashed format 의 브라우저 더블클릭 UX 문제 — 구체적 재현 가능한 사실
  • PLANETSCALE-NANOID-C3: NanoID 12자 / 36-char alphabet / 시간당 1,000개 생성 조건에서의 충돌 확률 수치 — PlanetScale 계산 기준
  • PLANETSCALE-NANOID-C4: public_id (NanoID) + auto-increment BigInt PK Dual 컬럼 패턴 — PlanetScale prod 구현 사례
  • PLANETSCALE-NANOID-C5: ID 복사 편의성이 개발자 경험에 누적 기여함 — PlanetScale 의 설계 철학

이 자료가 증명하지 않는 것

  • NanoID 가 UUID v7 / ULID / CUID2 보다 일반적으로 우수한 선택임 (비교 데이터 없음)
  • NanoID default 21자 길이의 충돌 확률 (본 글은 12자 기준)
  • public_id Dual 컬럼 패턴이 external-only 패턴보다 ca-skeleton 에 적합한지 (trade-off 비교 미언급)
  • NanoID 가 DB index 성능에 미치는 영향 (random insert B-tree fragmentation 등 — time-ordered ID 와 동일한 약점 언급 없음)
  • PlanetScale 의 NanoID alphabet 이 URL-safe RFC 3986 unreserved charset 과 정확히 일치하는지

내 프로젝트에 적용하려면 추가 확인이 필요한 것

  • ca-skeleton 의 실제 ID 생성 빈도와 12자 충돌 확률의 관계 — 더 높은 빈도라면 21자(NanoID default) 또는 26자(ULID) 검토
  • NanoID 공식 사양에서 21자 / URL-safe alphabet 의 충돌 확률 공식 검증 (별도 official-doc 필요)
  • Dual 컬럼(public_id + BigInt PK) vs External-only (NanoID as PK) 의 ca-skeleton 맥락 trade-off — D11 결정 전 Shopify / Stripe 사례 추가 비교 필요

메모 / Notes

  • 본 자료의 alphabet 예시 0123456789abcdefghijklmnopqrstuvwxyz (36자) 은 NanoID 의 URL-safe default alphabet (64자: A-Za-z0-9_-) 과 다름 — PlanetScale 이 custom alphabet 을 사용했을 가능성. D2 (charset 결정) 시 NanoID 공식 문서 별도 확인 필요.
  • Rails 구현에서 before_create callback + 충돌 시 retry 로직 언급 — Java/Spring 에서의 동등 구현 패턴은 본 자료로 추론 불가.
  • Go 구현에서 go-nanoid 라이브러리 사용 언급 — Java 생태계 라이브러리(예: nanoid-java) 와는 별개 검증 필요.
  • 충돌 확률 계산에 "NanoID collision tool" 사용 언급 — https://zelark.github.io/nano-id-cc/ 로 추정되나 URL 미확인.