Technical March 2026 6 min read

How BurnChat Achieves True Zero-Log Chat

Most "private" chat apps store your messages in a database and promise to delete them later. We took a different approach: the server never stores a single message in the first place. Here's exactly how it works — at the code level.

The core idea: you control storage and encryption

When you send a message on BurnChat, the server receives it over a WebSocket connection, broadcasts it to everyone else in the room, and immediately forgets it. The message is never saved to a variable, never written to an array, never pushed to a queue. It passes through the server the way electricity passes through a wire — it flows, but nothing stays behind.

This is fundamentally different from how every other chat platform works. Slack, Discord, Telegram, WhatsApp — they all receive your message, store it in a database, and then send it to the other participants. The database copy persists indefinitely unless someone explicitly deletes it (and even then, backups often survive). BurnChat has no database. No file writes. Not even an in-memory array.

So where do messages live?

In your browser. Only in your browser.

When the server relays a message to your browser, our JavaScript code saves it to sessionStorage — a browser API that stores data for the current tab session. This means:

1
You send a messageBrowser sends it to the server via WebSocket
2
Server relays itBroadcasts to all other users in the room — stores last 100 in RAM (or nothing in client-only mode)
3
Each browser saves locallyMessage stored in sessionStorage on each user's device
4
Tab closes = gonesessionStorage is destroyed by the browser. No trace remains anywhere.

This is the key insight: sessionStorage dies when the tab closes. It's not like localStorage or cookies, which persist across sessions. When you close the BurnChat tab, the browser destroys the data automatically. We don't even have to ask.

The full privacy stack

Zero-log isn't just one decision — it's enforced at every layer of the stack. If any single layer logged data, the whole promise would be broken. Here's what we do at each level:

LayerWhat happens
Server codePure relay. Socket.IO receives a message and broadcasts it. No variable, no array, no storage of any kind.
BrowserMessages saved to sessionStorage — dies when the tab closes. Each message is integrity-hashed to prevent tampering.
DatabaseThere is no database. No SQL, no NoSQL, no file-based storage. The server has no dependency that could persist chat data.
nginxaccess_log off and error_log /dev/null — the reverse proxy writes nothing to disk.
systemdStandardOutput=null — the process manager captures no output.
HTTP headersReferrer-Policy: no-referrer. No server version tokens. No analytics scripts.
NetworkAll traffic over HTTPS/WSS. No third-party CDNs. No external scripts. No tracking pixels.

What about voice messages and images?

Same principle. Voice messages are recorded in your browser using the MediaRecorder API, encoded as base64, sent through the WebSocket, relayed to other users. In server mode, the last 100 messages are kept in RAM for late joiners. In client-only mode, nothing is stored. Each recipient's browser plays the audio directly from the data it received. When the tab closes, the audio data in sessionStorage is destroyed.

Images work the same way. They're compressed client-side, sent as base64, relayed to the room, and saved only in each user's browser. The server never writes a single image byte to disk or RAM.

What the server does keep track of

The server isn't completely stateless. It tracks the minimum required to make real-time chat work:

WhatWhyWhen it's destroyed
Room existsSo people can join itWhen room burns or empties
User nicknamesTo prevent duplicatesWhen user disconnects
Admin rolesFor moderation commandsWhen room burns
Ban/mute listsTo enforce moderationWhen room burns
Room settingsPassword, topic, rulesWhen room burns

None of this includes message content. The server knows who is in a room and what settings the room has, but it has zero knowledge of what anyone said. If someone subpoenaed our server, they would find room IDs, nicknames, and settings — but not a single message, image, or voice note.

How BurnChat compares to "private" alternatives

Typical "private" chat
  • Messages stored in database
  • "We'll delete after 30 days"
  • Backups exist on multiple servers
  • Employees can access data
  • Subpoena returns full history
  • Data breach exposes everything
BurnChat
  • Server stores zero messages
  • Nothing permanent to delete — RAM cleared on burn, or nothing stored at all in client mode
  • No backups of chat data
  • We can't access what doesn't exist
  • Subpoena returns empty hands
  • Breach finds no message data

What about late joiners?

If you join a room that's already active, you start with a clean slate. You won't see previous messages because the server doesn't have them. This is a deliberate tradeoff: we chose privacy over convenience. Every user only sees what happens while they're connected.

If you refresh your tab, your own messages are restored from your browser's sessionStorage — but only your session's messages, and only until you close the tab.

Can we prove this?

Yes. The entire codebase is open source on GitHub. The server is a single JavaScript file. You can search it for any storage operation — push, writeFile, save, insert, store — and you'll find zero operations that persist message content. The only file write is a stats counter (rooms burned, total connections) that contains no message data.

We didn't build privacy as a feature that can be toggled off. We built an architecture where storing messages is physically impossible without rewriting the server. That's the difference.

The one-sentence version

The server is a wire, not a warehouse. Messages flow through it and vanish. The only copy lives in your browser and dies when you close the tab.

🔥

See for yourself

Try BurnChat. Read the source code. Verify every claim.

Open BurnChat View Source