Is UpsertAsync in Couchbase really asynchronous?

The question has been raised in Stack:

In short, I upserted 10000 documents to Couchbase, and it took like 6 seconds to complete that. But if I switch to JAVA, it only takes 1.6 seconds. While in JAVA, the non-async version took 3.4 seconds, so I am now suspecting if the UpsertAsync in .NET is really asynchronous.

Unfortunately, operation speed doesn’t necessarily directly relate to synchronicity. I can assure you that the operation itself across the network is asynchronous. However, how the calling code is written and how that interacts with specifics of the .NET and Couchbase .NET SDK can be a factor.

First of all, while the overall operation is asynchronous, the initial CPU-bound steps of the operation are generally synchronous. This includes serializing any JSON for the request and building the binary operation to be sent over the wire. This means that if your approach is to start 10,000 operations from one thread then await them all using Task.WhenAll (or similar) then all of the CPU bound portion of the operation start are on a single core. This is the problem I see in the linked StackOverflow thread.

This approach is generally more efficient for most use cases (i.e. a web server serving hundreds of simultaneous requests) because it assumes parallelization of incoming requests and avoids added latency of queueing the serialization work to be picked up by other threads. However, it can be less efficient when performing bulk operations. This can be mitigated by using constructs like await Parallel.ForEachAsync(...) to parallelize the operations.

Additionally, tools like Parallel.ForEachAsync can help manage throughput by avoiding starting too many simultaneous operations. Trying to send 10k operations over the wire simultaneously isn’t the most efficient approach, as it front-loads too much work with serialization, etc, and can require a lot of memory as well. Instead, managing the total number of simultaneous operations based on factors like hardware, network, and cluster size will allow for greater overall throughput.

2 Likes

Yes. See GitHub - couchbase/couchbase-net-client: The official Couchbase SDK for .NET Core and Full Frameworks

I ran the same C# test and was able to insert the 10,000 documents in 1.3 seconds. After increasing NumKvConnections to 8, it ran in under 1 second.

Similarly, the Java loaddriver utility was able to insert 28,000 documents in 1 second (which works out to 10,000 documents in 0.36 seconds).

It seems that whatever you are using is about 5x slower than me (macbook pro).

Details are on your stackoverflow thread.