Skip to content

Resume Playback — Flow Architecture#

The Two Paths#

Resume playback has two distinct flows — the write path (continuous position saving during playback) and the read path (position lookup when a new stream starts). They are independent and hit different endpoints.


Write Path — Saving Position During Playback#

Every 4 seconds while a user is watching, the client fires a progress update. This goes through the API Gateway for auth and lands at the Stream Service, which writes directly to Cassandra.

sequenceDiagram
    participant C as Client
    participant GW as API Gateway
    participant SS as Stream Service
    participant CASS as Cassandra

    Note over C: User watching — every 4 seconds
    C->>GW: POST /api/v1/stream/progress { movie_id, position_seconds }
    GW->>SS: authenticated write
    SS->>CASS: WRITE user_id + movie_id + position_seconds + timestamp
    CASS-->>SS: acknowledged
    SS-->>GW: 204 No Content
    GW-->>C: 204 No Content

The response is 204 No Content — there is nothing meaningful to return. The client fires and forgets, continuing playback without waiting.


Read Path — Resuming on Stream Start#

When a user clicks Play, the Stream Service reads the last saved position from Cassandra, applies the completion threshold, and returns the position alongside the stream URL.

sequenceDiagram
    participant C as Client
    participant GW as API Gateway
    participant SS as Stream Service
    participant CASS as Cassandra
    participant CDN as CDN

    C->>GW: GET /api/v1/stream?movie_id=inception
    GW->>SS: authenticated request
    SS->>CASS: READ position WHERE user_id=X AND movie_id=inception
    CASS-->>SS: position_seconds: 2843

    Note over SS: Apply completion threshold
    Note over SS: 2843 < 95% of 7800 → in progress

    SS-->>GW: { stream_url: "cdn.netflix.com/...", resume_position_seconds: 2843 }
    GW-->>C: response

    C->>CDN: fetch manifest → fetch chunks from position 2843
    Note over C: Playback starts at 47:23

How the Two Paths Fit Together#

flowchart TD
    subgraph Write Path
        WC[Client — watching] -->|POST /progress every 4s| WGW[API Gateway]
        WGW --> SS1[Stream Service]
        SS1 -->|WRITE position + timestamp| CASS[(Cassandra)]
    end

    subgraph Read Path
        RC[Client — press Play] -->|GET /stream| RGW[API Gateway]
        RGW --> SS2[Stream Service]
        SS2 -->|READ last position| CASS
        SS2 -->|apply 95% threshold| SS2
        SS2 -->|resume_position_seconds| RC
        RC -->|fetch chunks from that position| CDN[CDN]
    end

Component Responsibilities#

Component Role in Resume Playback
Client Fires progress write every 4 seconds during playback
API Gateway Auth on both read and write paths
Stream Service Writes position to Cassandra, reads position on stream start, applies completion threshold
Cassandra Stores raw position — last-write-wins by timestamp, no business logic
CDN Serves video chunks from the resumed position — no knowledge of Cassandra

The CDN has no involvement in resume logic. Once the client knows the position, it uses it to seek to the right chunk in the manifest and start fetching from there. Resume playback and chunk delivery are fully independent concerns.