SiliconValley_survivor

SiliconValley_survivor

Mobile Design Netflix, 오프라인 다운로드

다운로드 완료와 오프라인 재생 가능은 다르며, 미디어와 라이선스와 전송 복구를 함께 설계하는 모바일 경험

SiliconValley_survivor's avatar
SiliconValley_survivor
Sep 18, 2026
∙ Paid

Introduction & Requirements

사용자가 비행기를 타기 전에 드라마 세 편을 다운로드합니다.

앱에는 모두 다운로드 완료로 표시되어 있습니다. 사용자는 기내에서 비행기 모드를 켜고 첫 번째 영상을 선택합니다. 그런데 재생 화면에는 인터넷에 연결해 권한을 갱신하라는 안내가 나옵니다.

영상 파일은 휴대폰에 있는데 왜 재생할 수 없을까요.

이 문제를 이해하려면 다운로드한 미디어와 그 미디어를 사용할 수 있는 권한을 구분해야 합니다. 앱이 영상 데이터를 모두 받았다는 사실은 현재 기기에서 오프라인 재생에 필요한 모든 조건이 준비되었다는 뜻이 아닙니다.

다른 상황도 있습니다. 다운로드가 90퍼센트 진행된 상태에서 사용자가 앱을 닫았습니다. 다시 실행하니 진행률은 0퍼센트입니다. 실제 파일이 사라진 것인지, 다운로드 작업과 로컬 파일을 연결하던 정보만 사라진 것인지부터 확인해야 합니다.

사용자에게는 다운로드 버튼 하나이지만 앱은 서로 다른 수명을 가진 상태를 함께 관리합니다.

사용자가 저장하기를 원하는 상태
                  |
실제로 단말에 저장된 미디어
                  |
운영체제가 실행 중인 전송 작업
                  |
DRM이 인정하는 오프라인 재생 권한
                  |
현재 사용할 수 있는 저장 공간

Netflix의 공개 도움말에서는 다운로드한 콘텐츠를 해당 기기에서 오프라인으로 시청할 수 있으며, 모든 콘텐츠가 다운로드 가능한 것은 아니라고 설명합니다. 다운로드에는 만료가 있고, 일부 콘텐츠에는 다시 다운로드할 수 있는 횟수 제한도 있습니다. 오프라인으로 다운로드에 접근하려면 계정에 로그인된 상태를 유지해야 합니다. [Netflix 도움말 센터](https://help.netflix.com/en/node/54816)

이 글에서는 이러한 제품 경험을 만족시키는 모바일 시스템을 설계합니다. 아래의 컴포넌트 구성, 저장 스키마, API와 실행 정책은 제안하는 설계이며 Netflix 앱의 비공개 내부 구현을 설명하는 것이 아닙니다.

앞선 스트리밍 설계에서는 받은 내용, 화면에 표시한 내용, 저장을 완료한 내용을 구분했습니다. 다운로드에서도 같은 판단이 필요합니다. 네트워크에서 받은 바이트, 복구할 수 있는 저장 상태, 실제 재생 가능한 상태를 하나의 완료 플래그로 취급하지 않겠습니다. 붙여넣은 마크다운(1)


Functional Requirements

  • 사용자는 다운로드 가능한 영화나 에피소드를 선택하고, 저장할 화질과 제공되는 음성 및 자막을 선택할 수 있습니다.

  • 사용자는 다운로드를 시작하고 일시 중지하거나 삭제할 수 있으며, 여러 작업의 진행 상태와 대기 이유를 확인할 수 있습니다.

  • 앱은 네트워크 중단이나 프로세스 재시작 이후 이미 저장한 데이터를 확인하고, 재사용 가능한 부분을 유지하면서 작업을 계속할 수 있습니다.

  • 사용자는 필요한 미디어와 유효한 오프라인 라이선스가 준비된 콘텐츠를 네트워크 연결 없이 재생할 수 있습니다.

  • 앱은 미디어 저장 완료와 재생 권한 준비 상태를 구분하고, 권한 갱신이 필요하면 콘텐츠를 모두 다시 받아야 하는지와 별도로 안내합니다.

  • 앱은 저장 공간을 확인하고 다운로드 예산을 관리하며, 사용자가 직접 보관한 콘텐츠와 자동으로 받은 콘텐츠에 다른 삭제 정책을 적용할 수 있습니다.

  • 앱은 Wi-Fi 전용 설정, 모바일 데이터 사용 동의, 배터리 상태와 운영체제 실행 제약에 따라 작업을 시작하거나 대기시킬 수 있습니다.

  • 사용자가 계정을 전환하거나 콘텐츠를 삭제하면, 이전 작업의 늦은 응답 때문에 삭제된 다운로드가 다시 활성화되지 않아야 합니다.


Target & Scale, Traffic & Capacity Assumptions

단말 한 대의 조건부터 정합니다

대상은 iOS와 Android 모바일 앱입니다.

사용자는 여러 영상을 대기열에 넣을 수 있지만, 초기 정책에서는 동시에 실행하는 콘텐츠 다운로드 수를 제한하겠습니다. 한 콘텐츠 내부의 병렬 전송 수는 사용하는 미디어 프레임워크의 동작과 단말 측정 결과를 함께 고려합니다.

기본 사용 경험은 필요한 미디어를 모두 저장한 뒤 오프라인으로 재생하는 방식입니다. 다운로드 중인 영상을 온라인으로 재생하는 기능까지 동시에 구현하면 네트워크 읽기와 로컬 읽기의 우선순위가 추가되므로 별도 확장으로 둡니다.

이후 등장하는 사용자 수, 처리량과 성능 목표는 실제 Netflix 수치가 아니라 설계를 위한 가정입니다.

다운로드 접수량과 미디어 전송량은 다른 규모입니다

일간 활성 사용자를 1억 명으로 가정하겠습니다. 이 가운데 10퍼센트가 하루에 콘텐츠 하나를 다운로드하면 하루 다운로드 시작은 1천만 건입니다.

평균 시작 요청률은 초당 약 116건입니다. 피크를 평균의 8배로 두면 초당 약 926건입니다.

이 값은 다운로드 가능 여부 확인과 이용 권한 발급을 담당하는 서버의 부하를 설명합니다. 영상 데이터를 전달하는 부하는 별도로 계산해야 합니다.

평균 다운로드 크기를 1.5GB로 두면 하루 미디어 전달량은 1천만 × 1.5GB로 1,500만 GB입니다. 십진 단위를 사용하면 약 15PB입니다. 하루 동안 균등하게 전달한다고 계산한 평균 전송 대역폭은 약 1.39Tbps입니다.

여기에는 재시도, 추가 음성 트랙, 프로토콜 부가 정보는 포함하지 않았습니다.

이 차이 때문에 일반 API 서버가 모든 영상 바이트를 대신 받아서 모바일에 전달하도록 만들지 않겠습니다. API는 권한과 다운로드 계획을 처리하고, 미디어 데이터는 CDN에서 단말로 직접 전달하는 경로를 선택합니다.

다운로드 작업 수와 연결 수를 같게 계산하지 않습니다

다운로드 하나가 평균 10분 동안 활성 상태라고 가정하면 평균 활성 작업 수는 다음과 같이 계산할 수 있습니다.

평균 활성 다운로드 작업

초당 약 116건 시작
x
평균 600초 활성

약 6만 9천 건

이것은 활성 다운로드 작업 수이지 TCP 연결 수가 아닙니다. 콘텐츠 하나가 여러 HTTP 요청을 만들 수 있고, 연결을 재사용하거나 중간에 대기할 수도 있습니다.

따라서 서버에서는 다운로드 접수량, CDN 요청률과 대역폭을 따로 측정합니다. 단말에서는 콘텐츠 작업 수와 실제 동시 전송 수를 따로 제한합니다.

화질 선택은 다운로드 시간과 저장 공간을 함께 바꿉니다

이 글에서 계속 사용할 예시는 45분짜리 에피소드입니다.

비디오 평균 비트레이트를 초당 2.5Mb, 음성을 초당 128Kb로 가정하겠습니다. 단순 계산으로 필요한 미디어 데이터는 약 887MB입니다.

예상 미디어 크기

비디오와 음성의 평균 비트레이트 합계
x
재생 시간
/
8

약 887MB

실제 파일 크기는 가변 비트레이트, 자막, 컨테이너와 선택한 트랙에 따라 달라집니다. 이 값은 사용자가 선택하기 전에 보여주는 초기 예상치입니다.

실효 전송 속도를 초당 20Mb로 가정하면 순수 전송 시간은 약 5.9분입니다. 네트워크 대기, 라이선스 교환, 저장소 처리와 재시도 시간은 별도입니다.

여기서 다운로드 두 개를 동시에 시작한다고 각각 5.9분 안에 끝난다고 가정하면 안 됩니다. 같은 네트워크 용량을 나누어 사용하면 첫 번째 영상이 완료되는 시점이 오히려 늦어질 수 있습니다.

출발 전에 한 편이라도 준비하려는 사용자에게는 모든 콘텐츠를 동시에 진행하는 것보다 선택한 한 편을 먼저 완료하는 정책이 더 유용할 수 있습니다.


Non-Functional Requirements

아래 목표는 제안하는 제품의 초기 시험 기준입니다.

  • 다운로드 선택부터 로컬 대기 상태 표시까지 p95 100ms 이내를 목표로 합니다. 서버가 권한을 승인하기 전에는 다운로드 가능 상태를 확정하지 않습니다.

  • 필요한 미디어와 오프라인 라이선스가 준비된 시험 조건에서 재생 선택부터 첫 영상 표시까지 p95 2초 이내를 목표로 합니다. 지원하지 않는 코덱이나 누락된 트랙은 별도 실패로 분류합니다.

  • 네트워크가 없는 상태에서도 로컬 다운로드 목록과 저장된 콘텐츠의 상태를 확인할 수 있어야 합니다. 오프라인 재생을 시작하는 경로에 필수 서버 호출을 넣지 않습니다.

  • 앱이 저장 완료로 표시한 데이터와 실제 저장 상태가 일치하도록 복구 절차를 둡니다. 진행률 숫자만으로 완료를 판단하지 않습니다.

  • 동일한 사용자 요청의 재시도로 같은 다운로드 인스턴스나 이용 권한이 불필요하게 중복 생성되지 않아야 합니다.

  • 저장 공간 예약과 동시 작업 수에 상한을 두고, 앱 내부 버퍼가 콘텐츠 전체 크기에 비례하여 증가하지 않도록 합니다.

  • 미디어는 보호된 형식으로 저장하고, 앱의 일반 데이터 모델에는 평문 콘텐츠 키를 보관하지 않습니다. 재생 허용 여부는 플랫폼 DRM의 판단과 서비스 정책을 함께 따릅니다.

  • 앱 복귀 후에는 로컬 기록과 플랫폼 전송 작업을 다시 확인합니다. 작업을 복원할 수 있다는 것과 운영체제가 즉시 실행시킨다는 것을 다른 목표로 관리합니다.


Out of Scope

  • Netflix의 추천 모델, 콘텐츠 제작과 인코딩 파이프라인 내부는 다루지 않습니다.

  • DRM 암호 알고리즘과 보안 모듈을 직접 구현하지 않습니다. 플랫폼 DRM과 계약된 라이선스 서버의 인터페이스를 사용합니다.

  • 결제와 계정 관리 시스템의 내부 구현은 제외하지만, 다운로드 허가와 라이선스 발급에 필요한 계정 및 기기 권한 검사는 포함합니다.

  • 다운로드가 끝나기 전 온라인 재생으로 전환하는 기능과 기기 간 다운로드 파일 전송은 기본 범위에서 제외합니다.


Architecture

영상은 단말이 받고 서버는 권한과 전달 계획을 제공합니다

다운로드가 오래 걸린다고 해서 서버에 사용자별 장시간 다운로드 Worker를 반드시 만들어야 하는 것은 아닙니다.

이번 설계에서는 실제 미디어를 받는 작업이 모바일 기기에서 실행됩니다. 서버는 어떤 콘텐츠를 어떤 조건으로 받을 수 있는지 결정하고, 단말이 접근할 미디어 정보와 라이선스 교환 경로를 제공합니다.

[Mobile App]
     |
     +---- 요청과 권한 확인 ----> [Download API]
     |
     +---- 미디어 요청 --------> [CDN]
     |
     +---- DRM 요청 교환 ------> [License Service]

이렇게 나누면 API 서버를 늘리는 것과 CDN 전달 용량을 늘리는 것을 구분할 수 있습니다.

반대로 영상 바이트까지 일반 API 서버를 통과시키면, 작은 권한 요청과 대용량 전송이 같은 서버 자원을 사용하게 됩니다. 별도의 보안 프록시나 특수한 요구가 없다면 이 경로를 추가할 이유가 약합니다.

화면은 작업을 소유하지 않습니다

화면에서 다운로드 요청을 시작할 수는 있지만, 화면이 사라졌다고 사용자의 저장 요청까지 사라져서는 안 됩니다.

모바일 내부에서는 화면, 다운로드 상태, 플랫폼 실행기를 분리하겠습니다.

[Download Screen]
        |
        v
[Download Repository]
        |
        v
[Download Coordinator]
        |
        +----> [Local Download Queue]
        |                 |
        |                 v
        |       [Platform Transfer Adapter]
        |
        +----> [License Manager]
        |
        +----> [Storage Manager]
        |
        +----> [Local Metadata Store]

Download Repository는 화면이 네트워크, 파일과 DB를 직접 수정하지 않도록 접근을 모읍니다.

Download Coordinator는 사용자가 원하는 상태와 현재 관측한 상태를 비교하여 다음 작업을 결정합니다. 예를 들어 사용자는 다운로드를 원하지만 저장 공간이 부족하다면, 실패를 반복하는 대신 저장 공간 대기 상태로 둡니다.

Platform Transfer Adapter는 iOS와 Android의 실제 다운로드 실행기를 연결합니다. 앱이 직접 관리하는 상태와 프레임워크가 보관하는 전송 상태를 무조건 복제하지 않고, 둘을 연결하는 식별자를 저장합니다.

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2026 실리콘밸리_생존자 · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture