다중 테넌트 대 다중 사이트 아키텍처를 놓고 몇 개월간 논쟁하는 팀들을 봐왔는데, 결국 잘못된 선택을 했다가 또 다른 6개월을 마이그레이션에 쏟아붓곤 합니다. 추상적으로 보일 때는 괜찮은 결정이지만, 3개 스프린트가 지나면 콘텐츠 편집자가 실수로 잘못된 브랜드에 게시하거나, 배포 파이프라인이 45분 걸린다는 걸 깨닫게 됩니다. 단 하나만 변경되었는데 12개 사이트를 모두 다시 빌드하고 있기 때문입니다.

이것은 이론적인 비교가 아닙니다. 나는 두 패턴 모두 구축했으며, 때때로 같은 클라이언트를 위해 처음 선택이 작동하지 않을 때 모두 구축하기도 했습니다. 이 결정을 할 때 실제로 중요한 사항들을 안내해드리겠습니다.

목차

Multi-Tenant vs Multi-Site Architecture: How to Decide

용어 명확히 정의하기

이 용어들은 느슨하게 사용되곤 하므로 정확히 정의해보겠습니다.

다중 테넌트 아키텍처

하나의 애플리케이션 인스턴스가 여러 테넌트(브랜드, 클라이언트, 지역)를 제공합니다. 같은 코드베이스, 같은 데이터베이스(일반적으로), 같은 배포를 공유합니다. 테넌트 격리는 애플리케이션 계층에서 발생합니다. 미들웨어, 데이터베이스 스키마, 또는 행 수준 필터링을 통해서 말입니다.

아파트 건물처럼 생각하면 됩니다. 모두가 구조, 배관, 전기를 공유합니다. 하지만 각 단위는 자체 잠금장치를 가지고 있습니다.

다중 사이트 아키텍처

각 사이트는 자체 코드베이스(또는 공유 코드베이스의 포크), 자체 데이터베이스, 자체 배포 파이프라인을 가진 별도의 애플리케이션 인스턴스입니다. 디자인 시스템이나 컴포넌트 라이브러리를 공유할 수도 있지만, 독립적으로 배포되고 운영됩니다.

이는 주택 개발지와 더 비슷합니다. 같은 건설업자, 비슷한 청사진, 하지만 각 집은 자체 기초 위에 세워집니다.

하이브리드 존

솔직히 대부분의 프로덕션 시스템은 그 사이 어딘가에 자리합니다. 독립적으로 배포된 프론트엔드에 콘텐츠를 제공하는 다중 테넌트 CMS를 가질 수 있습니다. 또는 테넌트당 별도의 인스턴스로 배포되는 공유 코드베이스를 가질 수 있습니다. 실제 질문은 "어느 것"이 아니라 "스펙트럼의 어디"입니다.

다중 테넌트 아키텍처가 승리하는 경우

다중 테넌트는 사이트가 다르기보다는 유사할 때 빛을 발합니다.

강한 브랜드 일관성 요구사항

같은 브랜드의 15개 지역 사이트를 관리하고 있고 디자인을 고정된 상태로 유지해야 한다면, 다중 테넌트가 당신의 친구입니다. 하나의 코드베이스는 컴포넌트, 레이아웃, 상호작용 패턴에 대한 단일 출처를 의미합니다. 브랜드 팀이 버튼 스타일을 업데이트하면 모든 곳에 배포됩니다.

새로운 테넌트로의 빠른 확장

주간 단위로 새로운 위치를 구축해야 하는 프랜차이즈 플랫폼과 함께 작업했습니다. 다중 테넌트를 사용하면 새로운 사이트를 추가하는 것은 데이터베이스 항목과 DNS 레코드였습니다. 새로운 인프라 없음, 새로운 배포 없음. 출시 시간이 2주에서 약 30분으로 단축되었습니다.

중앙 집중식 콘텐츠 운영

작은 콘텐츠 팀이 여러 속성을 관리할 때, 다중 테넌트는 모든 것을 한 곳에 보관합니다. 편집자는 하나의 시스템에 로그인하고, 컨텍스트를 전환하고, 모든 테넌트에서 콘텐츠를 관리합니다. 12개의 CMS 인스턴스에 대한 자격증명을 관리할 필요가 없습니다.

공유 기능 개발

구축하는 모든 기능은 모든 테넌트에 동시에 혜택을 줍니다. 버그 수정, 성능 개선, 새로운 통합 - 한 번 배포하면 모든 곳에 혜택을 줍니다. 개발 노력에 대한 ROI는 곱셈입니다.

다중 사이트 아키텍처가 승리하는 경우

다중 사이트는 사이트가 크게 다를 필요가 있을 때 승리합니다.

근본적으로 다른 사용자 경험

브랜드 A가 전자상거래 상점이고 브랜드 B가 콘텐츠 출판물이라면, 하나의 코드베이스에 두 가지를 집어넣는 것은 엉망입니다. 나는 60%의 코드가 테넌트별 조건부 뒤에 있는 다중 테넌트 코드베이스를 봤습니다. 그 시점에서 당신은 하나의 애플리케이션을 가지지 않은 것입니다 - 저장소를 공유하는 여러 개의 나쁜 것들을 가지고 있습니다.

다른 기술 요구사항

한 사이트는 동적이고 앱 같은 경험을 위해 Next.js가 필요하고, 다른 사이트는 Astro에 완벽한 콘텐츠 헤비 사이트일 수 있습니다. 다중 사이트는 각 속성이 올바른 도구를 사용하도록 허용합니다. 우리는 일부 사이트는 Next.js에서 실행되고 다른 사이트는 Astro에서 실행되며, 모두 공유 헤드리스 CMS에서 가져오는 포트폴리오를 구축했습니다.

독립적인 릴리스 사이클

다른 비즈니스 단위가 다른 사이트를 소유하고 자체 일정에 따라 배포해야 할 때, 다중 테넌트는 병목이 됩니다. 테넌트 A의 새로운 기능에 대한 배포가 테넌트 B부터 Z까지의 회귀 테스트를 요구하지 않아야 합니다. 다중 사이트는 각 팀에 자율성을 제공합니다.

규제 또는 데이터 격리

일부 산업에서는 엄격한 데이터 격리를 요구합니다 - 단순한 애플리케이션 계층 분리가 아니라 물리적으로 분리된 데이터베이스, 잠재적으로 다른 지역에 있는 데이터베이스입니다. 의료, 금융, 정부 프로젝트는 종종 이를 요구합니다. 다중 사이트는 격리가 논리적이 아닌 아키텍처적이기 때문에 준수를 간단하게 만듭니다.

다른 성능 프로필

한 테넌트가 월 1000만 방문을 받고 다른 테넌트가 50,000을 받으면, 인프라를 공유하는 것은 작은 테넌트에 대해 과도하게 프로비저닝하거나 큰 테넌트에 대해 과소 프로비저닝하는 것을 의미합니다. 별도의 배포를 통해 각 속성의 크기를 올바르게 조정할 수 있습니다.

Multi-Tenant vs Multi-Site Architecture: How to Decide - architecture

의사결정 프레임워크

여기 내가 클라이언트와 함께 실제로 사용하는 프레임워크입니다. 상황에 맞게 각 요소에 점수를 매기세요:

요소 다중 테넌트 선호 다중 사이트 선호
사이트 유사성 80% 이상 공유 UI/기능 50% 미만 공유
속성 수 10개 이상의 사이트 5개 미만의 사이트
성장률 자주 사이트 추가 안정적, 거의 추가 없음
팀 구조 하나의 중앙 팀 사이트당 독립적인 팀
콘텐츠 모델 동일 또는 거의 동일 크게 다름
준수 요구사항 표준 요구사항 엄격한 데이터 격리
기술 스택 모든 곳에 같은 프레임워크 필요한 다른 프레임워크
릴리스 주기 조정된 릴리스 OK 독립적인 릴리스 필요
사용자화 깊이 테마 수준(색상, 로고) 구조적(레이아웃, 기능)
예산 효율성 최적화 유연성 최적화

대부분 한 열에서 점수를 받고 있다면, 결정은 명확합니다. 중간을 따라 점수가 나뉘어진다면, 아마도 하이브리드 접근 방식을 살펴보고 있는 것일 것입니다 - 그리고 그것은 괜찮습니다.

실제 아키텍처 패턴

코드에서 구체적으로 살펴보겠습니다.

Next.js를 사용한 다중 테넌트

내가 사용하는 가장 일반적인 패턴은 미들웨어 기반 테넌트 해결입니다:

// middleware.ts
import { NextRequest, NextResponse } from 'next/server';

const TENANT_MAP: Record<string, string> = {
  'brand-a.com': 'brand-a',
  'brand-b.com': 'brand-b',
  'brand-c.com': 'brand-c',
};

export function middleware(request: NextRequest) {
  const hostname = request.headers.get('host') || '';
  const tenantId = TENANT_MAP[hostname] || 'default';
  
  // Pass tenant context via headers
  const response = NextResponse.next();
  response.headers.set('x-tenant-id', tenantId);
  
  // Rewrite to tenant-specific paths if needed
  const url = request.nextUrl.clone();
  url.pathname = `/${tenantId}${url.pathname}`;
  
  return NextResponse.rewrite(url);
}

그러면 페이지 컴포넌트는 테넌트별 구성을 가져옵니다:

// lib/tenant-config.ts
export async function getTenantConfig(tenantId: string) {
  // Could be from database, CMS, or config files
  return {
    theme: await fetchTheme(tenantId),
    navigation: await fetchNavigation(tenantId),
    features: await fetchFeatureFlags(tenantId),
    locale: await fetchLocaleConfig(tenantId),
  };
}

이것은 테넌트가 다른 페이지 구조, 다른 데이터 가져오기 전략, 또는 다른 제3자 통합이 필요해질 때까지 잘 작동합니다. 그 시점이 조건부 논리가 스며들기 시작할 때입니다.

공유 패키지를 가진 다중 사이트

다중 사이트의 경우, 나는 공유 패키지가 있는 모노레포를 사용합니다:

├── apps/
│   ├── brand-a/          # Next.js app
│   ├── brand-b/          # Astro app  
│   └── brand-c/          # Next.js app
├── packages/
│   ├── ui/               # Shared component library
│   ├── cms-client/       # Shared CMS integration
│   ├── analytics/        # Shared analytics wrapper
│   └── config/           # Shared TypeScript/ESLint config
├── turbo.json
└── package.json
// turbo.json
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "deploy": {
      "dependsOn": ["build"]
    }
  }
}

Turborepo(또는 Nx)는 변경된 내용만 다시 빌드하도록 종속성 그래프를 처리합니다. 브랜드 A가 새로운 기능을 얻었나요? 브랜드 A만 다시 빌드하고 배포합니다. 공유 UI 패키지가 업데이트되었나요? 이에 종속된 모든 것이 다시 빌드됩니다.

하이브리드: 다중 테넌트 CMS, 다중 사이트 프론트엔드

솔직히 이것은 대부분의 시나리오에 대한 내 최애 패턴입니다. 중앙 집중식 콘텐츠 관리와 독립적인 프론트엔드 배포를 얻습니다:

┌─────────────────────┐
│   Headless CMS      │
│  (Sanity/Contentful)│
│   Multi-tenant      │
│   content spaces    │
└──────┬──────┬───────┘
       │      │
   ┌───┘      └───┐
   ▼              ▼
┌──────┐    ┌──────┐
│Site A│    │Site B│
│Next.js│   │Astro │
└──────┘    └──────┘

콘텐츠 편집자는 하나의 로그인을 받고 모든 속성을 관리할 수 있습니다. 개발자는 독립적인 코드베이스와 배포 파이프라인을 얻습니다. 중앙 집중식 콘텐츠 관리와 독립적인 프론트엔드 배포의 장점을 모두 얻습니다.

CMS 고려사항

CMS 선택은 아키텍처 결정을 크게 제한하거나 활성화합니다.

다중 테넌트 CMS 지원

CMS 다중 테넌트 모델 다중 사이트 지원 가격 영향
Sanity 테넌트당 데이터셋 우수함(한 프로젝트에서 여러 데이터셋) 무료 계층: 2개 데이터셋; 유료는 $99/월부터
Contentful 테넌트당 스페이스 좋음(조직 수준 관리) 각 스페이스는 플랜에 계산됨; $300+/월
Strapi 단일 DB, 테넌트별 필터링 수동 구현 필요 자체 호스팅, 인프라로 확장
Hygraph 환경 및 스테이지 네이티브 다중 사이트 콘텐츠 연합 팀 플랜의 경우 $199/월부터
WordPress(헤드리스) WordPress Multisite 성숙하지만 복잡함 호스팅 비용은 사이트당 확장
Payload CMS 컬렉션 수준 다중 테넌트 성장하는 지원(v3.0+) 자체 호스팅, 오픈 소스

Sanity의 데이터셋 모델은 다중 테넌트 설정을 위해 특히 우아합니다. 각 테넌트는 자체 스키마를 가진 자체 데이터셋을 받지만, 하나의 프로젝트 아래에 있습니다. 데이터셋 간에 스키마 정의를 공유하면서 테넌트별 사용자화를 허용할 수 있습니다. 규모가 클 때(10개 이상의 테넌트), 이것은 콘텐츠 운영을 정상으로 유지합니다.

Contentful의 별도 스페이스 접근 방식은 작동하지만 빠르게 비용이 많이 듭니다. 팀 플랜의 각 스페이스는 실제 비용이 들고, $300/월 최소로 보고 있으며, 스페이스를 추가하기 시작하기 전입니다.

콘텐츠 모델링 함축

다중 테넌트를 사용하면 콘텐츠 모델이 모든 테넌트를 수용해야 합니다. 일반적으로 이는 다음을 의미합니다:

  • 모든 콘텐츠 타입의 tenant 또는 brand 필드
  • 테넌트별 검증 규칙
  • 편집자가 테넌트 콘텐츠만 볼 수 있도록 하는 신중한 권한 모델링
  • 테넌트 스코핑이 필요한 공유 콘텐츠 타입(예: "전역 설정")

다중 사이트에서 각 사이트는 자체 콘텐츠 모델을 가집니다. 사이트별로는 더 간단하지만, 추가 콘텐츠 신디케이션 계층 없이 사이트 간에 콘텐츠를 공유할 수 없습니다.

성능 및 확장성

다중 테넌트 성능 특성

다중 테넌트의 가장 큰 위험은 "시끄러운 이웃" 문제입니다. 테넌트 A가 바이러스 캠페인을 실행하고 트래픽이 10배 증가하면 모든 테넌트가 느낍니다. 완화 전략:

  • 테넌트당 엣지 캐싱: Vercel의 또는 Cloudflare의 엣지 네트워크를 사용하고 테넌트 식별자를 포함하는 캐시 키
  • 테넌트 인식 ISR: 콘텐츠가 변경된 테넌트의 페이지만 재검증
  • 테넌트당 요청률 제한: 공유 리소스를 단일 테넌트가 압도하지 않도록 보호
// next.config.js - ISR with tenant-aware revalidation
export async function generateStaticParams() {
  const tenants = await getAllTenants();
  const paths = [];
  
  for (const tenant of tenants) {
    const pages = await getTenantPages(tenant.id);
    paths.push(...pages.map(page => ({
      tenant: tenant.slug,
      slug: page.slug,
    })));
  }
  
  return paths;
}

다중 사이트 성능 특성

각 사이트는 독립적으로 확장됩니다. 그것이 좋은 소식입니다. 나쁜 소식은 N개의 배포 파이프라인, N개의 모니터링 대시보드, N개의 성능 예산 세트를 관리하고 있다는 것입니다. 20개 이상의 사이트에서 운영 오버헤드가 애플리케이션 성능이 아닌 병목이 됩니다.

2025년에 실행한 벤치마크에서 Vercel에서 대략적으로 예상할 수 있는 사항:

메트릭 다중 테넌트(1개 앱, 10개 테넌트) 다중 사이트(10개 앱)
Cold start(Edge) 20-50ms 사이트당 20-50ms
빌드 시간 8-15분(모든 테넌트) 사이트당 2-4분
증분 빌드 30-90초 사이트당 30-90초
인스턴스당 메모리 256-512MB 공유 각각 256-512MB
월별 Vercel 비용(Pro) ~$20 ~$200($20 × 10)

그 비용 차이는 상당합니다. Vercel Pro 단일 플랜에서 다중 테넌트는 $20/월 대 Multi-Site는 Enterprise가 필요하거나 창의적인 프로젝트 조직이 필요합니다.

비용 분석

12개월에 걸쳐 10개 사이트의 포트폴리오에 대한 실제 수치를 살펴보겠습니다.

다중 테넌트 비용 추정

항목 월별 비용 연간 비용
Vercel Pro(1개 프로젝트) $20 $240
Sanity Team(1개 프로젝트, 10개 데이터셋) $99 $1,188
개발(초기 빌드) -- $40,000-60,000
유지보수(지속) $2,000 $24,000
총 1년 -- $65,428-$85,428

다중 사이트 비용 추정

항목 월별 비용 연간 비용
Vercel Pro(10개 프로젝트) $200 $2,400
Sanity Team(10개 프로젝트) $990 $11,880
개발(초기 빌드, 공유 패키지) -- $50,000-80,000
유지보수(지속, 10개 사이트) $4,000 $48,000
총 1년 -- $112,280-$142,280

다중 테넌트는 대략 40-60% 더 저렴하며, 주로 감소된 유지보수 부담 때문입니다. 하지만 다중 테넌트 복잡성으로 인해 더 많은 버그, 느린 기능 개발, 또는 나중의 고통스러운 마이그레이션이 발생하면 이 숫자는 뒤집힙니다.

특정 상황에 대한 더 정확한 추정을 원하신가요? 발견 프로세스 동안 아키텍처 비용을 자세히 분석합니다.

마이그레이션 전략

때때로 한 가지 접근 방식으로 시작하고 다른 것으로 전환해야 합니다. 모든 것을 태우지 않고 이것을 하는 방법은 다음과 같습니다.

다중 테넌트 → 다중 사이트

이것이 더 일반적인 마이그레이션 방향입니다. 필요한 신호:

  • 테넌트별 코드가 코드베이스의 30%를 초과함
  • 배포가 교차 테넌트 회귀 테스트로 인해 차단됨
  • 팀이 서로의 변경 사항을 밟고 있음

전략:

  1. 먼저 공유 코드를 패키지로 추출(UI 컴포넌트, 유틸리티, CMS 클라이언트)
  2. 기존 앱 주위에 모노레포 구조 생성
  3. 가장 다양한 테넌트에 대한 앱 포크
  4. 다른 테넌트를 자체 앱으로 점진적으로 이동
  5. 각 앱이 독립적이 될 때 테넌트 전환 논리 삭제

다중 사이트 → 다중 테넌트

덜 일반적이지만 발생하며, 일반적으로 회사가 여러 브랜드를 인수하고 운영을 통합하려는 경우입니다.

  1. 모든 사이트를 공유 패턴에 대해 감사(예상보다 더 많이 찾을 것)
  2. 최고의 구현에서 공유 컴포넌트 라이브러리 구축
  3. 가장 간단한 사이트로 다중 테넌트 앱 생성
  4. 각 단계에서 패리티를 검증하면서 한 번에 하나의 사이트 마이그레이션
  5. 테넌트가 라이브되면 개별 앱 폐기

두 마이그레이션 모두 중단적입니다. 3-6개월을 예산에 할당하고 상당한 테스트 노력을 하세요. 이는 정확히 초기 결정을 올바르게 하는 것이 중요한 이유입니다 - 단순한 아키텍처 선택이 아니라 약속입니다.

이 결정에 직면하고 있으며 이것을 시도해본 사람과 이야기하고 싶다면, 연락해주세요.

FAQ

다중 테넌트 아키텍처와 다중 사이트 아키텍처의 차이점은 무엇입니까?

다중 테넌트는 하나의 애플리케이션 인스턴스를 사용하여 여러 브랜드 또는 클라이언트를 제공하며, 테넌트 격리는 애플리케이션 계층에서 처리됩니다. 다중 사이트는 각 사이트에 대해 별도의 애플리케이션 인스턴스를 배포하며, 모노레포와 컴포넌트 라이브러리를 통해 코드를 공유할 수 있습니다. 핵심 구별은 하나의 애플리케이션을 실행하고 있는지, 아니면 많은 애플리케이션을 실행하고 있는지입니다.

다중 테넌트 CMS를 다중 사이트 프론트엔드와 함께 사용할 수 있습니까?

절대로, 그리고 종종 최고의 접근 방식입니다. 여러 데이터셋이 있는 Sanity 같은 헤드리스 CMS는 중앙 집중식 콘텐츠 관리를 제공하는 반면, 별도의 프론트엔드 배포는 각 사이트에 기술 선택, 배포 일정, 성능 확장 측면에서 독립성을 제공합니다. 이 하이브리드 패턴은 사이트가 콘텐츠 구조를 공유하지만 다른 사용자 경험이 필요할 때 특히 잘 작동합니다.

다중 테넌트 아키텍처는 SEO에 어떤 영향을 미칩니까?

다중 테넌트 앱은 도메인 또는 서브도메인을 기반으로 다른 콘텐츠를 제공하며, 검색 엔진은 적절한 정규 URL, 테넌트별 고유 메타데이터, 별도의 사이트맵을 구현하는 한 이를 잘 처리합니다. 위험은 테넌트 간의 우발적인 콘텐츠 중복입니다 - 사이트맵 생성과 robots.txt가 테넌트를 인식하도록 하세요. SEO 관점에서 검색 엔진은 사이트가 코드베이스를 공유하는지 상관없습니다. 그들이 상관하는 것은 받는 콘텐츠와 마크업입니다.

다중 테넌트가 다중 사이트보다 저렴합니까?

일반적으로 그렇고, 종종 호스팅 및 유지보수 비용의 40-60%입니다. 하나의 배포, 하나의 모니터링 설정, 하나의 인프라 세트에 대해 비용을 지불하고 있습니다. 그러나 테넌트가 크게 분기하면 다중 테넌트가 개발 시간에서 더 비용이 많이 들 수 있습니다. 테넌트별 논리를 관리하는 복잡성이 비선형적으로 증가하기 때문입니다. 손익분기점은 사이트가 실제로 얼마나 유사한지에 따라 달라집니다.

다중 테넌트 앱에서 공유 인증을 처리하려면 어떻게 해야 합니까?

중앙 집중식 인증 공급자(Auth0, Clerk, 또는 NextAuth.js)를 테넌트 인식 세션 관리로 사용하세요. 인증 토큰은 테넌트 컨텍스트를 포함해야 하며, 미들웨어는 인증된 사용자가 요청된 테넌트에 액세스할 수 있는지 검증해야 합니다. 데이터베이스의 행 수준 보안(Supabase와 Neon 모두 지원)은 교차 테넌트 데이터 유출로부터 보호할 수 있는 두 번째 계층을 추가합니다.

다중 테넌트 앱이 처리할 수 있는 최대 테넌트 수는 얼마입니까?

하드 제한은 없지만 실제 제한이 나타납니다. Vercel의 Next.js ISR을 사용하면 50개 이상의 테넌트를 효과적으로 처리하는 다중 테넌트 앱을 봤습니다. 100개 이상의 테넌트를 넘어서면, 모든 페이지를 미리 생성하는 대신 요청 시 ISR을 보고 싶을 것이고, 정교한 캐싱 전략이 필요합니다. Shopify 같은 SaaS 플랫폼은 효과적으로 수천 개의 테넌트를 실행하지만, 그 인프라에 몇 년간 투자했습니다.

다중 사이트 아키텍처를 위해 모노레포를 사용해야 합니까?

거의 항상 그렇습니다. Turborepo 또는 Nx가 있는 모노레포는 다중 테넌트의 코드 공유 이점(공유 컴포넌트, 유틸리티, 구성)을 배포 독립성의 장점과 함께 제공합니다. 핵심은 공유 패키지를 잘 정의하고 버전을 관리하는 것입니다. 모노레포 없이, 당신은 저장소 간에 코드를 복사하고 즉시 다양해지며 수개월 내에 유지보수 악몽이 되는 코드를 자르고 붙이게 됩니다.