Optimizing a humbly large node.js response - node.js

I am responding with a large (10 MB) payload from node.js to an Akka spray.io based actor, and getting a chunk size error from spray/akka [akka://spray-actor-system/user/IO-HTTP/group-0/3] Received illegal response: HTTP chunk size exceeds the configured limit of 1048576 bytes.
My node.js code just plainly sends off the response in one res.end command. (It does so because the response is generated in a non-streamed way and therefore there has been no "inherent" gain in streaming it further along, at least up until a spray.io client-side was added).
I am wondering what's the simplest way to chunk the response using node.js api, in case I prefer not handling very large http responses by increasing the spray.io size limit. Also whether there's any performance downside in sending responses this size from node.js - i.e. does node.js block on the res.end operation?

Related

Should I be minimizing connection count or reducing payload size?

What is more important for scalable backend, minimizing number of HTTP requests from clients, or decreasing the bandwidth?
I have a function on the express backend that can return data in 4 different time intervals. I'm not sure if I should be sending all 4 intervals at once to minimize connection count, and then filter out what's necessary on the front end, or send the necessary data per each interval separately as requested by the client to save on bandwidth.
My reasoning is that server can crash because of too many connections, but never from high payloads so approach number one is more intelligent, right?
I'm talking about 15 lines of JSON vs 60 in a file or 1 HTTP request vs 4.

Can aiobotocore be configured to automatically handle rate limiting?

I'm using boto3 to write a lot of objects to S3. I keep hitting an error like:
botocore.exceptions.ClientError: An error occurred (SlowDown) when calling the PutObject operation (reached max retries: 0): Please reduce your request rate.
This is clearly coming from the server and asking my code to slow down the requests it's making. My question is whether there's a way to get aiobotocore to handle this automatically with its retry logic?
It should be theoretically possible for the response to be handled automatically, including a wait. The issue with doing this in my own code is that there are many tasks all hitting the same bucket, so negotiating rate limiting between them will be very complex indeed.

How to limit stream length in node.js

My Node.js web service will accept user uploads. I need to limit maximum number of bytes user can upload. I don't want to rely solely on content-length header since an invalid value can be provided. Is there a way I can limit request stream length I pipe to disk or db?
I thought about stream.Transform that will throw an exception if the stream length is longer than content-length header value. Probably, there is a built-in function?

What should I limit my POST per second rate to?

I'm building out an API using Hapi.js. Some of my code is pushing small amounts of data to the API. The issue seems to be that the pusher code is swamping the API and I'm getting ECONNRESET errors -- which means messages are getting lost. I'm planning on installing a rate-limiter in the pusher code, probably node-rate-limiter (link).
The question is, what should I set that limit to? I want to max out performance for this app, so I could easily be attempting to send in thousands of messages per hour. The data just gets dumped into redis, so I doubt the code in the API will be an issue but I still need to get an idea of what kind of message rate Hapi is comfortable with. Do I need to just start with something reasonable and see how it goes? Maybe 1 message per 10 milliseconds?
Hapi = require('hapi');
server = new (Hapi.Server);
server.connection(port: config.port, routes: {
cors: {
origin: ['*']
}
});
server.route({method: 'POST', path: '/update/{id}', ...})
There is no generic answer to how many requests per second you can process. It depends upon many things in your configuration and code such as:
Type and performance of server hardware
The amount of CPU time an average request uses
Whether your requests are CPU or disk bound. If disk bounded, then it depends a lot on your database and disk performance.
Whether you implement clustering to use multiple cores (if CPU bound)
Whether you're on shared infrastructure or not
The max number of incoming connections your server is configured for
So, there is no absolute answer here that works for everyone. If you don't have some sort of design problem that is artificially limiting your concurrency, then the best way to discover what your server can actually handle is to build a test engine and test it. Find where and how it fails and either fix those issues to extend the scalability further or implement protections to avoid hitting that limit.
Note: When a public API makes rate limiting choices, it is typically done on a per-client basis and the limit is set to a value that seems to be a little above what a reasonable client would be doing. This is more to allow fair use of the server by many clients to that one single client does not consume too much of the overall resource. If issuing thousands of small requests from a single client is not considered "good practice" in using your API, then you can just pick a number that is much smaller than that for a per-client limit.
Note: You may also want to make it easier for clients by having your API let them upload multiple messages in one API request rather than lots of API requests.

what's the best way to limit async send speed based on response handling speed in netty 4?

I'm writing a RPC client, which uses netty4 to do the networking. The client put requests to a map, and after receiving responses the requests' callback is triggered in channel handler and the requests are removed.
During benchmark test, my sending thread seemed to be sending too fast as the response latency increased to ~1 secs.
So what's the best way to control the speed of the sending thread based on the channel handler speed? Do I have to add another blocking queue so that if there are too many requests in the map, the sender got blocked against the queue.
Have you tried setting AUTO_READ option to false for Server Bootstrap. This will control what amount of data you read on one channel before another channel consumes it.

Resources