들어가며: "업로드했는데 왜 안 뜨죠?"

팟캐스트 크리에이터라면 한 번쯤 겪어봤을 상황입니다. 에피소드를 올렸는데 몇 시간째 안 보이고, 청취자한테 먼저 연락이 옵니다. "이번 화 안 올라왔어요?"

2026년 6월 24일, Spotify에서 실제로 벌어진 일입니다. 영상 팟캐스트 에피소드가 몇 시간씩 발행 지연됐고, 일부 크리에이터는 안 올라온 줄 알고 다시 업로드했습니다. 그게 부하를 더 키웠죠. 시스템이 "접수됐고 대기 중"이라고 알려주지 않았으니까요. 이건 크리에이터 잘못이 아니라 플랫폼 책임입니다.

이 글은 단순 장애 공지가 아니라, 미디어 처리 파이프라인을 운영하는 팀이라면 반드시 봐야 할 아키텍처 교훈입니다. 근거자료는 Spotify 엔지니어링 블로그에서 확인할 수 있어요.

Server rack with transcoding queue backlog visualization for podcast publishing pipeline Development Concept Image

사고의 4가지 원인: 하나가 아니라 '겹침'이 문제

장애는 단일 원인이 아니라 4가지가 동시에 터진 겹합입니다. 이게 실무에서 가장 무서운 패턴이에요.

1. 여유 용량(headroom) 부족

평상시 트래픽은 스케일링으로 커버됐지만, **대량 신규 콘텐츠 급증(burst)**을 받아낼 여유가 없었습니다. 오토스케일링이 있어도 '최대치 근처'에서 돌고 있으면 급증에 취약하죠.

2. 배치 작업과의 충돌

기존 에피소드를 재처리하는 정기 배치 잡이 돌고 있었습니다. 낮에는 문제 없어 보였지만, 신규 제출 급증과 겹치자 용량을 잠식했습니다.

3. 품질 개선이 곧 비용 증가

"더 좋은 화질을 더 낮은 비트레이트로" 개선을 배포했는데, 에피소드당 처리 시간과 연산량이 증가했습니다. 용량 계획에 이 증가분이 반영되지 않았어요.

4. 스케줄링 버그로 10% 유휴

더 강력한 하드웨어로 마이그레이션한 뒤, 리소스 스케줄링 버그 때문에 가용 컴퓨트를 약 10% 덜 쓰고 있었습니다. 돈은 내는데 성능은 못 뽑는 상태였던 거죠.

# 사고 재현 시뮬레이션 (개념 예시)
# 실제 Spotify 코드가 아니라, 용량 계획 실패 패턴을 보여주는 의사 코드입니다.

class TranscodingCluster:
    def __init__(self, total_capacity):
        self.total_capacity = total_capacity  # 초당 처리 가능한 에피소드 수
        self.batch_job_load = 0
        self.new_content_load = 0
        self.scheduling_efficiency = 1.0  # 버그로 0.9까지 떨어짐

    def effective_capacity(self):
        # 스케줄링 버그 반영: 실효 용량이 줄어든다
        return self.total_capacity * self.scheduling_efficiency

    def is_overloaded(self):
        total_load = self.batch_job_load + self.new_content_load
        return total_load > self.effective_capacity()

# 사고 당시 상황
cluster = TranscodingCluster(total_capacity=100)
cluster.batch_job_load = 30        # 배치 잡이 잡아먹는 용량
cluster.new_content_load = 75      # 신규 영상 급증
cluster.scheduling_efficiency = 0.9  # 버그로 10% 손실

print(cluster.is_overloaded())  # True -> 큐 적체 시작

핵심은 이거예요. "평균 트래픽 기준으로 여유 있다"는 착각이 사고를 부릅니다. 피크 + 배치 + 버그가 겹치는 순간이 진짜 리스크입니다.

Cloud infrastructure dashboard showing capacity scaling and batch job scheduling for media processing Technical Structure Concept

타임라인이 말해주는 진짜 문제: '4시간의 침묵'

사고 대응에서 가장 뼈아픈 부분은 기술이 아니라 감지 지연이었습니다.

시각 (UTC)사건
13:30내부 모니터링 초기 알림 발생 (광범위 용량 문제로 인식 못 함)
15:00영상 팟캐스트 급증으로 트랜스코딩 최대치 근접
16:35배치 잡 중단으로 용량 확보
17:31크리에이터 첫 이슈 리포트 접수
17:34자동 알림이 큐 임계치 초과 확인, 대응 개시
20:49리소스 활용 개선 소프트웨어 픽스 배포
01:02 (6/25)모든 큐 정상화

13:30에 첫 알림이 떴는데, 공식 대응은 17:34에 시작됐습니다. 약 4시간의 갭. 그 사이 크리에이터는 자기 청취자한테서 먼저 문제를 통보받았죠. 이게 진짜 실패입니다.

재발 방지 조치

  • 트랜스코딩 용량 약 67% 증설
  • 스케줄링 버그 픽스
  • 용량 한계 근접 시 더 이른 알림을 위한 모니터링 개선

이 기술의 한계와 주의사항

  • 용량 증설은 근본 해결이 아닙니다. 67% 늘려도 사용자 급증이 그 이상이면 다시 터집니다. 진짜 해법은 백프레셔와 우선순위 큐입니다.
  • 오토스케일링은 '여유'가 아니라 '반응'입니다. 스케일 아웃에 걸리는 시간 동안은 큐가 쌓입니다. 사전 프로비저닝과 배치 스케줄링 분리가 필수예요.
  • 품질 개선 배포는 반드시 용량 재계산과 함께. 화질 개선 커밋 하나가 처리 시간을 늘리면, 그게 곧 장애 씨앗이 됩니다.

Data analysis chart of medium and low priority queue build-up during podcast video incident System Abstract Visual

정리: 팀에 가져다 쓸 3가지 체크리스트

  1. "평균"이 아니라 "피크 + 배치 + 장애 복구"로 용량을 계획하세요. 정상 상태 트래픽만 보면 반드시 터집니다.
  2. 실시간 크리에이터 콘텐츠는 항상 배치 작업보다 우선순위를 높게. 백그라운드 재처리 잡이 신규 발행을 막으면 안 됩니다.
  3. 모니터링 알림과 대응 절차를 연결하세요. 알림만 뜨고 아무도 '이건 큰 문제다'라고 판단 못 하면 4시간이 그냥 날아갑니다.

다음 단계 학습 방향

  • SRE 관점: Google SRE Book의 'Handling Overload' 챕터, 백프레셔·부하 분산 패턴
  • 아키텍처 관점: 우선순위 큐 설계, 배치/실시간 워크로드 격리
  • 관측성 관점: 큐 깊이(queue depth) 기반 SLI 설계

국내 개발 생태계에서의 적용 맥락

국내 미디어·커머스 플랫폼에서도 "업로드했는데 반영이 안 된다"는 CS가 장애의 첫 신호인 경우가 많습니다. 특히 대규모 프로모션·라이브 커머스 시점엔 신규 콘텐츠 제출이 폭증하죠. 이때 배치성 통계·재색인 잡이 같이 돌고 있다면 이번 사고와 똑같은 패턴이 재현됩니다. 배치 잡 스케줄을 프로모션 캘린더와 분리하는 것만으로도 절반은 예방됩니다.

함께 보면 좋은 글

본 콘텐츠는 신뢰할 수 있는 출처를 바탕으로 AI 도구를 활용하여 초안이 작성되었으며, 편집자의 검토를 거쳐 발행되었습니다. 전문가의 조언을 대체하지 않습니다.