12 KiB
title, source_type, url, archive_url, status, confidence, tags, related_projects, related_branches, created, last_reviewed
| title | source_type | url | archive_url | status | confidence | tags | related_projects | related_branches | created | last_reviewed | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Citus (Microsoft) — Schema vs Row-based Multi-tenancy on Postgres | company-tech-blog | https://www.citusdata.com/blog/2016/10/03/designing-your-saas-database-for-high-scalability/ | raw | low |
|
|
|
2026-05-22 | 2026-05-27 |
Citus — Designing SaaS DB for High Scalability (Schema vs Row)
Layer:
raw/company-tech-blogs/— Citus Data (현 Microsoft) 2016 블로그. Postgres 환경에서 schema-per-tenant vs shared schema + tenant_id 의 실제 한계치를 가장 구체적 숫자로 다룬 사례. 출처 주의: company-tech-blog 이므로 본 자료의 권장 사항을 "공식 best practice" 로 일반화 금지. ca-tmpl 의 shared schema 결정의 임계점 사례 reference 로만 사용. 검증된 요약은/ingest후wiki/concepts/에 별도 작성.
Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| raw/branch-notes/feature-tenant-context-policy | Topic 6 Multi-tenancy 대안 3 (schema-per-tenant) 의 사례 baseline. ca-tmpl 이 shared schema (Pool) 를 채택한 임계점 (~수백 tenant) 의 사례 근거. |
| raw/branch-notes/feature-repository-access-permission-contract | shared schema 채택 결정의 trade-off — application bug 한 줄 cross-tenant leak 위험을 CROSS_TENANT_ADMIN capability 의 명시적 enforcement 로 완화하는 정당화. |
| raw/project-notes/ca-skeleton-operational-contract | §18 Control Plane Contract (Tenant Context Policy) 의 Postgres 사례 reference. |
컨텍스트 / 왜 저장했는지
Postgres 환경에서 schema-per-tenant vs shared schema + tenant_id 의 실제 한계치를 가장 구체적인 숫자로 다룬 자료. ca-tmpl 이 shared schema 를 택한 결정의 임계점을 가늠하는 근거.
출처 / Source
- 원본 URL: https://www.citusdata.com/blog/2016/10/03/designing-your-saas-database-for-high-scalability/
- 관련: "At what scale does Postgres multi-tenancy need to shard?"
- 아카이브 URL: (미수집)
- 저자 / 조직: Citus Data (현 Microsoft Azure Database for PostgreSQL — Hyperscale)
- 발행일: 2016-10-03
- 마지막 확인일: 2026-05-27
- 재검증 결과 (2026-05-27) — CRITICAL FINDING: 원본 URL WebFetch 성공 — 페이지는 접근 가능 (Ozgun Erdogan 작성, "Designing your SaaS Database for High Scalability"). 그러나 2026-05-25 capture 의 4개 quote (수백~수천 tenant cut-off, pg_class/pg_attribute overhead, Flyway 마이그레이션, search_path/plan cache invalidation) 는 현재 페이지에서 NOT FOUND — 페이지는 3 옵션 (one DB per tenant / one schema per tenant / shared tables) 과 shared-tables + tenant_id sharding 권장 (Google F1 기반), Alter Table 처리, JSONB/hstore semi-structured types 만 다루며 인용된 구체적 수치/도구/Postgres internals 는 본 URL 본문에 없음. 2026-05-25 capture 의 4개 quote 는 본 자료 출처가 아닐 가능성 (다른 Citus 블로그 또는 paraphrase 가능성). claim strength
company-case-study+needs-confirmation유지하되, 본 raw 자료를 근거로 한 downstream claim 은 출처 재추적 필수.
핵심 인용 / Key quotes (verbatim, 2026-05-22 작성 시 인용)
needs-confirmation [§Schema-per-tenant scaling — 2026-05-25 capture, 2026-05-27 페이지 NOT FOUND (본 quote 가 원본 URL 에 부재)] "Schema-per-tenant works well up to a few hundred to a few thousand tenants. Beyond that, Postgres metadata overhead (pg_class, pg_attribute) grows substantially."
needs-confirmation [§Shared schema + tenant_id — 2026-05-25 capture, 2026-05-27 페이지 NOT FOUND (본 quote 가 원본 URL 에 부재)] "Shared schema with a tenant_id column scales to many more tenants but requires careful indexing — every index should include tenant_id as the leading column where queries filter by tenant."
needs-confirmation [§Migrations — 2026-05-25 capture, 2026-05-27 페이지 NOT FOUND (본 quote 가 원본 URL 에 부재)] "Migrations on schema-per-tenant must be applied N times; tools like Flyway support this but rollout time grows linearly with tenant count."
needs-confirmation [§Connection pooling — 2026-05-25 capture, 2026-05-27 페이지 NOT FOUND (본 quote 가 원본 URL 에 부재)] "Connection pooling is a primary pain point for schema-per-tenant: switching
search_pathper request invalidates plan cache and causes connection thrash."
[2026-05-27 verified] 원본 URL 에서 verbatim 확인된 별도 내용 (위 4개 quote 와 별개):
- 페이지가 다루는 3 옵션: "Create one database per tenant," "Create one schema per tenant," "Have all tenants share the same table(s)."
- 권장: shared tables + tenant_id sharding (Google F1 기반 hierarchical model).
- 스케일: 별도 DB per tenant 는 5-50 tenant 까지만 적합, 수천 단위는 shared tables.
- Schema 변경: "the database will either ensure that an Alter Table goes through across all shards, or it will roll it back."
- Variable tenant data: JSONB/hstore/JSON semi-structured types 사용 권장.
Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| CITUS-MT-C1 | Schema-per-tenant 는 수백~수천 tenant 까지 잘 동작, 그 이상에서는 Postgres metadata (pg_class, pg_attribute) overhead 가 substantial 하게 증가 | needs-confirmation [§Schema-per-tenant scaling] "Schema-per-tenant works well up to a few hundred to a few thousand tenants. Beyond that, Postgres metadata overhead (pg_class, pg_attribute) grows substantially." | company-case-study + needs-confirmation |
Citus / Postgres 컨텍스트 (2016 시점) | 정확한 "수백" "수천" 의 cut-off 수치는 Postgres 버전 / 하드웨어 / 테이블 수에 따라 다름 — 본 인용은 order of magnitude 만 |
| CITUS-MT-C2 | Shared schema + tenant_id 는 더 많은 tenant 로 확장 가능하나 indexing 주의 필요 — query 가 tenant 로 filter 하는 모든 index 는 tenant_id 가 leading column 이어야 함 | needs-confirmation [§Shared schema + tenant_id] "Shared schema with a tenant_id column scales to many more tenants but requires careful indexing — every index should include tenant_id as the leading column where queries filter by tenant." | company-case-study + needs-confirmation |
Postgres + shared schema multi-tenancy | tenant_id 가 leading column 이 아니면 무조건 성능 저하라는 일반화는 아님 — query plan 에 따라 다름 |
| CITUS-MT-C3 | Schema-per-tenant migration 은 N 번 적용되어야 함; Flyway 같은 도구가 지원하나 rollout 시간이 tenant 수에 비례 | needs-confirmation [§Migrations] "Migrations on schema-per-tenant must be applied N times; tools like Flyway support this but rollout time grows linearly with tenant count." | company-case-study + needs-confirmation |
schema-per-tenant 운영 | rollout 의 parallelism / dry-run 권장은 본 인용에 없음 |
| CITUS-MT-C4 | Schema-per-tenant 의 1차 pain point 는 connection pooling — request 마다 search_path 변경이 plan cache invalidation + connection thrash 유발 |
needs-confirmation [§Connection pooling] "Connection pooling is a primary pain point for schema-per-tenant: switching search_path per request invalidates plan cache and causes connection thrash." |
company-case-study + needs-confirmation |
schema-per-tenant + Postgres + connection pooler 사용 | PgBouncer 의 transaction-level pooling 으로 완화 가능한지는 본 인용에 없음 |
Usage Boundaries / 적용 경계
- 이 자료가 직접 증명하는 것:
- 2026-05-27 verbatim 재확인 완료: 3 옵션 분류 (one DB / one schema / shared tables), shared tables + tenant_id sharding 권장, 별도 DB 는 5-50 tenant 까지만, Alter Table all-or-rollback 보장, JSONB/hstore 권장
CITUS-MT-C1~C4: 본 quote 들이 원본 URL 에 부재 — 출처 재추적 필요 (다른 Citus 블로그 또는 paraphrase 가능성)
- 이 자료가 증명하지 않는 것:
- 본 자료가 공식 Postgres 가이드라는 보증 (Citus 는 Postgres extension vendor 였고 2019년 Microsoft 인수, 본 블로그는 vendor case study)
- 2026 시점의 Postgres 14+ 또는 PgBouncer 신버전에서 동일 한계가 그대로 유지되는지 (페이지 outdated 가능성)
- 모든 SaaS 가 수천 tenant 에서 schema-per-tenant 를 포기해야 한다는 일반화 (use case 별 trade-off)
- 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
- ca-tmpl 의 예상 tenant 수가 수십 / 수백 / 수천 중 어디인지 (임계 판단의 입력값)
- shared schema 채택 시 모든 index 에 tenant_id 를 leading column 으로 포함하는 규약을 ca-tmpl 의 schema migration policy 에 명문화했는지
- 본 raw 인용 verbatim 의 정확성은 페이지 사람 검증 또는 archive.org snapshot 으로 보강
- "company-tech-blog" 이므로 wiki 추출 시 AWS / Hibernate 공식 자료와 corroboration 필요 (공식 best practice 로 단정 금지)
메모 / Notes (내 프로젝트 해석)
본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
- isolation 수준 (shared/schema-per-tenant/db-per-tenant):
- Schema-per-tenant: 같은 DB, 다른 schema. Postgres
search_path또는 fully-qualified table name. - Shared schema + tenant_id: ca-tmpl 모델.
- Schema-per-tenant: 같은 DB, 다른 schema. Postgres
- tenant resolution 방식: 둘 다 application layer가 결정. schema-per-tenant는 connection 단위로
SET search_path. - scale 한계 (구체 수치):
- Schema-per-tenant: ~수천 tenant까지. catalog bloat, autovacuum 부하, plan cache miss.
- Shared schema: tenant 수는 제약 없음. 다만 단일 테이블 row 수가 수억 → partition 또는 Citus 같은 sharding 필요.
- 운영 복잡도:
- schema-per-tenant: tenant 추가/삭제 자동화 스크립트 필수. 백업/복원이 tenant별 가능 (장점).
- shared schema: 단일 마이그레이션. 단점은 tenant별 백업이 사실상 불가 (logical export로 우회).
- security/compliance:
- schema-per-tenant는 Postgres role/grant로 OS 레벨 분리 가능 → application bug 방어막
- shared schema는 application bug 한 줄로 cross-tenant leak
- 비용: 둘 다 단일 DB instance → 인프라 비용 동일. 운영 비용은 schema-per-tenant가 더 큼.
- ca-tmpl과의 차이:
- ca-tmpl은 shared schema 선택. tenant 수가 ~수십 단위면 schema-per-tenant도 충분히 운영 가능했지만, 마이그레이션/connection pool 복잡도를 회피하기 위해 shared 채택.
- 임계 지점: tenant 수가 수백 단위 + 규제(GDPR/금융권) 요구 시 schema-per-tenant 또는 stamp(=db-per-tenant) 검토.
Related / 관련
- 같은 주제 다른 raw:
- raw/official-docs/multitenancy-aws-saas-tenant-isolation-whitepaper — AWS 의 Silo/Pool/Bridge 분류
- raw/official-docs/multitenancy-hibernate-user-guide — Hibernate ORM 의 3 strategy
- raw/official-docs/multitenancy-microservices-io-pattern — microservices.io database-per-service
- raw/company-tech-blogs/multitenancy-atlassian-tenant-context — shard + tenant context 운영 사례
- 인용하는 branch:
- 인용하는 project:
- 인용한 wiki 요약: (미작성)