Serialized RPC arguments or return values are limited to 1MiB
When trying to move to a Service Binding oriented architecture between workers, I bumped into the following error:
Serialized RPC arguments or return values are limited to 1MiB
This is happening when trying to transmit a large dataset through a service binding to the worker that handles DB operations. The array of data (trimmed as much as possible to an array of arrays) is just over 1 MB in size.
It feels strange that I may need to break this data up into multiple RPC calls to get past this limitation when doing it over HTTP worked just fine.
1. Is it possible to up this limit for a worker?
2. Do I have other options?
Thanks!9 Replies
Hi, I think you should be able to pass around larger amounts of data with streams - although I haven't specifically tested the size limit, they should work with any size, even larger than the worker memory size (unbuffered of course, which doesn't count here).
So if instead of using an array as the argument, you pass in a readablestream, you should be able to read from the service binding what you pipe in from your caller and vice versa.
@Purple Blob thanks for the input. Are you aware of any code examples of how to do with with RPC service bindings?
Also, the documentation notes that the Stream API is only available within a
fetch
event. Do I have this or other options within a scheduled
event?
For anyone who stumbles into this thread... I managed to figure this out (thanks Cursor IDE).
Worker making the RPC call with a large payload...
Consumer worker with RPC method...
hey I just want to revive this discussion on a related note.
instead of streaming, I'm trying to modify the work I'm doing within the Worker to ensure that the return value is smaller than the 1MiB limit before returning it.
I use the above, but I notice that the value returned and the actual value shown when an error is thrown can be quite different.
How can I reliably check what is the size of a return value before returning it?
Thanks in advance!
@DaniFoldi
i have a differnt approach if my callee fails due to the 1mib limit, I call a new handler on the RPC which accepts chunks of args, assembles them and calls the initial function locally with no 1mib limit
if my return fails due to large response size, i check the error, and re-call the same RPC handler with a streaming flag which then returns the response as a stream instead
For me this works since large requests and responses are an edge case and the happy path defaults to no streaming 99.999% of the time
Do you mind sharing some example code of how you do this? š
I wonder if I can adapt this to my problem, I suspect itās a little different because Iām using Cloudflare Workflows and they try to save the 1MiB return value from each step of the workflow hmm
Sorry I missed your reply - unfortunately I donāt think thereās a good way since itās stored as a byte stream, not a stringified (base64 or otherwise) version.
They donāt have a built-in api since the exact encoding isnāt guaranteed and āshould be transparent to the userā
You can try opening an issue on GitHub on the workerd repo, since it is a fair question in my opinion, and the team might have a better answer for you
All good! Do you mind elaborating on the āshould be transparent to the userā part? That is, we should not have to think about this?
My code isn't suited to post here for the whole thing, but this is the key part which handles the stream processing on the caller side. Note the closure function I pass in is the actual RPC call.
on the callee side, I wrap my response in something like this if i want to stream the response
which in my case, is called on the RPC callee side in the response handler
`
for added efficiency, I save the response in memory on the callee side so I don't have to reprocess it, but my RPC callee is a durable object which will maintain the state in memory for a few seconds which is enough for me
Thank you this is very helpful!