{"id":1749,"date":"2020-09-24T08:45:01","date_gmt":"2020-09-24T15:45:01","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cosmosdb\/?p=1749"},"modified":"2021-06-07T15:41:25","modified_gmt":"2021-06-07T22:41:25","slug":"enable-content-response-on-write","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/enable-content-response-on-write\/","title":{"rendered":"Optimizing bandwidth in the Azure Cosmos DB .NET SDK"},"content":{"rendered":"<p class=\"wp-block-paragraph\">When we create, update, and even delete an item in our Azure Cosmos containers, the actual body of the item is <strong>always included as part of the service response<\/strong> 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 <strong>we might not be using at all<\/strong>. Wouldn&#8217;t it be great if there was a way to tell the service <strong>not to include it in the response<\/strong>?<\/p>\n<p>&nbsp;<\/p>\n<h3>What is included in a normal operation response?<\/h3>\n<p>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 <a href=\"https:\/\/docs.microsoft.com\/rest\/api\/cosmos-db\/common-cosmosdb-rest-response-headers\" target=\"_blank\" rel=\"noopener noreferrer\">set of known headers<\/a> (request charge, session token, etc.). The <strong>information in the headers<\/strong>, which tends to be <strong>more important<\/strong> in these operations, often <strong>uses the smallest bandwidth<\/strong>.<\/p>\n<p>&nbsp;<\/p>\n<h3>Do we really need the response content?<\/h3>\n<p>Most of the time, we don&#8217;t really do much with the response content, because it&#8217;s what we just defined as input when we made the operation call or we plainly don&#8217;t need it (do we really need the content of the item we just deleted?). Let&#8217;s take a look at two code examples to make it more clear.<\/p>\n<p>https:\/\/gist.github.com\/ealsur\/85c27d994602b95b497ef24ed8f8a41b<\/p>\n<p>In this create operation, extract important information like the <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/request-units\" target=\"_blank\" rel=\"noopener noreferrer\">request units<\/a>, <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/database-transactions-optimistic-concurrency#optimistic-concurrency-control\" target=\"_blank\" rel=\"noopener noreferrer\">ETag<\/a>, or <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/consistency-levels\" target=\"_blank\" rel=\"noopener noreferrer\">Session<\/a> information from the headers, but the &#8220;Resource&#8221; property of the response really has the same information as the original &#8220;item&#8221; variable and we probably are not using it.<\/p>\n<p>https:\/\/gist.github.com\/ealsur\/ee178f458380ad78a9c9fb50a1f1d2e8<\/p>\n<p>In this replace operation, we receive the content of the replaced item again on the &#8220;Resource&#8221; property, that might be hardly used, but that&#8217;s <strong>consuming bandwidth nevertheless<\/strong>.<\/p>\n<p>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! <strong>Wouldn&#8217;t it be great if there was a way to tell the backend not to send the item body back?<\/strong><\/p>\n<p>&nbsp;<\/p>\n<h3>Optimizing our bandwidth<\/h3>\n<p>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 <a href=\"https:\/\/docs.microsoft.com\/dotnet\/api\/microsoft.azure.cosmos.itemrequestoptions.enablecontentresponseonwrite\" target=\"_blank\" rel=\"noopener noreferrer\">part of the ItemRequestOptions<\/a> and is called <strong>EnableContentResponseOnWrite<\/strong>.<\/p>\n<p>When <strong>setting this property to false<\/strong>, the response will no longer include the content mapped to the Resource property and won&#8217;t consume the bandwidth for it.<\/p>\n<p>Using our previous examples:<\/p>\n<p>https:\/\/gist.github.com\/ealsur\/bd0262bf4805bd088f9f10031716a7d2<\/p>\n<p>Now the write operation&#8217;s response, won&#8217;t include the item content, thus reducing the network bandwidth usage.<\/p>\n<p>https:\/\/gist.github.com\/ealsur\/8566693b4c4dbfd3c011b1fc2af13539<\/p>\n<p>The replace operation won&#8217;t include the unnecessary item content either.<\/p>\n<p>&nbsp;<\/p>\n<h3>Does this work when Bulk mode is enabled?<\/h3>\n<p>If you remember our previous posts about the <a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/introducing-bulk-support-in-the-net-sdk\/\" target=\"_blank\" rel=\"noopener noreferrer\">Bulk mode in V3 .NET SDK<\/a>, 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, <strong>yes, EnableContentResponseOnWrite also when Bulk mode is enabled<\/strong>, so make sure you are taking advantage of it if you are not using those response contents!<\/p>\n<p>&nbsp;<\/p>\n<h3>Is there a global configuration?<\/h3>\n<p><strong>Yes<\/strong>! If you want to use the setting across all the operations with the SDK, you can also define it at the <strong>client creation level<\/strong> on the <a href=\"https:\/\/docs.microsoft.com\/dotnet\/api\/microsoft.azure.cosmos.cosmosclientoptions.enablecontentresponseonwrite\" target=\"_blank\" rel=\"noopener\">CosmosClientOptions<\/a>:<\/p>\n<p>https:\/\/gist.github.com\/ealsur\/769d8b0d6594c3642d3db31fa6c325fe<\/p>\n<h3>Is this currently supported in other SDK languages?<\/h3>\n<p>While this post focuses on .NET, you can also see the feature implemented in other SDK languages.<\/p>\n<p>In <strong>Java V4 SDK<\/strong>, the <a href=\"https:\/\/docs.microsoft.com\/java\/api\/com.azure.cosmos.cosmosclientbuilder.contentresponseonwriteenabled\" target=\"_blank\" rel=\"noopener noreferrer\">CosmosClientBuilder has contentResponseOnWriteEnabled<\/a>, which you can set to false, to achieve the same behavior:<\/p>\n<p>https:\/\/gist.github.com\/ealsur\/a5eb1ac1b63100e0d336f26290e6737f<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to optimize the network bandwidth usage in your application by taking advantage of EnableContentResponseOnWrite to avoid getting unneeded content as part of your operations with the Azure Cosmos DB .NET SDK<\/p>\n","protected":false},"author":9477,"featured_media":61,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[14,19],"tags":[],"class_list":["post-1749","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-core-sql-api","category-tips-and-tricks"],"acf":[],"blog_post_summary":"<p>Learn how to optimize the network bandwidth usage in your application by taking advantage of EnableContentResponseOnWrite to avoid getting unneeded content as part of your operations with the Azure Cosmos DB .NET SDK<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/1749","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/users\/9477"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=1749"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/1749\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media\/61"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media?parent=1749"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=1749"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=1749"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}