Optimizing Real-Time Device Updates: Efficient Channels for User Notifications
Outline
Are You Tracking Devices Efficiently or Wasting Resources?
TLDR; I ended up using the traditional way but was a fun exercise to unlearn and determine what would work best for the project
In real-time systems, tracking devices and keeping users updated is a common task for fleet management, IoT devices, and logistics companies. But how you handle those updates can significantly impact server performance and operational costs. Are you sending updates the most efficient way?
The decisions you make around whether to send updates based on devices or users can dramatically alter the performance of your application. Let’s dive into the two primary methods for sending updates, how they compare, and which makes more sense for your infrastructure as you scale.
User and Device Relationships
At the heart of any tracking system is the relationship between users and devices. In most setups:
- A user can manage many devices: For instance, a fleet owner might be responsible for hundreds or thousands of devices.
- A device can have many users: A single device might be monitored by multiple users, particularly in shared environments.
The key challenge arises when a device moves or changes status. Should you notify the device’s managing users through a device-based channel, or send notifications to each user individually via their user-based channel?
Comparing Update Methods
Device-Based Channel Updates
In this model, each device has its own channel for updates. When a device moves, all users managing that device are notified by subscribing to that device’s channel. Here’s how it works in practice:
-
Scenario 1: 10 devices, 5 users
- 10 device channels
- 1 message per channel for each device, consumed by 5 users
- Server operations: 1 write, 5 reads
-
Pros:
- Fewer writes, especially in environments where devices outnumber users.
- Easier scaling on the read side since reads are cheaper than writes.
-
Cons:
- Devices with many users might lead to many reads, but fewer write operations.
- As the number of devices grows, more channels need to be managed.
User-Based Channel Updates
In this method, updates are sent to each user’s unique channel. Whenever a device moves, the users managing that device each get a personal notification.
-
Scenario 2: 10 devices, 5 users
- 5 user channels
- 1 message per user per device update
- Server operations: 5 writes, 5 reads
-
Pros:
- Users can have a single channel for updates across all devices they manage.
- Fewer reads, more write operations, but manageable in environments where there are far fewer users than devices.
-
Cons:
- If many users manage a single device, the server must write multiple messages.
- More write-heavy, which can be costly depending on your infrastructure.
Considerations and Trade-offs
Read vs. Write Operations
When evaluating both methods, understanding the cost of reads vs. writes is critical:
- Reads are generally cheaper and faster, especially at scale.
- Writes, particularly in high volumes, can slow down a system and lead to bottlenecks.
In environments with more devices than users, it might make sense to use device-based channels to minimize the number of write operations. However, in user-heavy systems, you might find user-based updates more efficient.
Scaling and Infrastructure Costs
Another consideration is scalability. As your system grows, managing these channels efficiently becomes more complex. Device-based channels are easier to scale on the read side since you’re minimizing the number of writes.
User-based channels, on the other hand, can scale well if you optimize for fewer users managing more devices. However, more complex scenarios—where thousands of devices are managed by a few users—could lead to excessive write costs.
User Experience and Client Devices
User experience is another critical factor in this decision. With user-based channels, you can streamline the experience for end-users, consolidating all their updates into a single channel. This reduces the processing load on the client-side, especially for low-end devices where resources are limited.
In contrast, device-based channels might lead to multiple subscriptions, which can add complexity to the client-side experience. This could be a problem if the end-user is using older or less powerful devices.
Practical Example: Fleet Management
Consider a fleet management system where each user manages hundreds of vehicles. In such a setup:
- Devices greatly outnumber users.
- Sending updates based on user channels might seem intuitive, but in practice, sending thousands of updates to a single user channel can become a costly operation.
By shifting to a device-based channel model:
- The system sends a single update for each device and lets the users subscribe to the devices they manage.
- This drastically reduces the number of messages sent, easing the burden on both the server and the client.
The Trade-Off: Absorb Some Costs or Build a Custom Solution?
Every infrastructure decision comes down to a balance of performance and cost. Using third-party services like Pusher is often easier to implement but can lead to increasing infrastructure costs as your system scales. On the other hand, building your own solution—such as Reverb—may require more upfront work but offer long-term savings.
For a system managing thousands of devices, scaling horizontally (adding more servers) or vertically (boosting the power of existing servers) can help absorb some of these costs. However, you’ll need to be mindful of the trade-offs in efficiency, particularly around high read/write loads.
Conclusion and Best Practices
When deciding whether to use device-based or user-based channels for real-time updates, it’s essential to consider:
- The ratio of devices to users.
- The cost of reads vs. writes in your system.
- The potential impact on user experience, particularly for lower-end client devices.
For most systems where devices outnumber users, a device-based channel approach will be more efficient. However, always evaluate the specifics of your infrastructure and benchmark performance before committing to one method.
Best Practices:
- Start with benchmarking to understand your system’s read/write operations.
- Choose your notification strategy based on your system’s architecture and scaling potential.
- Consider long-term costs and infrastructure trade-offs before deciding to build or use third-party services
- Unlearn and revisit past opinions to problem at hands. A good solution might not be especially to your product/project.