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.
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.
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.
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
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.
messagesChat messages with history and replay
_typingEphemeral typing indicators (no logging)
locationsGPS coordinates streamed in real-time
metricsAggregated 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
| Level | Example | Purpose |
|---|---|---|
| Project | logistics-prod | Billing, actor management, environment boundary |
| Apps | chat, tracking, dashboard | Separate features with independent config |
| Rooms | dispatch-team, driver-42, overview | Per-user/team/device data isolation |
| Topics | messages, locations, metrics | Individual message channels within a room |
A dispatcher with access to all three apps can simultaneously:
dispatch-teamdriver-42overviewAll 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.