Skip to main content
Back to Blog
Engineering4 min read

Real-Time Messaging in a Multi-Tenant Architecture

Mario Fernandez

Mario Fernandez

CEO · Apr 25, 2026 · 4 min read

Building a messaging system is one of those features that looks simple on the surface. A text box, a send button, a list of messages. Users have been sending messages in apps since the early days of the internet. How hard can it be?

The answer, as anyone who has built one knows, is very. Real-time message delivery, offline handling, typing indicators, read receipts, and presence detection are each significant engineering challenges on their own. Layer in multi-tenant isolation, where hundreds of workspaces share the same infrastructure but must never see each other's data, and the complexity compounds quickly.

Tenant Isolation at the Channel Level

The most critical requirement for messaging in a multi-tenant platform is isolation. Workspace A must never receive a message from Workspace B. This is not just a privacy concern. It is a security and legal requirement. Client names, venue details, crew rates, and gig specifics flow through messages constantly. A single leak between tenants would be catastrophic.

JamCrew enforces tenant isolation at the channel level. Every message channel is scoped to a workspace ID. When a user connects and subscribes to channels, the server validates that the user belongs to the workspace that owns the channel. This check happens on every subscription request, not just at login. If a user's workspace membership is revoked, their active subscriptions are terminated immediately.

Channel naming follows a deterministic pattern that includes the workspace ID as a prefix. This makes it structurally impossible for a subscription to accidentally cross tenant boundaries. Even if application logic had a bug, the channel naming convention would prevent data leakage.

Connection Management on Mobile

Desktop users maintain stable connections. Mobile users do not. A crew member checks their phone between tasks, reads a message, puts the phone back in their pocket. The screen locks, the app goes to background, and the connection drops. Five minutes later they pull the phone out again and expect to see any messages that arrived while they were offline.

JamCrew handles this with a combination of persistent message storage and intelligent reconnection. Every message is written to the database before it is broadcast. When a client reconnects, it requests all messages since its last known message timestamp. The server sends the missed messages in order, and the client merges them into the local conversation state.

This approach means the real-time connection is an optimization, not a requirement. If the connection drops for 30 seconds or 30 minutes, the user experience is the same: open the app and all messages are there. The real-time layer provides instant delivery when both parties are online. The persistence layer guarantees nothing is lost when they are not.

Battery life is a real concern on mobile. Maintaining an open WebSocket connection drains power, even when no messages are flowing. JamCrew uses an adaptive connection strategy. When the app is in the foreground and the user is in a conversation, the connection is kept alive with lightweight heartbeat pings. When the app moves to the background, the connection is closed gracefully and push notifications take over for delivery alerts. When the app returns to the foreground, the connection re-establishes and catches up.

Typing Indicators and Presence

Typing indicators and online presence are features users expect but rarely think about. They are also surprisingly expensive if implemented naively. Broadcasting a "user is typing" event to every member of a channel, on every keystroke, generates enormous message volume. Multiply that across hundreds of concurrent conversations and the infrastructure cost becomes significant.

JamCrew throttles typing indicators to one event per two seconds per user per channel. The client-side debounces keystrokes and only sends a typing event if the user has typed something new since the last event. The receiving clients display a typing indicator for three seconds after the last received event, then hide it. This approach reduces event volume by roughly 90% compared to per-keystroke broadcasting while maintaining the appearance of real-time feedback.

Presence (whether a user is online or offline) uses a similar strategy. The server tracks the last activity timestamp for each user. A user is considered online if they have been active within the last 60 seconds. The presence state is updated on connection events and on message sends, not on a continuous polling basis.

Infrastructure Decisions

We evaluated three approaches: building on raw WebSockets, using a managed real-time service, and leveraging Convex's built-in reactivity. Convex's reactive query system turned out to be the strongest fit for our architecture. Queries automatically re-run when their underlying data changes, which means message lists update in real time without manual WebSocket management. Tenant isolation is enforced in the query functions themselves, at the data access layer, not at the transport layer.

This choice eliminated an entire class of infrastructure concerns. No WebSocket server to scale. No connection pooling to manage. No pub/sub system to maintain. The same TypeScript functions that enforce tenant isolation for reads and writes also enforce it for real-time subscriptions. One security model, applied consistently everywhere.

Encryption Considerations

End-to-end encryption is on the roadmap but not in the initial release. The technical challenge is not the encryption itself. It is key management in a multi-tenant context where users belong to workspaces managed by admins. If an admin needs to review messages for compliance purposes, end-to-end encryption conflicts with that requirement. The solution likely involves a hybrid model where workspace-level encryption protects data at rest and in transit, while preserving admin access within the tenant boundary. This is an area where getting it right matters more than getting it first.

messagingreal-timemulti-tenantengineering

Ready to streamline your crew management?

JamCrew helps production companies manage crews, gigs, and schedules in one place.

Get Started