Internal Alpha: stress-testing LynxDock's networking layer
Written by The LynxDock Team, Engineering, LynxDock
A networking stack that passes its unit tests but has never been watched working end to end is a hypothesis, not a feature. Before starting on voice and video, we wanted to know that the messaging layer underneath them behaves correctly not just in the happy path, but under concurrency, failure, and recovery - the conditions that usually don't surface a bug until it's in someone's real conversation. This is a write-up of that verification pass: the tests, the results, and the defect we found and fixed before shipping.
The setup. One server and three clients signed in as three different users, each also connected from a second window so every account was live on two devices at once. That arrangement lets a single machine exercise most of the distributed behavior that matters - cross-client delivery, cross-device state sync, and concurrent writes to the same channel. Each test case maps to a method the server actually implements, so nothing here is theoretical.
Server restart, mid-conversation. With messages in flight we killed the server process outright. Every client detected the drop within a couple of seconds and moved to a reconnecting state rather than erroring. When we restarted the server, all three clients re-established their sessions on their own in about six seconds, with no re-login. A reaction added just before the outage was still there afterward, and unread counts survived the restart intact, because read state is persisted to disk rather than held only in server memory.
The offline queue. While the server was down, we kept composing. Instead of failing, outgoing messages collected in a local outbox under a 'waiting to send' indicator. On reconnect, the queue drained automatically - and this is the part that matters - the messages arrived at the other clients in order and exactly once. No duplicates from an over-eager retry, no gaps from a dropped send. An outbox that double-delivers on reconnect is a classic distributed-systems failure, and it's the specific thing we were watching for.
Cross-device read state. With the same account open on two devices, we opened an unread channel on one and watched the unread badge clear on the other without touching it. Server-backed read state is a feature nearly every chat product claims and comparatively few verify across devices under observation. Ours now has a passing test with a date on it.
Simultaneous sends. Then we stopped being gentle. Three clients each fired a burst of twenty messages into the same channel at once - sixty concurrent writes. Every accepted message received a unique id, and all three clients converged on a single global ordering that matched to the character: no duplicates, no gaps, no lost events, and no disagreement between clients about what happened or in what order. Total-order consistency under concurrent writes is the hard part of a real-time chat system, and it held.
The defect, and the fix. A stress test earns its keep by breaking something, and this one did: very long messages were handled inconsistently. The client and server disagreed on how to count length - one measured UTF-16 code units, the other Unicode code points, so an emoji-heavy message could be counted two different ways - and on one path a message over the limit could clear the composer and vanish without an error, which reads to the user as silent data loss. We fixed it before publishing this post. There is now a single documented length limit enforced identically on client and server, counted the same way on both; a live character counter; an explicit over-limit message; and a hard guarantee that the composer never clears your text unless the server has actually accepted the message. We added tests at the limit, one under, and one over, on both the client and the server, and re-ran the full three-client check until it came back clean.
What's still open, in the open. A few smaller gaps came out of the same pass and are on the board rather than hidden: during a network outage the client currently blanks its cached view until reconnect - everything returns, but a local-first app should keep showing history while offline - message editing exists on the server without a UI yet, and there are a couple of cosmetic rough edges. Two cases were deferred rather than failed: the containerized self-host parity run, and the voice smoke test, which needs human ears and gates the next release tag.
Why we work this way. A month ago our own roadmap described intent and filed it under status; we've since made a rule that a capability only gets a checkmark when someone has watched it be true. Version 2.2 is now tagged with that standard met - networking verified end to end, stress-tested, and hardened against the one real failure the stress test found. That is what starts the internal alpha: not a claim that it works, but a dated record that it does, and an honest list of what's next.