Imagine that we want to serve a web application to thousands of users. The information on the page should stay up to date even if the user does not actively refresh the page. At the moment, we have two ways to achieve this:
- Setup subscriptions to the data that may change via GraphQL
- Setup periodic queries to GraphQL on a loaded page
Here are some thoughts:
- A change in the data should be visible to the client after maximum 30s. So periodic queries would need to run every 30s at least.
- Let’s say 1000 users have our page open at the same time, even if they are not actively looking at it. If we query every 30s, that will generate a base load of 33.3 queries/second even if nobody actively requests a new view or refreshes.
- On the “worst” view, there are maybe 60 data points that would individually update via subscriptions. So 1000 open tabs would be 60k open subscriptions.
We are wondering which solution scales better / is recommended.
- Is it best to have thousands of subscriptions running (essentially thousands of open TCP sockets powering the websocket connections) or is it better to query again and again for barely changing data?
- How big is the “steady-state”/”heartbeat” load of the open websocket connections for the subscriptions?
- From a server perspective, will the open websockets or the periodic queries require more CPU load for the GraphQL server?
If you have experience with such a trade-off, it would be great if you could share it.
1 Answer
Reset to default
GraphQL Subscriptions
Real-time Updates: GraphQL subscriptions are designed to provide real-time updates to clients. This is particularly beneficial for applications where immediate data changes need to be reflected on the user interface. Changes made by one user can be instantly seen by others who are viewing the same data.
Reduced Network Traffic: Subscriptions send data only when there’s an actual change, which can lead to less data being transferred over the network compared to periodic querying. This can be especially important for mobile devices or users with limited bandwidth.
Complexity: Implementing subscriptions can be more complex than periodic querying, as it involves setting up and managing WebSocket connections on both the client and server. Server-side handling of subscriptions requires additional infrastructure, such as a WebSocket server.
User Experience: Subscriptions provide a more seamless and interactive user experience, as updates are pushed to the client in real-time. Applications that require collaboration or communication between users benefit from this immediate feedback.
Periodic Querying
Predictable Load: Periodic querying generates a steady load on the server since requests are sent at regular intervals. This predictability can make resource allocation and scaling more straightforward.
Bandwidth Consumption: Periodic querying can consume more bandwidth compared to subscriptions, especially when there are frequent updates. However, the impact can be mitigated by using efficient caching mechanisms.
Server Efficiency: Periodic queries can be processed in bulk, potentially allowing the server to optimize and batch requests. However, if too many clients synchronize their queries simultaneously, it might lead to performance bottlenecks.
Latency: Periodic querying introduces latency between data changes and updates on the client. The client may not reflect the latest data until the next query.
Hybrid Approach
Critical vs. Non-Critical Data: Consider using subscriptions for critical data that needs to be updated in real-time and periodic queries for less time-sensitive data.
This balances the benefits of real-time updates with the efficiency of periodic querying.
Scalability: Depending on your application’s scaling requirements, you might use subscriptions for a subset of users (e.g., premium users or active participants) and rely on periodic querying for others.
Monitoring and Optimization
Resource Management: Regardless of the approach, it’s crucial to monitor resource utilization, including memory, CPU, and network usage. Properly managing resources ensures optimal performance and scalability.
Latency Analysis: In latency-sensitive applications, compare the time it takes for updates to reach clients via subscriptions to the delay introduced by periodic querying.
Load Testing: Run load tests in various scenarios to see how each approach performs at different levels of user activity.
Caching: Use smart caching strategies to reduce server load and bandwidth consumption by minimizing redundant queries or duplicate subscription updates.
2
-
Could you please give this very generic answer a bit more body by sharing personal experiences and recommendations?
– Gert Arnold29 mins ago
-
Well, THB, this reads like something that may have been pasted from an external source, esp. since, so far, nothing in your profile history testified of any GraphQL affiliation (although it’s fair to say that this history isn’t really long yet).
– Gert Arnold25 mins ago
or ask your own question.
|