I am developing a Meteor app which just started getting traffic (thousands of concurrent sessions according to Google Analytics). Under such load the Meteor servers (hosted on AWS) return a high rate of 5xx responses.
The bulk part of the requests (99%) are read-only requests: subscriptions to collections which rarely change.
I’m looking for ways to dramatically reduce the Meteor servers load. Any ideas are welcome!
I’ve already reduced the subscriptions to the minimal amount of data necessary and followed advice given by Meteor-scaling blogs (such as mongodb indexing by relevant keys, using replica sets, users w/oplog tailing permissions). Nevertheless, the servers are still 5xxing and I’m guessing it’s because of the large amount of subscriptions.
As such, I’m willing to have the clients close most subscriptions after they receive data. Basically - converting the comm to (REST/AJAX)-like requests, only over DDP. Later on I plan to gradually and selectively increase the amount of open subscriptions.
I’ve searched how to properly stop a subscription. There seem to be a few methods, however they are bit ambiguous TMHO. I didn’t gain confidence that a specific solution is better.
Option 1
According to the Meteor docs, on the client it’s possible to:
let handler = Meteor.subscribe('items');
...
// subscription no longer necessary
handler.stop();
This option seems short, but after getting laggy client behavior I’ve discovered that when handler.stop()
is called, the server sends multuple removed
ddp messages (one for each document which the client subscribed to). In subscriptions where lots of documents are involved, this wastes time and bandwidth. I’ve noticed this also delayed new pending subscriptions which need bandwidth on the ddp channel.
I’d prefer an efficient way, as in dropping the whole subscription via one ddp message. Which leads me to:
Option 2
Actively end the subscription on the server in response to a new empty-subscription client request, as in:
Meteor.publish("items", function(criteria) {
if (criteria) {
return Messages.find({
someField: criteria
});
} else {
return this.stop();
}
});
The problem with this approach is that AFAIK it’s not documented. I’ve bumped into it in a stackoverflow post so maybe it is wildly used?
Does anyone have experience with efficiently shutting down subscriptions on high-traffic meteor environments?
What’s the best method in your opinion?
Thanks!