Optimizing bandwidth in the Azure Cosmos DB .NET SDK
When we create, update, and even delete an item in our Azure Cosmos containers, the actual body of the item is always included as part of the service response along with other useful information in the headers, like the request charge. This body content consumes bandwidth, and if we think about it, we are using almost the same bandwidth to send the operation than to receive its response. When the volume of operations it high, this accounts for quite a big chunk of data over the wire, which we might not be using at all. Wouldn’t it be great if there was a way to tell the service not to include it in the response?
What is included in a normal operation response?
Write operations include create, replace, upsert, and delete item operations. In most of them (except delete), you send a payload with the item content you want to write and when the operation is completed successfully on the Azure Cosmos backend, you receive a response that contains the original item content you sent, a status code indicating the success, and a set of known headers (request charge, session token, etc.). The information in the headers, which tends to be more important in these operations, often uses the smallest bandwidth.
Do we really need the response content?
Most of the time, we don’t really do much with the response content, because it’s what we just defined as input when we made the operation call or we plainly don’t need it (do we really need the content of the item we just deleted?). Let’s take a look at two code examples to make it more clear.
In this create operation, extract important information like the request units, ETag, or Session information from the headers, but the “Resource” property of the response really has the same information as the original “item” variable and we probably are not using it.
In this replace operation, we receive the content of the replaced item again on the “Resource” property, that might be hardly used, but that’s consuming bandwidth nevertheless.
In applications where the item size is large or where the volume of operations is high, this accounts for quite a relevant chunk of network bandwidth, that we could be using to actually send more operations! Wouldn’t it be great if there was a way to tell the backend not to send the item body back?
Optimizing our bandwidth
The Azure Cosmos DB .NET V3 SDK has a feature that you can use, per operation, to avoid the item body in the response. This feature is part of the ItemRequestOptions and is called EnableContentResponseOnWrite.
When setting this property to false, the response will no longer include the content mapped to the Resource property and won’t consume the bandwidth for it.
Using our previous examples:
Now the write operation’s response, won’t include the item content, thus reducing the network bandwidth usage.
The replace operation won’t include the unnecessary item content either.
Does this work when Bulk mode is enabled?
If you remember our previous posts about the Bulk mode in V3 .NET SDK, you know that Bulk is all about optimizing throughput and operational volume. In this case, reducing the network usage is a great step in that same direction (the faster we obtain those responses, the faster we can send new operations!). And the answer is, yes, EnableContentResponseOnWrite also when Bulk mode is enabled, so make sure you are taking advantage of it if you are not using those response contents!
Is there a global configuration?
Yes! If you want to use the setting across all the operations with the SDK, you can also define it at the client creation level on the CosmosClientOptions:
Is this currently supported in other SDK languages?
While this post focuses on .NET, you can also see the feature implemented in other SDK languages.
In Java V4 SDK, the CosmosClientBuilder has contentResponseOnWriteEnabled, which you can set to false, to achieve the same behavior:
And I imagine this would improve speed as well by decreasing the time taken to send the response without the body? My app doesn’t ever read the response body so can see this being a quick win to boost performance by omitting it on upserts.
That is correct. The client doesn’t spend time downloading the response’s body, so it would complete faster.
I feel so cool about this option! Thank you for this article! And I have feedback about the EnableContentResponseOnWrite.
In .NET SDK, I would like to set default behavior for content response on write. For example, I want to default behavior is false about EnableContentResponseOnWrite option, and specific operation require response. (Maybe support that, currently?)
In Java SDK, I would like to set EnableContentResponseOnWrite option when specific operation behavior for content response on write.
Thanks a lot for your feedback!
Could you direct your request to the respective GitHub repos?
* For .NET https://github.com/Azure/azure-cosmos-dotnet-v3/
* For Java https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/cosmos/azure-cosmos
Does this reduce the cost of an operation?
No, it does not.