As discussed in the documentation, all of the KV APIs allow you to specify Durability Requirements. Also, @matthew.groves has a good blog that goes into some of the details of the semantics.
There is a design philosophy behind this. Not all requests from the app are equal, and only the application developer has the context to know if in memory on two nodes is considered durable enough or if on disk on four nodes is considered durable enough. Unlike traditional databases where this is only express-able at the database configuration/definition level, in Couchbase you can scope it to the operation. In systems like Couchbase, the app is more in control of things like schema, durability and so on.
This makes sense, in our opinion, as some updates are simple status/telemetry that will be updated with more details soon and you don’t want to pay the latency cost and others are very important and your app will want to handle very carefully any errors that come about. Of course, there are some stages in between.
Worth thinking about also: the tradeoff for durability is availability. Here in the modern, distributed world-- do you consider it durable if it’s ‘on disk’ on an ephemeral node? Probably not. Also, what will you do if, at least temporarily, a mutation can’t make it to multiple nodes. The good thing about our design is you are in control. (I should probably write a blog on this!)
I should also mention that for Couchbase Server EE subscribers, there is a Multi-Cluster for Java component that enables high availability writes (among other things) across clusters.
Hope that helps and feel free to ask any additional questions.