Skip to content

Phone Off Three Days

Full status flow — Bob's phone is dead for 3 days, then he turns it on

Every tick state Alice sees, and when each one changes.


The setup

Alice and Bob are chatting. The last message Bob read was seq=41 (last_read_seq=41). Bob's phone dies — battery completely dead.

Over the next 3 days, Alice sends 5 messages:

seq=42  "hey"
seq=43  "where are you?"
seq=44  "hello??"
seq=45  "is everything okay?"
seq=46  "call me when you can"

Each is stored in DynamoDB. Each triggers an attempt to deliver to Bob — no WebSocket found, Bob is offline. pending_deliveries entry created for Bob / conv_abc123 with first_undelivered_seq=42.

APNs is called for each message, but Bob's phone is off — APNs queues the latest notification, can't deliver to a dead device.


Alice's view during these 3 days

All 5 messages: single tick ✓

last_delivered_seq = 41  (last WebSocket ack Bob sent, before phone died)
last_read_seq = 41

Every message seq=42 through seq=46:
  seq > last_delivered_seq → single tick

Alice sees single tick on all 5 messages. Nothing changes until Bob's phone turns on.


Day 3 — Bob turns his phone on

Step 1 — OS connects to APNs

Bob's phone powers on. The OS re-establishes its persistent connection to APNs automatically. No app involvement.

APNs had the latest notification queued: "Alice: call me when you can"

APNs delivers it immediately:

Bob's lock screen: "Alice: call me when you can"

Alice's tick view: still single tick. Nothing has changed server-side yet. The notification was delivered by Apple's infrastructure, not WhatsApp's.


Step 2 — Bob does NOT open WhatsApp yet

Bob sees the notification. He's just woken up, doesn't open the app.

Alice: still single tick on all 5 messages.


Step 3 — Bob taps the notification, WhatsApp opens

Bob taps. WhatsApp launches. The app reads conversation_id from the notification payload and opens conv_abc123 directly.

WebSocket established:

WhatsApp → WS server: HTTP upgrade → authenticated → WebSocket live
WS server → Redis: SET ws:bob → ws_server_3

pending_deliveries queried:

GET WHERE PK=bob
→ { conversation_id: conv_abc123, first_undelivered_seq: 42 }

DynamoDB range query:

PK=conv_abc123, SK >= 42
→ returns seq 42, 43, 44, 45, 46

All 5 messages pushed to Bob over WebSocket.


Step 4 — Bob's client sends cumulative delivery ack

Bob's client receives all 5 messages, renders them:

Bob's client → WS server: {
  type: "delivered",
  conversation_id: "conv_abc123",
  seq: 46
}

Server updates message_status:

UPDATE message_status
  SET last_delivered_seq = 46
  WHERE user_id=bob AND conversation_id=conv_abc123

Server checks if Alice is online:

GET ws:alice → ws_server_1   (Alice is online)
→ Push to Alice: { type: "status_update", conversation_id: conv_abc123, last_delivered_seq: 46 }

Alice's view:

seq=42 through seq=46: double tick ✓✓

All 5 messages flip from single to double tick simultaneously. Alice is at her desk and sees the ticks update in real time.


Step 5 — Bob reads the messages (chat is already open)

Bob is already on the chat screen — he tapped the notification and it opened directly to conv_abc123. The messages are visible. His client fires a read event:

Bob's client → WS server: {
  type: "read",
  conversation_id: "conv_abc123",
  seq: 46
}

Server updates message_status:

UPDATE message_status
  SET last_read_seq = 46
  WHERE user_id=bob AND conversation_id=conv_abc123

Push to Alice:

{ type: "status_update", conversation_id: conv_abc123, last_read_seq: 46 }

Alice's view:

seq=42 through seq=46: blue tick ✓✓ (blue)


The full tick timeline from Alice's perspective

Day 0, 9am   Alice sends seq=42        → single tick ✓
Day 0, 2pm   Alice sends seq=43        → single tick ✓
Day 1        Alice sends seq=44, 45    → single tick ✓
Day 3, 8am   Alice sends seq=46        → single tick ✓

Day 3, 9am   Bob turns phone on        → still single tick (notification only, no WebSocket)
Day 3, 9:02am Bob opens WhatsApp       → WebSocket established
Day 3, 9:02am Bob's client acks seq=46 → all 5 messages flip to double tick ✓✓ instantly
Day 3, 9:02am Bob's client reads chat  → all 5 messages flip to blue tick ✓✓ seconds later

Three days of single tick. Then within seconds of Bob opening the app, both double tick and blue tick arrive. Alice sees two rapid tick updates in quick succession.

Interview framing

"While Bob's phone is off, Alice sees single tick — no WebSocket means no delivery ack. The moment Bob opens WhatsApp, WebSocket is established, pending messages are pushed, Bob's client sends a cumulative delivered ack, and all messages flip to double tick. If Bob opens the chat (which he does, since the notification lands him there), read event fires immediately after and blue tick follows. Both updates arrive within seconds."