✎ ShareNotes
2026-10-03 Β· Engineering Β· By the ShareNotes team

One note, many viewers: how ShareNotes real-time sync works

The hard part of real-time sharing is not the socket. It is deciding what the socket is allowed to say, and to whom. Here is the whole design behind ShareNotes live notes, including the parts we would change at ten times the traffic.

Every ShareNotes note can be open in many places at once: a teacher and a classroom, a phone and a laptop in a clipboard room, two colleagues on a call. The common case is one person writing and several people watching, and the design is built around that.

Writes go over HTTP, reads come over the socket

This is the one decision everything else follows from. When you stop typing for a second, your browser saves the whole note with an ordinary HTTP request. That request is where the rules live: the server checks the note exists, refuses it if it was a view-once note already read, checks the PIN if the note is locked, and only then writes it to Postgres.

Then, and only then, the server sends the stored version to everyone watching. The WebSocket connection is for receiving. A browser can tell the server which notes it wants to follow; it cannot use the socket to change what anyone else sees.

Rule of thumb: never let one client's message be the thing other clients render. Route every change through the same checked path that stores it, and broadcast what was stored.

Fan-out

The server is a single Node process using the ws library, mounted at /ws on the same server as the API. It keeps a map from each open connection to the set of notes it follows. When a save succeeds, it walks that map and sends the new content to every connection subscribed to that note. For the sizes we see, that loop is cheap β€” a note has a handful of viewers, not thousands.

Notes locked for viewing are the exception. A connection only receives their content if it supplied the right PIN when it subscribed, and that is checked at the moment each update is sent β€” so subscribing to a note's address before someone creates it with a lock gets you nothing.

The reader's side

When an update arrives, the page replaces the note β€” unless you are typing in it at that moment. Yanking text out from under someone's cursor is worse than a short delay, so a focused editor keeps what you are writing and the latest version is there when you stop.

Reconnecting

Phones sleep, Wi-Fi drops, laptops close. The server pings each connection every 30 seconds so dead ones are noticed. The browser reconnects on its own with exponential backoff β€” one second, then two, four and so on up to thirty, for up to ten tries β€” and on reconnect it re-subscribes to every note it was following, including re-sending the PIN for locked ones. You do not see any of it; the note just catches up.

Where the design stops

  • Last save wins. Each save replaces the whole note. There is no operational transform or CRDT merging two people's keystrokes. If two people type in the same note at the same moment, the later save wins. For one writer and many readers β€” the case it is built for β€” that never comes up. For a shared document with several active writers, use a tool built for it.
  • Whole-document updates. We send the full note on every save, not a diff. Notes are small enough that this is simpler and fast.
  • One process. The subscription map lives in memory.

What we would do at ten times the traffic

The single-process map is the first thing to go. With several servers, a save on one has to reach viewers connected to another. Postgres gives us a way, and the plumbing is half built: the server already LISTENs on a note_updates channel. Nothing sends to it yet, because one process does not need it. At scale, each save would NOTIFY that channel with the note's address, and every process would look the note up and fan it out to its own connections. After that would come diffs instead of whole notes, and only then β€” if multi-writer editing ever became the main use β€” a real merge algorithm.

Classroom mode is this mechanism plus a PIN on the write path; we wrote up how that works for teachers. If you would rather drive notes from a script, the REST API creates them the same way.

No sign-up Β· Free forever Try a live note β†’

Answers, briefly.

The questions this post gets asked most.

How does ShareNotes sync a note in real time?
When the writer stops typing for a second, the browser saves the note over HTTP. The server checks permissions, stores it, and then pushes the stored version over WebSocket to every browser viewing that note.
Why are edits saved over HTTP instead of sent over the WebSocket?
So permissions are checked in one place. The save request verifies the PIN and other rules before storing anything, and only the stored version is broadcast. A browser cannot use the socket to change what others see.
What happens if two people edit the same note at the same time?
The later save wins, because each save replaces the whole note. ShareNotes is built for one writer and many readers; for several people typing at once, use a tool with real merge support.
What happens when my connection drops?
The browser reconnects automatically with exponential backoff, from one second up to thirty seconds, for up to ten tries, and re-subscribes to the notes you had open, so the note catches up without a refresh.
Do people watching a PIN-locked note get updates?
For an edit-locked note, yes β€” anyone with the link can watch. For a note locked for viewing, only browsers that supplied the correct PIN receive its content.