본문으로 건너뛰기

확장 — 1만 명 · 10만 명

갱신일 2026-08-11 · 기준: CA 실측 형상 + SA §10 + ADR 0006 이 문서가 갖는 것: 부하 모델, 무엇이 어떤 순서로 부러지는가, 언제 무엇을 하는가. 네 축의 상세는 아래 문서들이 갖는다.

⚠︎ 이건 계획이지 현황이 아니다. 지금 서 있는 것은 현재 판 아키텍처 문서들이 갖는다. 여기 적힌 수는 전부 추정이고, 실측이 들어오면 갈아엎는다.

문서갖는 것
IA정보 구조화자·그래프·외부 클라이언트가 화면에 만드는 변화
AA애플리케이션서비스 다섯 · 의존 방향 · 소유권 · 파이프라인
SA시스템경계 열하나 · 인증 · 런타임 흐름 · 새 천장
CA클라우드ECS 형상 · GPU 운용 · 오디오 경로 · 관측 · AWS 운영 · 비용
데이터저장소 다섯의 소유권 · 원본/파생 경계 · 무엇을 지워도 되나 · 재생성 경로
ERD물리 스키마 — 테이블·칼럼·FK·제약 · 삭제 사슬 · 마이그레이션 순서
온톨로지그래프 노드·관계 · 근거 규칙 · 가능해지는 기능
실시간 경로오디오·채팅 스트림 개선 · 회의 중 에이전트

1. 확장과 함께 들어오는 것 다섯

규모만 커지는 게 아니다. 제품이 같이 바뀐다. 둘을 한 문서에서 보는 이유는 서로를 제약하기 때문이다.

무엇아키텍처에 무엇을 요구하나
Soniox 실시간 STT공급자 교체. 오디오는 서버를 지난다(§5) — egress와 릴레이 부하가 그대로 남는다
pyannote 화자 분리 (배치)GPU · 배치 · 오디오 보관 — 지금 아키텍처에 없는 세 가지가 한꺼번에. 실시간 대안이 없어 확정이다
voice print생체정보 취급 · 별도 저장·삭제 경로
Neo4j graph RAG네 번째 저장소 · 회의를 넘는 맥락 · 파생 규칙
MCP · CLI두 번째 public edge · 토큰 인증 · 호출 상한
회의 중 에이전트전사 스트림의 새 소비자 · LLM 부하가 버스트에서 지속으로 · 실시간 경로

2. 부하 모델 — 먼저 가정을 박는다

사용자 수는 부하가 아니다. 동시에 진행 중인 회의 수가 부하다. 아래를 바꾸면 이 문서의 모든 수가 따라 바뀐다.

가정
DAU / 등록 사용자20%
DAU 1인당 회의 참여0.5건/일
회의당 참가자4명
평균 회의 길이45분
업무일월 22일
피크 집중도하루 회의의 25%가 피크 1시간에 시작
등록 1만등록 10만
DAU2,00020,000
회의250건/일 · 5,500건/월2,500건/일 · 55,000건/월
전사 시간4,125시간/월41,250시간/월
피크 동시 회의50건500건
피크 동시 WebSocket2002,000
정각 종료 버스트30건 동시300건 동시

마지막 줄이 제일 중요하다. 회의는 정각에 끝난다. 부하가 고르게 퍼지지 않고 :00과 :30에 벽처럼 선다. 그리고 이제 그 벽 뒤에 GPU 배치가 있다.

3. 회의 종료가 한 방에서 다섯 단계가 된다

이게 이번 변화의 본체다. 지금은 종료 → 요약 한 방이고, 앞으로는 이렇다.

따라오는 요구어디서 다루나
오디오를 저장해야 한다 (지금은 안 한다)CA §8
GPU를 파산하지 않고 운용해야 한다CA §6
단계별 실패·건너뛰기·재시도AA §3
대기 시간이 화면에 드러난다IA §5
5단계를 관통하는 트레이스CA §10

4. 천장이 걸리는 순서

순서가 중요하다. 뒤엣것을 먼저 고쳐도 앞엣것에서 막힌다.

#천장내용
ai 1GB + 동시 실행 상한 없음정각 버스트에 OOM. 1만 명 문제가 아니라 지금 문제다
t4g 크레딧 소진동시 50회의는 버스트가 아니라 지속 부하다. 크레딧이 마르면 small 0.4 vCPU · micro 0.2 vCPU로 산다. 에러 없이 느려지기만 한다
STOMP 내부 브로커enableSimpleBroker 는 JVM 안이다. 2대로 늘리면 팬아웃이 조용히 반쪽 난다. 수평 확장·무중단 배포의 유일한 전제
RDS db.t4g.micro Single-AZ1GB 안에서 OLTP와 pgvector가 싸운다. deletion_protection=false·skip_final_snapshot=true 는 사고 한 방에 끝나는 설정이다
server 경유 오디오egress·CPU·대역폭이 한 대에 몰린다 (§5)
GPU 배치 처리량새로 생기는 천장. 정각 300건 동시
전사 쓰기량 · 그래프 순회 · MCP 폭주SA §10

④ 는 오늘 코드에 이미 있는 것이고, ⑤⑦ 은 새로 들어오는 것이다.

5. 결정 둘 — 오디오는 서버를 지나고, 화자 분리는 배치로 한다

앞선 판에서 미확인으로 두었던 두 가지가 결정됐다. 둘 다 비용이 늘어나는 쪽이다. 그래서 이 문서의 나머지가 그 위에 다시 선다.

결정대안이었던 것왜 이쪽
오디오는 브라우저 → 서버 → Soniox브라우저 → Soniox 직결아래
화자 분리는 pyannote 배치Soniox 실시간 화자 분리실시간 품질이 쓸 만하지 않다

오디오가 서버를 지나서 잃는 것

전사 1시간당 egress 230MB — 측정값이다. 이게 그대로 남는다.

전사 시간/월egress/월비용/월 (추정)
지금717시간165GB약 $8
등록 1만4,125시간0.95TB약 $110
등록 10만41,250시간9.5TB$1,190

돈보다 큰 건 대역폭과 CPU가 백엔드에 몰린다는 것이다. 동시 500 스트림이면 상시 32MB/s를 릴레이하면서 STOMP 팬아웃과 REST를 같이 진다. 그래서 전사 릴레이 분리가 10만 구간에서 선택이 아니라 필수가 된다.

대신 얻는 것 — 이게 공짜가 아니다

얻는 것왜 중요한가
전사 위조가 불가능해진다서버가 Soniox 응답을 직접 받는다. 클라이언트가 보낸 텍스트를 믿을 필요가 없다
오디오 보관이 단순해진다릴레이하면서 서버가 S3에 쓴다. 브라우저 이중 업로드·presigned 발급이 사라진다
브라우저가 단순해진다Soniox 단기 토큰 발급 경로가 통째로 없다
사용량 계측·차단이 경로 위에 있다한도 초과를 실시간으로 끊을 수 있다

전사 위조 문제가 사라진 게 제일 크다. 직결 안에서는 이걸 막으려면 배치 재전사(전사 원가 2배)까지 갔어야 했다. 그 비용이 없어졌으므로 egress $1,190과 배치 재전사 비용을 맞바꾼 셈이고, 회의록 무결성이 중요한 제품이라면 나쁜 교환이 아니다.

화자 분리를 배치로 하면

pyannote가 확정이므로 GPU는 조건부가 아니라 상수다. CA §6의 운용 규칙(평소 0대 · Spot · 평탄화 우선)이 그만큼 더 중요해진다 — 이제 이게 인프라 최대 항목이다.

대신 배치 전사는 하지 않는다. 위조 문제가 없으므로 실시간 전사가 곧 정본이고, 오디오는 화자 분리에만 쓴다.

6. 등록 1만 명 — 무엇을 하는가

순서대로. 위에서부터 하지 않으면 아래가 의미 없다.

#무엇왜 지금
1RDS Multi-AZ + deletion_protection + 최종 스냅숏사용자 데이터가 실재한다
2ai 분석에 동시 실행 상한 + 외부 큐정각 버스트에 1GB가 OOM 난다
3STOMP 외부 브로커 릴레이모든 수평 확장·무중단 배포의 전제
4APP-189 (재기동 시 전역 세션 중단) 해결3번을 해도 이게 남으면 2대째가 1대째를 끊는다
5ECS Fargate로 이전 + ALB · IaC 같이서비스가 다섯이면 손으로 굴리는 EC2가 다섯 배가 된다. 클러스터를 콘솔로 만들면 그때부터 늦다
6ai 분리·증설PgSingleFlight 덕에 지금도 수평 확장이 된다. 막는 건 크기뿐
7오디오 S3 보관 + speech 서비스 + 파이프라인 5단계화자 분리의 전제. 서버가 릴레이하면서 S3에 쓴다
8voice print — 생체정보 취급 설계나중에 얹을 수 없다. 스키마·키·삭제 경로를 처음부터
9Neo4j + 그래프 투영파생 규칙과 재생성 경로를 처음부터 박는다 — 온톨로지
10mcp 서비스 + 토큰·범위·상한두 번째 public edge
11server↔ai 인증 · access token 갱신 경로인스턴스가 늘면 보안그룹만으로 안 된다
12관측 유료 전환 + 파이프라인 트레이스Fargate는 host가 없어 push 모델이다. 5단계를 로그로 디버깅하는 건 불가능하다
12.5staging 환경5단계 파이프라인을 prod에서 처음 돌리면 안 된다
13워치독 스케줄러 리더 선출2대가 되면 스케줄러가 둘 다 돈다
14전사 릴레이 부하 실측오디오가 서버를 지나므로 §7의 분리 시점을 수치로 잡아야 한다
15오디오 Float32 → Int16몇 줄로 대역폭 절반. 규모와 무관하게 이득 — 실시간 §7
16전사 세션 재개 + 공유 챗봇 관전자 STOMP배포·장애가 한 코드로 처리되고 폴링이 사라진다

1~4는 성능이 아니라 정확성·생존 문제다. 5부터가 용량이고, 7부터가 새 기능이다.

7. 등록 10만 명 — 그다음

#무엇
15정각 버스트 평탄화 (지연 + 지터)제일 싸고 효과가 크다. 정각 300건 → 5분에 300건이면 필요한 GPU가 한 자릿수로 떨어진다
16전사 릴레이를 별도 서비스로 분리동시 500 스트림 × 32MB/s 상시 릴레이가 REST·STOMP와 한 프로세스에 있으면 한쪽 스파이크가 다른 쪽을 죽인다. heymoa-transcription-worker 저장소가 이미 있다
17읽기 복제본 + 세그먼트 쓰기 배치화
18벡터를 전용 스토어로pgvector를 OLTP와 같이 두는 건 1만까지
19organization 계층 (결제·SSO·감사)IA §2
20project 경로 · 검색 1급 화면워크스페이스당 노트 1,000건이 조건
21알림 폴링 → push폴링이 그 자체로 부하가 된다
22그래프 순회 깊이·팬아웃 상한깊이·팬아웃 상한 → 온톨로지 §7
23LLM·STT 원가를 제품 정책으로요금제·회의 길이 상한·재분석 정책
24회의 중 에이전트 (C3 충돌만)그래프가 선 다음. LLM 호출이 요약의 6~20배가 되므로 게이트 정밀도가 곧 원가 — 실시간 §4

8. 비용

인프라는 문제가 아니다. 외부 API가 문제다. 상세는 CA §16.

등록 1만 (월)등록 10만 (월)
인프라 전체 (GPU 포함, 추정)약 $1,100약 $5,000~7,000
— 그중 GPU 배치$150~300$1,500~3,000
egress (오디오가 서버를 지난다)$110$1,190
Soniox 전사4,125시간41,250시간
OpenAI 요약·채팅5,500건 + 채팅55,000건 + 채팅

아래 두 줄에 단가를 못 넣었다. 모른다. 시간당 $0.2만 돼도 10만에서 전사만 월 $8,000 이고, 위 인프라 전부보다 크다. 배치 재전사는 하지 않으므로 이 줄이 두 배가 되지는 않는다(§5).

결론은 인프라 결정이 아니라 제품 결정이다.

9. 설계 전제

  • 동시 회의 수로 사이징한다. 등록 사용자 수로 하지 않는다. §2만 고치면 나머지가 따라온다.
  • 정각을 부하의 기본 단위로 본다. 평균 처리량으로 사이징하면 매시 정각마다 무너진다.
  • 버스트는 인스턴스보다 평탄화로 먼저 줄인다. 사용자는 "1분 뒤"와 "3분 뒤"를 구분하지 못하고, 스팟 시장은 구분한다.
  • 정본은 Postgres 다. 그래프·벡터는 지우고 다시 만든다. 오디오만 예외이고 그래서 짧게 산다.
  • 생체정보는 처음부터 따로 설계한다. 나중에 분리할 수 없다.
  • 외부 API 원가를 아키텍처 제약으로 취급한다.

10. 미확인 — 확인 순서대로

§5의 결정 둘이 앞선 판의 1·2번을 지웠다. 남은 것.

#무엇무엇이 걸려 있나
1Soniox·OpenAI 실계약 단가§8의 빈 두 줄. 원가가 제품 정책을 정한다
2pyannote 처리 시간 · GPU 필요 여부speech 인스턴스 수·타입·타임아웃. CPU로 되면 훨씬 싸다
3전사 릴레이 실측 부하스트림당 서버 CPU·메모리. §7 16번(분리)의 시점을 정한다
4Spot 확보 가능성 (서울 g5·g6)안 되면 GPU 원가가 3배
5voice print 매칭 정확도·임계값틀린 이름 vs 이름 없음의 교환비
6현재 사용자 수 대비 전사 시간월 165GB ⇒ 약 717시간/월. 활성 사용자 수로 나누면 §2가 실측이 된다
7Neo4j 재생성 소요"파생" 규칙이 실현 가능한지
8결정·액션 아이템 추출 정확도나쁘면 파이프라인에 사람 확인 단계가 하나 더 붙는다
9MCP로 내보낼 범위보안·원가 양쪽

1과 2가 원가를 지배한다. 나머지는 만들면서 나온다.