Guide

Presence tells you who is online. Typing tells you who is typing right now. Both feel important, but neither is stored history. They're ephemeral signals. If the system loses one, the chat still works. So they're built to be cheap, and they're the first thing dropped when the system is under load.

Concept

A heartbeat is a small message that a client sends every few seconds to say "still here." A TTL is a time-to-live. A value with a TTL disappears on its own unless something refreshes it.

The big idea

"Online" is not a physical fact. It's a smoothed view of recent heartbeats. A phone can lose its signal while its app still looks connected. A mobile OS can freeze a socket without telling the app. So presence is a guess that gets better over time.

The guess is still useful, because presence decides which delivery path to try first. It is never the only safety net. Delivery and sync-on-connect protect the messages themselves.

Walking through it

Presence lives in a fast store, such as Redis, with a short TTL on each entry. Heartbeats refresh the TTL, every 15 to 30 seconds. The entry is userId → status, lastSeen.

When a phone dies silently, its heartbeats stop. The entry expires within one interval. In that window, other users may still see that person as online. The team accepts that trade-off, because perfect detection would cost far more.

Broadcast carefully. Send presence only to people who need it, such as friends or channel members, or compute it when someone looks. A global presence feed for every user doesn't scale.

Typing is an ephemeral pub/sub event. Nothing touches disk. Limit it to one event per user, per channel, every few hundred milliseconds. Drop it freely under load.

t=0s    phone sends heartbeat    → presence: online, TTL 30s
t=20s   phone dies, no heartbeat
t=30s   TTL expires              → presence: offline
        (other users saw "online" for up to one interval)

Common mistakes

  • Storing presence or typing on disk. Durable writes for ephemeral signals waste capacity.
  • Broadcasting presence to everyone. Each status change then fans out to millions of clients.
  • Treating presence as proof of delivery. A user who looks offline still needs the message. Save the message and sync on connect.

Check yourself

  1. A phone's heartbeats stop without warning. How long can others see it as online? Until its presence entry expires, which is about one heartbeat interval, so roughly 15 to 30 seconds with the example settings.
  2. Why is it safe to drop typing events under load? They are not stored, and no message depends on them.

Key takeaways

  • Presence and typing are best-effort, ephemeral signals.
  • Heartbeats with a TTL give a smoothed view of who is online.
  • Broadcast presence only to people who need it.
  • Presence chooses a delivery path. It never replaces saving the message.

Further learning

The real-time delivery page covers the pub/sub and connection techniques behind these signals.

Next, read about the chat connection layer, which holds the sockets that presence depends on.