Low Level Design: Presence Service

Presence States

  • online — active heartbeat within the last 30 seconds
  • away — active within the last 5 minutes but not in the last 30 seconds
  • offline — no activity for more than 5 minutes

Heartbeat Mechanism

Client sends a ping every 15 seconds. Server updates presence in Redis:

SETEX user:{id}:heartbeat 30 {timestamp}

The 30-second TTL ensures the key auto-expires if the client disconnects without an explicit logout.

Status Derivation

GET user:{id}:heartbeat
  -> key exists, age < 30s  => online
  -> key exists, age < 5min => away
  -> key missing            => offline

Presence Events and Fan-Out

On state change, publish to Redis channel:

PUBLISH presence:{user_id} {state}

A subscriber service maintains the friendship graph. On each presence event it fans out notifications to all friends with active WebSocket connections.

High-Follower Fan-Out

For users with more than 10K followers, synchronous fan-out is too slow. Instead, push the event to an async fan-out queue (e.g., Kafka/SQS). Workers consume and deliver to followers in batches.

Last-Seen Storage

UserPresence (
  user_id      BIGINT PRIMARY KEY,
  last_seen_at TIMESTAMP
)

Written to DB when a user transitions to offline, so last-seen can be displayed even for users who have been offline for days.

Privacy

Each user has a per-account setting to hide their online status. If enabled, presence events are suppressed and API responses return null for that user.

Presence Subscription

On app load, the client sends a list of contact user IDs. The server subscribes the client to those presence channels and streams state changes in real time.

Batch Presence API

For rendering a contact list efficiently:

GET /presence/batch?user_ids=1,2,3,4,5

Response:
{
  "1": "online",
  "2": "away",
  "3": "offline"
}

Server performs a Redis pipeline MGET for all requested keys, derives states, and returns in a single response.

Architecture Summary

Client  --heartbeat ping-->  API Server  --SETEX-->  Redis
                                             |
                                         PUBLISH presence:{uid}
                                             |
                                      Subscriber Service
                                             |
                                    Fan-out to friends via WS / queue

{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “How does a presence service determine if a user is online?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “The client sends a heartbeat ping every 15 seconds. The server stores a Redis key with a 30-second TTL. If the key exists and its age is under 30 seconds, the user is online. If the age is under 5 minutes, the user is away. If the key is missing, the user is offline.”
}
},
{
“@type”: “Question”,
“name”: “How do you scale presence fan-out to users with many followers?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “For users with more than 10K followers, synchronous fan-out is too slow. Instead, presence change events are pushed to an async fan-out queue such as Kafka or SQS. Workers consume events in batches and deliver notifications to followers.”
}
},
{
“@type”: “Question”,
“name”: “How is last-seen stored for users who have been offline for a long time?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “When a user transitions to offline, last_seen_at is written to a UserPresence table in the database. This allows the application to display accurate last-seen timestamps even after the Redis key has expired.”
}
},
{
“@type”: “Question”,
“name”: “How do you fetch presence status for an entire contact list efficiently?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “A batch API endpoint GET /presence/batch?user_ids=1,2,3 uses a Redis pipeline MGET to fetch all heartbeat keys in a single round trip, derives each user's state, and returns the results in one response.”
}
}
]
}

See also: Meta Interview Guide 2026: Facebook, Instagram, WhatsApp Engineering

See also: Netflix Interview Guide 2026: Streaming Architecture, Recommendation Systems, and Engineering Excellence

See also: LinkedIn Interview Guide 2026: Social Graph Engineering, Feed Ranking, and Professional Network Scale

See also: Snap Interview Guide

See also: Atlassian Interview Guide

Scroll to Top