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:
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:
| Layer | What happens |
|---|---|
| Server code | Pure relay. Socket.IO receives a message and broadcasts it. No variable, no array, no storage of any kind. |
| Browser | Messages saved to sessionStorage — dies when the tab closes. Each message is integrity-hashed to prevent tampering. |
| Database | There is no database. No SQL, no NoSQL, no file-based storage. The server has no dependency that could persist chat data. |
| nginx | access_log off and error_log /dev/null — the reverse proxy writes nothing to disk. |
| systemd | StandardOutput=null — the process manager captures no output. |
| HTTP headers | Referrer-Policy: no-referrer. No server version tokens. No analytics scripts. |
| Network | All 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:
| What | Why | When it's destroyed |
|---|---|---|
| Room exists | So people can join it | When room burns or empties |
| User nicknames | To prevent duplicates | When user disconnects |
| Admin roles | For moderation commands | When room burns |
| Ban/mute lists | To enforce moderation | When room burns |
| Room settings | Password, topic, rules | When 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
- 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
- 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