/ how it works

Four levels. Zero confusion.

Every message in NoLag flows through a four-level hierarchy. Each level exists for a specific reason. Skip one, and you'd lose an important boundary.

project  / app   / room     / topic
―――――――――――――――――――――――――――――――――――――――――――
logistics  / chat   / dispatch-team / messages
logistics  / chat   / dispatch-team / _typing
logistics  / tracking / driver-42   / locations
logistics  / tracking / driver-42   / status
logistics  / dashboard / overview   / metrics

A logistics platform with chat, GPS tracking, and a live dashboard, all within one project.

Project: Your Product Boundary

A project is the top-level container. It represents your product or a specific environment of your product. Everything inside (apps, actors, rooms, usage) belongs to that project.

Billing boundary

Usage limits (connections, messages, bandwidth) are tracked per project.

Actor home

Actors (your end users) are created within a project and granted access to specific apps.

Environment separation

Most teams create separate projects for production and staging so test traffic never touches real data.

Think of a project the same way you'd think of a Firebase project or a Supabase project: one per product, per environment.

App: A Distinct Real-time Feature

Inside a project, each app represents a separate real-time capability. Apps have their own topic definitions, room configurations, webhooks, and message logging settings.

Why separate apps instead of one big app?

Because different features have fundamentally different requirements:

Chat app

Needs message history with 7-day retention, replay on reconnect, and typing indicators with no logging.

GPS tracking app

Needs low-latency fire-and-forget delivery with no message storage. Stale coordinates are useless.

Dashboard app

Needs aggregated metrics with short retention and widget configuration updates.

By splitting these into separate apps, each one gets its own configuration without compromise. Chat doesn't inherit tracking's fire-and-forget QoS. Tracking doesn't pay for chat's message storage. And when you need notifications later, you add a new app without touching the others.

Actors are granted access to specific apps. A single actor can be given access to chat, tracking, and dashboard, interacting with each through one WebSocket connection.

Room: Scoped Data Isolation

Rooms give each user, team, device, or session their own isolated instance of an app's topics. Without rooms, every subscriber to "messages" would see every message from every conversation. Rooms scope the data.

Chat app

Each room is a conversation: dispatch-team, drivers-east, support.

Tracking app

Each room is a tracked entity: driver-42, vehicle-108.

Dashboard app

Each room is a view: overview, region-north.

Static vs Dynamic Rooms

Rooms can be static (defined in your app configuration for permanent channels like general) or dynamic (created via the REST API when a new driver signs up or a new team is formed).

Public vs Private Rooms

By default, rooms are public, meaning any actor with access to the app can connect. When you attach specific actors to a room, that room automatically becomes private. Only the attached actors can access it.

This is how you implement per-user or per-team data isolation without writing any authorization logic:

  • Attach a driver to their tracking room, and no other driver can see their GPS stream
  • Attach team members to a chat room, and outsiders can't join
  • Attach a user to their notification room, and only they receive their alerts
No actors attached = public. At least one actor attached = private. There is no toggle; the presence of actor assignments is what makes a room private.

Topic: The Message Channel

Topics are the actual pub/sub channels within a room. Each topic carries one type of data. Subscribers choose which topics to listen to, so a client in the dispatch-team chat room might subscribe to messages but not _typing.

messages

Chat messages with history and replay

_typing

Ephemeral typing indicators (no logging)

locations

GPS coordinates streamed in real-time

metrics

Aggregated dashboard data points

Topic Inheritance

Topics are defined at the app level and inherited by every room. All rooms in your chat app share the same topic structure (messages and _typing), so you configure once and scale to thousands of rooms.

Putting It All Together

LevelExamplePurpose
Projectlogistics-prodBilling, actor management, environment boundary
Appschat, tracking, dashboardSeparate features with independent config
Roomsdispatch-team, driver-42, overviewPer-user/team/device data isolation
Topicsmessages, locations, metricsIndividual message channels within a room

A dispatcher with access to all three apps can simultaneously:

chat
Sends and receives messages in dispatch-team
tracking
Watches live GPS updates from driver-42
dashboard
Monitors fleet health on overview

All through one connection, with each app's data cleanly separated.

Ready to build?

Create a free project and start publishing messages in under 5 minutes.