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 |
|
|
|
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 로 취급 금지. 검증된 요약은/ingest후wiki/concepts/또는wiki/projects/에 별도 작성.
Parent / 활용 branch (필수)
이 자료는
feature-resource-identifier-contractbranch 의 구현 결정 근거로 보관됨.
| 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
- 원본 URL: https://planetscale.com/blog/why-we-chose-nanoids-for-planetscales-api
- 아카이브 URL: (미확인)
- 저자 / 조직: PlanetScale Engineering Blog
- 발행일: (확인 필요 — 페이지에서 날짜 추출 불가)
- 마지막 확인일: 2026-05-31
왜 저장했는지 / 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_idcolumn to our database. We still use standard auto-incrementingBigInts 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-studystrength. 공식 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-incrementBigIntPK Dual 컬럼 패턴 — PlanetScale prod 구현 사례PLANETSCALE-NANOID-C5: ID 복사 편의성이 개발자 경험에 누적 기여함 — PlanetScale 의 설계 철학
이 자료가 증명하지 않는 것
- NanoID 가 UUID v7 / ULID / CUID2 보다 일반적으로 우수한 선택임 (비교 데이터 없음)
- NanoID default 21자 길이의 충돌 확률 (본 글은 12자 기준)
public_idDual 컬럼 패턴이 external-only 패턴보다 ca-skeleton 에 적합한지 (trade-off 비교 미언급)- NanoID 가 DB index 성능에 미치는 영향 (random insert B-tree fragmentation 등 — time-ordered ID 와 동일한 약점 언급 없음)
- PlanetScale 의 NanoID alphabet 이 URL-safe RFC 3986
unreservedcharset 과 정확히 일치하는지
내 프로젝트에 적용하려면 추가 확인이 필요한 것
- 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_createcallback + 충돌 시 retry 로직 언급 — Java/Spring 에서의 동등 구현 패턴은 본 자료로 추론 불가. - Go 구현에서
go-nanoid라이브러리 사용 언급 — Java 생태계 라이브러리(예:nanoid-java) 와는 별개 검증 필요. - 충돌 확률 계산에 "NanoID collision tool" 사용 언급 — https://zelark.github.io/nano-id-cc/ 로 추정되나 URL 미확인.
Related / 관련
- 같은 주제 다른 company-tech-blog (예정):
raw/company-tech-blogs/shopify-public-private-id— Dual 컬럼 패턴 비교 - 같은 주제 다른 company-tech-blog (예정): raw/company-tech-blogs/segment-ksuid.md — KSUID 사례 (time-ordered 대안)
- 공식 문서 (예정): raw/official-docs/nanoid-spec.md — NanoID 21자 default / URL-safe alphabet / 충돌 확률 공식
- 이 자료를 인용한 branch: raw/branch-notes/feature-resource-identifier-contract