{"id":17639,"date":"2025-10-16T11:32:57","date_gmt":"2025-10-16T18:32:57","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=17639"},"modified":"2025-10-16T11:34:12","modified_gmt":"2025-10-16T18:34:12","slug":"bulk-get-documents-reactive-synchronous-api","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/bulk-get-documents-reactive-synchronous-api\/","title":{"rendered":"Bulk Get Documents in Couchbase using Reactive or Asynchronous API"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">When working with distributed databases like Couchbase, performance and efficiency are key considerations, especially when retrieving a large amount of data. Many times when customers come from different development or database backgrounds, they ask about the capability of Couchbase to do \u201cmulti-get\u201d or \u201cbulk get\u201d operations.\u00a0 Many databases offer \u201cmulti-get\u201d as an out of the box method to retrieve multiple documents to perform based on their keys. Most Couchbase SDKs don\u2019t offer explicit APIs for batching because reactive programming provides the flexibility to implement batching tailored to your specific use case and is often more effective than a one-size-fits-all, generic method.<\/span><\/p>\n<h2>What is Bulk Get?<\/h2>\n<p><span style=\"font-weight: 400;\">A bulk get operation allows you to request multiple documents in a single operation, rather than making repeated individual GET calls. In traditional key-value stores, each request usually targets a specific node. However, in a distributed environment like Couchbase, spreading these operations across nodes can introduce overhead if managed manually.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">SDK support for bulk operations<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">The Couchbase SDKs (including Java, .NET, and Go) offer built-in support for bulk get operations. These SDK methods are designed to accept a list of document keys and automatically manage the parallel execution of individual <em>OBTER<\/em> requests in an efficient way because of three main reasons.<\/span><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Parallelism<\/strong>: Rather than fetching each document sequentially, the SDKs initiate multiple requests concurrently.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Node targeting<\/strong>: The SDKs intelligently route each request to the correct node in the cluster where the data resides.<br \/>\n<\/span><\/li>\n<li aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Asynchronous execution<\/strong>: Leveraging the asynchronous capabilities of each SDK, the operations are handled in a non-blocking fashion, ensuring higher throughput and better resource utilization.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Couchbase provides two main ways to achieve bulk get capability using Reactive Programming and Async Programming.<\/p>\n<h2>Reactive API<\/h2>\n<p><span style=\"font-weight: 400;\">If you\u2019re aiming to optimize bulk get operations in Couchbase, reactive programming provides an efficient and easier approach. Couchbase&#8217;s binary protocol has out-of-order execution and has strong support for async operations in KV. By efficiently managing asynchronous data flows, it enables high throughput and low latency, making it ideal for distributed systems. To fully leverage its capabilities, a fully reactive stack where each layer, from the database to the client, supports reactive streams is ideal. Couchbase\u2019s <\/span><span style=\"font-weight: 400;\"><i>ReactiveCollection<\/i><\/span><span style=\"font-weight: 400;\"> integrates seamlessly with Project Reactor, enabling fully non-blocking access to Couchbase Key-Value (KV) operations. This integration aligns perfectly with modern reactive architectures, allowing applications to handle high-throughput workloads more efficiently by avoiding unnecessary thread blocking.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">That said, migrating an entire existing application to a reactive architecture can involve significant work. If it is a new project, adopting a reactive framework like Spring WebFlux is strongly recommended. However, even in non-reactive applications, introducing a reactive approach at the Couchbase CRUD layer alone can deliver meaningful gains. By doing so, you can minimize thread blocking and reduce CPU throttling, leading to better resource efficiency and improved scalability.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Below is an example of a Java code that can maximize the performance of Couchbase using Reactive API and can work with a non-reactive stack.<\/span><\/p>\n<pre class=\"nums:false lang:java decode:true\">\/**\r\n\u00a0\u00a0\u00a0* @param collection The collection to get documents from.\r\n\u00a0\u00a0\u00a0* @param documentIds The IDs of the documents to return.\r\n\u00a0\u00a0\u00a0* @param mapSupplier Factory for the returned map. Suggestion:\r\n\u00a0\u00a0\u00a0* Pass {@code TreeMap::new} for sorted results,\r\n\u00a0\u00a0\u00a0* or {@code HashMap::new} for unsorted.\r\n\u00a0\u00a0\u00a0* @param concurrency Limits the number of Couchbases requests in flight\r\n\u00a0\u00a0\u00a0* at the same time. Each invocation of this method has a separate quota.\r\n\u00a0\u00a0\u00a0* Suggestion: Start with 256 and tune as desired.\r\n\u00a0\u00a0\u00a0* @param mapValueTransformerScheduler The scheduler to use for converting\r\n\u00a0\u00a0\u00a0* the result map values. Pass {@link Schedulers#immediate()}\r\n \u00a0\u00a0* to use the SDK's IO scheduler. Suggestion: If your value converter does IO,\r\n\u00a0\u00a0\u00a0* pass {@link Schedulers#boundedElastic()}.\r\n\u00a0\u00a0\u00a0* @param mapValueTransformer A function that takes a document ID and a result,\r\n\u00a0\u00a0\u00a0* and returns the value to associated with that ID in the returned map.\r\n\u00a0\u00a0\u00a0* @param &lt;V&gt; The return map's value type.\r\n\u00a0\u00a0\u00a0* @param &lt;M&gt; The type of the map you'd like to store the results in.\r\n\u00a0\u00a0\u00a0* @return a Map (implementation determined by {@code mapSupplier})\r\n\u00a0\u00a0\u00a0* where each given document ID is associated with the result of\r\n\u00a0\u00a0\u00a0* getting the corresponding document from Couchbase.\r\n\u00a0\u00a0\u00a0*\/\r\n\r\npublic static &lt;V, M extends Map&lt;String, V&gt;&gt; Map&lt;String, V&gt; bulkGet(\r\n\u00a0\u00a0\u00a0\u00a0ReactiveCollection collection,\r\n\u00a0\u00a0\u00a0\u00a0Iterable&lt;String&gt; documentIds,\r\n\u00a0\u00a0\u00a0\u00a0int concurrency,\r\n\u00a0\u00a0\u00a0\u00a0Supplier&lt;M&gt; mapSupplier,\r\n\u00a0\u00a0\u00a0\u00a0Scheduler mapValueTransformerScheduler,\r\n\u00a0\u00a0\u00a0\u00a0BiFunction&lt;String, SuccessOrFailure&lt;GetResult&gt;, V&gt; mapValueTransformer\r\n\u00a0\u00a0) {\r\n\u00a0\u00a0\u00a0\u00a0return Flux.fromIterable(documentIds)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.flatMap(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0documentId -&gt; Mono.zip(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Mono.just(documentId),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0collection.get(documentId)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.map(SuccessOrFailure::success)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.onErrorResume(error -&gt; Mono.just(SuccessOrFailure.failure(error)))\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0concurrency\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.publishOn(mapValueTransformerScheduler)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.collect(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mapSupplier,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(map, idAndResult) -&gt; {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0String documentId = idAndResult.getT1();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SuccessOrFailure&lt;GetResult&gt; successOrFailure = idAndResult.getT2();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0map.put(documentId, mapValueTransformer.apply(documentId, successOrFailure));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.block();\r\n\u00a0\u00a0}\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">This reactive approach is fetching documents using their IDs and returning a <\/span><em><span style=\"font-weight: 400;\"><code>Map&lt;String, V&gt;<\/code><\/span><\/em><span style=\"font-weight: 400;\"> where each key is a document ID and the value is the processed result.<\/span> <span style=\"font-weight: 400;\">While it&#8217;s not wrong to collect the results into a List and reprocess them later, a better strategy (both in terms of performance and code clarity) is to collect the results into a <\/span><em><span style=\"font-weight: 400;\"><code>ConcurrentHashMap<\/code><\/span><\/em><span style=\"font-weight: 400;\"> indexed by document ID. This avoids repeated scanning and makes result lookups constant-time operations. Let&#8217;s break down how this works step-by-step.<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Creating a Reactive stream from document IDs<\/strong><br \/>\nIn line 19, we are creating a <b>Fluxo<\/b> (reactive stream) from the list of document IDs. For each document ID, it calls <em>collection.get(documentId)<\/em> to fetch the document reactively.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><strong>Wrapping results in <em>SuccessOrFailure<\/em><br \/>\n<\/strong>To ensure resilience, each async operation wraps the result in a <em>SuccessOrFailure&lt;GetResult&gt;<\/em> object. This wrapper captures both successful and failed fetches. By default, if<em> collection.get(documentId)<\/em> throws an error (e.g. network issue, missing doc), the whole <em>Fluxo<\/em> stream will error out and stop processing. This is not ideal for bulk operations as we want to continue processing other documents even if one fails. So instead of propagating the error, it converts the failure into a<em> SuccessOrFailure.failure(error)<\/em> object. This way, the downstream still gets a valid value (<em>SuccessOrFailure<\/em>) for every documentID, whether successful or failed.<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><strong>Pairing document IDs with results using <em>Mono.zip<\/em><br \/>\n<\/strong>Usando<em> Mono.zip<\/em> makes it explicit that you\u2019re combining the <em>documentId<\/em> and the async <em>obter<\/em> result into a tuple. This helps identify the association between documentID and result, especially when results arrive out of order due to concurrency.<\/li>\n<li aria-level=\"1\"><em><strong>Concorr\u00eancia<\/strong><\/em><span style=\"font-weight: 400;\"><strong> controles<\/strong> how many document fetches are run in parallel (how many requests are in flight at once).<\/span><\/li>\n<li aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Parallelism and scheduler handoff<\/strong><br \/>\nReactive streams are non-blocking by default, but transformation logic (e.g., parsing JSON, converting data) can be CPU-intensive. Before we collect the resulting tuples, the stream switches to a caller-specified scheduler using <em>publishOn(&#8230;)<\/em>. This offloads the transformation work from IO threads to a separate thread pool. That ensures IO threads aren\u2019t blocked by transformation work due to heavy computation.<br \/>\n<\/span><\/li>\n<li aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Collecting into a map<\/strong><br \/>\nOnce all results are in, the stream collects the tuples pairs into a map. It uses <em>mapSupplier<\/em> to create the map. For each<em> (documentId, result)<\/em> pair, it applies <em>mapValueTransformer<\/em> to transform the raw result into a domain-specific type <em>V<\/em> and then puts the transformed value into the map.<br \/>\n<\/span><\/li>\n<li aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Blocking to retrieve final result<\/strong><br \/>\nSince everything here is asynchronous (non-blocking), <em>block()<\/em> is used to wait for the entire stream to finish and return the constructed <em>mapa<\/em> to the caller.<br \/>\n<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2>Asynchronous API<\/h2>\n<p><span style=\"font-weight: 400;\">While we recommend using the reactive APIs for their performance, flexibility, and built-in backpressure handling, Couchbase also offers a low-level Asynchronous API for scenarios where you need even more fine-grained control and performance tuning. However, writing efficient asynchronous code comes with its own challenges, it requires careful management of concurrency and backpressure to prevent resource exhaustion and avoid timeouts.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Below is an example demonstrating how to use the Async API to enhance bulk get performance in Couchbase:<\/span><\/p>\n<pre class=\"nums:false lang:java decode:true\">\/\/ async api to call get() for an array of keys\r\nList&lt;CompletableFuture&lt;GetResult&gt;&gt; futures = new LinkedList&lt;&gt;();\r\n\r\nfor (int i = 0; i &lt; keys.size(); i++) {\r\n\u00a0\u00a0\u00a0\u00a0CompletableFuture&lt;GetResult&gt; f = collection.async().get(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0keys.get(i),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0(GetOptions) options\r\n\u00a0\u00a0\u00a0\u00a0);\r\n\u00a0\u00a0\u00a0\u00a0futures.add(f);\r\n}\r\n\r\n\/\/ Wait for all Get operations to complete\r\nCompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();\r\n\r\n\/\/ Convert results to JsonObjects\r\nList&lt;JsonObject&gt; results = new LinkedList&lt;&gt;();\r\n\r\nfor (CompletableFuture&lt;GetResult&gt; future : futures) {\r\n\u00a0\u00a0\u00a0\u00a0try {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0JsonObject json = future.join().contentAsObject();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0results.add(json);\r\n\u00a0\u00a0\u00a0\u00a0} catch (CompletionException e) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0e.printStackTrace();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0results.add(null); \/\/ or skip \/ handle differently\r\n\u00a0\u00a0\u00a0\u00a0}\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Let&#8217;s break down how this works step-by-step.<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Fetch documents<\/strong><br \/>\nHere we iterate over keys and for each key, we call <em>collection.async().get(key, options)<\/em>, which returns a <em>CompletableFuture&lt;GetResult&gt;<\/em> and then we store all those futures in a list.<br \/>\n<\/span><\/li>\n<li aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Wait for all fetches to finish<\/strong><br \/>\n<em>CompletableFuture.allOf(&#8230;)<\/em> creates a new future that completes when all futures in the array complete<em>.<\/em><em>.join()<\/em> blocks the current thread until all async fetches are done.<br \/>\n<\/span><\/li>\n<li aria-level=\"1\"><span style=\"font-weight: 400;\"><strong>Transform results<\/strong><br \/>\nOnce all the fetches are done, we create another list to hold final values in plain <em>List&lt;JsonObject&gt;<\/em>. For each <em>CompletableFuture&lt;GetResult&gt;<\/em>, we retrieve and transform the result. Depending on the requirement, you can handle the failure error by either adding <em>nulo<\/em> to the list in place of the failed result or an error marker object.<br \/>\nThe transformation step assumes that fetching the documents is complete prior to transforming results, however, If the goal is to continue chaining async operations then we can create a list if futures <em>List&lt;CompletableFuture&lt;JsonObject&gt;&gt;<\/em> and wrap the transformation in another async wrapper.<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>We recommend using this API only if you are either writing integration code for higher level concurrency mechanisms or you really need the last drop of performance. In all other cases, the reactive API (for richness in operators) is likely the better choice.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p><span style=\"font-weight: 400;\">Reactive programming offers one of the most efficient ways to achieve high performance for bulk get operations with Couchbase. Its true power is unlocked when applied across an entirely reactive stack, where non-blocking behavior and scalability are fully optimized.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">That said, you don&#8217;t need a fully reactive architecture to start reaping the benefits. A practical and impactful first step is to migrate just the Couchbase CRUD layer to reactive. Doing so can dramatically reduce thread blocking and minimize CPU throttling, leading to better system responsiveness and resource utilization without requiring a complete architectural overhaul.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If performance and scalability are priorities, reactive programming is well worth the investment, even in a partial implementation.<\/span><\/p>\n<hr \/>\n<p><em><span style=\"font-weight: 400;\">The author acknowledges the Couchbase SDK team and their excellent explanation on how we can achieve the batching efficiently without the need for a generic bulk get function, thank you.<\/span><\/em><\/p>\n<p><br style=\"font-weight: 400;\" \/><br style=\"font-weight: 400;\" \/><\/p>","protected":false},"excerpt":{"rendered":"<p>When working with distributed databases like Couchbase, performance and efficiency are key considerations, especially when retrieving a large amount of data. Many times when customers come from different development or database backgrounds, they ask about the capability of Couchbase to [&hellip;]<\/p>","protected":false},"author":85517,"featured_media":17640,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1811,1814,1816,1820,1818,2201],"tags":[1437,1516],"ppma_author":[10017],"class_list":["post-17639","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-application-design","category-couchbase-server","category-golang","category-java","category-tools-sdks","tag-async","tag-reactive"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Bulk Get Documents in Couchbase using Reactive or Asynchronous API - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"Introducing a reactive approach at the Couchbase CRUD layer alone can deliver meaningful gains, leading to better resource efficiency and scalability.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/bulk-get-documents-reactive-synchronous-api\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Bulk Get Documents in Couchbase using Reactive or Asynchronous API\" \/>\n<meta property=\"og:description\" content=\"Introducing a reactive approach at the Couchbase CRUD layer alone can deliver meaningful gains, leading to better resource efficiency and scalability.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/bulk-get-documents-reactive-synchronous-api\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-16T18:32:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-16T18:34:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents-1024x536.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"536\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Rohit Kumar, Sr. Solutions Engineer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Rohit Kumar, Sr. Solutions Engineer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/\"},\"author\":{\"name\":\"Rohit Kumar, Sr. Solutions Engineer\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/82c0b7ad32f97f54dcae300546cc382c\"},\"headline\":\"Bulk Get Documents in Couchbase using Reactive or Asynchronous API\",\"datePublished\":\"2025-10-16T18:32:57+00:00\",\"dateModified\":\"2025-10-16T18:34:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/\"},\"wordCount\":1385,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents.png\",\"keywords\":[\"async\",\"Reactive\"],\"articleSection\":[\".NET\",\"Application Design\",\"Couchbase Server\",\"GoLang\",\"Java\",\"Tools &amp; SDKs\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/\",\"name\":\"Bulk Get Documents in Couchbase using Reactive or Asynchronous API - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents.png\",\"datePublished\":\"2025-10-16T18:32:57+00:00\",\"dateModified\":\"2025-10-16T18:34:12+00:00\",\"description\":\"Introducing a reactive approach at the Couchbase CRUD layer alone can deliver meaningful gains, leading to better resource efficiency and scalability.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents.png\",\"width\":2400,\"height\":1256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Bulk Get Documents in Couchbase using Reactive or Asynchronous API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/82c0b7ad32f97f54dcae300546cc382c\",\"name\":\"Rohit Kumar, Sr. Solutions Engineer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/bb41f6e793c4f310548c1fc7afea6ba4\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/09\/rohitkukmar-couchbase.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/09\/rohitkukmar-couchbase.png\",\"caption\":\"Rohit Kumar, Sr. Solutions Engineer\"},\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/rohitkumar\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Bulk Get Documents in Couchbase using Reactive or Asynchronous API - The Couchbase Blog","description":"Introducing a reactive approach at the Couchbase CRUD layer alone can deliver meaningful gains, leading to better resource efficiency and scalability.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/bulk-get-documents-reactive-synchronous-api\/","og_locale":"pt_BR","og_type":"article","og_title":"Bulk Get Documents in Couchbase using Reactive or Asynchronous API","og_description":"Introducing a reactive approach at the Couchbase CRUD layer alone can deliver meaningful gains, leading to better resource efficiency and scalability.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/bulk-get-documents-reactive-synchronous-api\/","og_site_name":"The Couchbase Blog","article_published_time":"2025-10-16T18:32:57+00:00","article_modified_time":"2025-10-16T18:34:12+00:00","og_image":[{"width":1024,"height":536,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents-1024x536.png","type":"image\/png"}],"author":"Rohit Kumar, Sr. Solutions Engineer","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Rohit Kumar, Sr. Solutions Engineer","Est. reading time":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/"},"author":{"name":"Rohit Kumar, Sr. Solutions Engineer","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/82c0b7ad32f97f54dcae300546cc382c"},"headline":"Bulk Get Documents in Couchbase using Reactive or Asynchronous API","datePublished":"2025-10-16T18:32:57+00:00","dateModified":"2025-10-16T18:34:12+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/"},"wordCount":1385,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents.png","keywords":["async","Reactive"],"articleSection":[".NET","Application Design","Couchbase Server","GoLang","Java","Tools &amp; SDKs"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/","url":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/","name":"Bulk Get Documents in Couchbase using Reactive or Asynchronous API - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents.png","datePublished":"2025-10-16T18:32:57+00:00","dateModified":"2025-10-16T18:34:12+00:00","description":"Introducing a reactive approach at the Couchbase CRUD layer alone can deliver meaningful gains, leading to better resource efficiency and scalability.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/10\/blog-couchbase-bulk-get-documents.png","width":2400,"height":1256},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/bulk-get-documents-reactive-synchronous-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Bulk Get Documents in Couchbase using Reactive or Asynchronous API"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/82c0b7ad32f97f54dcae300546cc382c","name":"Rohit Kumar, engenheiro de solu\u00e7\u00f5es s\u00eanior","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/bb41f6e793c4f310548c1fc7afea6ba4","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/09\/rohitkukmar-couchbase.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/09\/rohitkukmar-couchbase.png","caption":"Rohit Kumar, Sr. Solutions Engineer"},"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/rohitkumar\/"}]}},"authors":[{"term_id":10017,"user_id":85517,"is_guest":0,"slug":"rohitkumar","display_name":"Rohit Kumar, Sr. Solutions Engineer","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/09\/rohitkukmar-couchbase.png","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/09\/rohitkukmar-couchbase.png"},"author_category":"","last_name":"Kumar, Sr. Solutions Engineer","first_name":"Rohit","job_title":"","user_url":"","description":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/17639","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/85517"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=17639"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/17639\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/17640"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=17639"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=17639"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=17639"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=17639"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}