DEV Community

Kashaf Abdullah
Kashaf Abdullah

Posted on

What Really Happens When You Hit "Send" on WhatsApp Without Internet?

We've all done it.

You type a message, press Send, and suddenly realize… there's no internet.

The message doesn't disappear.
It doesn't fail instantly.
Instead, it patiently waits and then magically gets delivered once the connection returns.

But what's actually happening behind the scenes?

The answer is: a surprisingly sophisticated distributed system starts working the moment you hit Send.

Let's break it down.


Step 1: Your Message Gets Stored Locally

The moment you press Send, WhatsApp doesn't immediately depend on the internet.

Your message is first stored locally on your device and marked as pending.

That's why even when you're offline, the message still appears inside your chat.

Conceptually:
User → Send

Local Storage
Status = Pending

text

This local-first behavior improves reliability and user experience.


Step 2: The Message Enters an Outgoing Queue

Once stored locally, the app places the message into an outgoing queue.

Think of a queue like a waiting line.

If internet isn't available:

  • Message remains queued
  • Order is preserved
  • App waits instead of failing

Queues are one of the most important reliability patterns in modern systems.


Step 3: Connectivity Monitoring Starts

While the message waits, the app continuously listens for connectivity changes using operating system network signals.

The goal: Send instantly when a usable connection becomes available.

No manual retry needed.


Step 4: Retry Mechanism Kicks In

As soon as internet returns:

  • App detects connectivity
  • Pending messages are retried automatically
  • Messages leave the queue in order

This retry layer makes messaging feel seamless.

Without retries, users would constantly resend messages manually.


Step 5: End-to-End Encryption Happens

Before the message leaves your device, it is encrypted.

This means:

  • Sender can read it
  • Receiver can read it
  • Intermediate systems cannot read message content

Encryption protects privacy while the message travels across networks.


Step 6: Persistent Connections Reduce Latency

Messaging apps avoid opening a brand-new network connection for every message.

Instead, they maintain persistent connections whenever possible.

Benefits:

  • Faster delivery
  • Lower overhead
  • Reduced battery usage
  • Better real-time performance

This is one reason messages often appear to arrive instantly.


Step 7: Backend Infrastructure Handles Scale

Once the encrypted message reaches backend systems:

  • Load balancers distribute traffic
  • Messaging services process requests
  • Internal buffering and asynchronous processing help absorb spikes

Why? Imagine millions of users sending messages simultaneously.

Without buffering and distributed processing, systems would overload.


Step 8: Offline Recipient? Store and Deliver Later

If the receiver is offline:

  • Message waits temporarily
  • Delivery happens when receiver reconnects

That's why messaging feels reliable even across unstable networks.


Understanding WhatsApp Status Icons

Icon Meaning
Waiting to send
Server received the message
✓✓ Recipient device received it
Blue ✓✓ Recipient opened/read it (if enabled)

Complete Flow Diagram

User presses Send


Message stored locally (Pending)


Message added to outgoing queue


Is internet available? ───No───▶ Wait, monitor connectivity
│ Yes │
▼ ▼
Encrypt message Internet returns
│ │
▼ ▼
Send via persistent Retry message automatically
connection to backend │
│ │
▼ ▼
Backend processes Message delivered
and routes message


Receiver gets message

text


Code Example: Simple Offline Message Queue

// Simple offline message queue simulation
class MessageQueue {
  constructor() {
    this.queue = [];
    this.isOnline = navigator.onLine;
    this.setupListeners();
  }

  setupListeners() {
    window.addEventListener('online', () => {
      this.isOnline = true;
      this.processQueue();
    });

    window.addEventListener('offline', () => {
      this.isOnline = false;
    });
  }

  sendMessage(message) {
    this.queue.push({
      ...message,
      status: 'pending'
    });

    if (this.isOnline) {
      this.processQueue();
    }
  }

  async processQueue() {
    while (this.queue.length > 0 && this.isOnline) {
      const message = this.queue[0];
      try {
        await this.uploadToServer(message);
        this.queue.shift();
        console.log('✅ Message delivered:', message.id);
      } catch (error) {
        console.log('❌ Delivery failed, retrying later');
        break;
      }
    }
  }

  async uploadToServer(message) {
    // Simulate API call
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (Math.random() > 0.1) {
          resolve({ success: true });
        } else {
          reject(new Error('Network error'));
        }
      }, 1000);
    });
  }
}

// Usage
const queue = new MessageQueue();
queue.sendMessage({ id: 1, text: 'Hello World' });


Enter fullscreen mode Exit fullscreen mode

Why This Design Matters

Feature Benefit
Local-first storage Messages don't disappear
Queues Preserves order and reliability
Retry mechanism No manual resend needed
Encryption Protects privacy
Persistent connections Fast delivery
Buffering Handles massive scale

Final Thoughts

Sending a message feels simple.

But behind one tap exists a complete distributed architecture:

  • Local persistence
  • Retry mechanisms
  • Queue-based delivery
  • Persistent connections
  • Encryption
  • Load balancing
  • Real-time synchronization

All of this works together so users experience one thing:

Tap Send → Message Delivered.

And most people never notice the engineering behind it.


Written by Kashaf Abdullah

Software Engineer | MERN Stack | Web Development


Top comments (0)