Couchbase evicts data from RAM when it runs out of memory, but you can control what gets evicted based on your workload.
Let’s see this in action. Imagine a busy Couchbase cluster where memory is getting tight. We’ve got a beer-sample dataset loaded, and we’re performing a mix of reads and writes.
# Simulate some writes
for i in {1..10000}; do
couchbase-cli document put \
--cluster 127.0.0.1:8091 \
--bucket beer-sample \
--user Administrator \
--password password \
--id "doc_id_$i" \
--data '{"key": "value", "count": '"$i"'}'
done
# Simulate some reads (this will cause contention for memory)
for i in {1..5000}; do
couchbase-cli document get \
--cluster 127.0.0.1:8091 \
--bucket beer-sample \
--user Administrator \
--password password \
--id "doc_id_$((RANDOM % 10000))"
done
As memory pressure increases, Couchbase needs to make space. The eviction policy dictates how it chooses which documents to remove from RAM. The primary goal is to keep the most valuable data readily available, minimizing disk I/O for subsequent requests.
There are two main eviction policies: fullEvict and valueEvict.
valueEvict (the default): This policy evicts only the value of a document, not its metadata. The document’s key, CAS (Check-And-Set) value, and other metadata remain in RAM. This is generally preferred for read-heavy workloads because it means that even if a document’s value is evicted, Couchbase can still quickly check if it exists and retrieve its metadata. If the value is needed again, it can be reloaded from disk. This is efficient when you have many more keys than can fit in memory but still want fast lookups.
fullEvict: This policy evicts both the document’s value and its metadata from RAM. The document is effectively removed from memory until it’s accessed again, at which point it’s reloaded from disk. This is useful for write-heavy workloads or when you have a very large number of documents, and even metadata for all of them doesn’t fit comfortably in RAM. By evicting both value and metadata, you free up more memory for active data.
You configure this on a per-bucket basis. Let’s say you have a bucket named my-app-bucket and you want to set it to fullEvict.
couchbase-cli bucket-edit \
--cluster 127.0.0.1:8091 \
--bucket my-app-bucket \
--user Administrator \
--password password \
--eviction-policy fullEvict
To switch back to the default valueEvict:
couchbase-cli bucket-edit \
--cluster 127.0.0.1:8091 \
--bucket my-app-bucket \
--user Administrator \
--password password \
--eviction-policy valueEvict
The eviction-policy setting is a crucial lever for tuning memory usage. On nodes with limited RAM, choosing the right policy can prevent performance degradation due to excessive disk reads. If your workload consists of many short-lived documents or a very high volume of writes where older data is less likely to be accessed, fullEvict might be more appropriate. For scenarios where you have a massive dataset but frequently access a subset of keys, valueEvict allows for quicker checks of document existence even when values are swapped out.
A common misconception is that valueEvict keeps the "document" in memory. It’s more accurate to say it keeps the key and associated metadata in memory, allowing for fast existence checks and metadata retrieval, while the actual data payload is flushed to disk. This distinction is key to understanding why it’s beneficial for read-heavy workloads.
Beyond fullEvict and valueEvict, there’s also a less common offlineEvict which is primarily for offline data synchronization scenarios and not typically relevant for active cluster operations. The choice between fullEvict and valueEvict hinges on the balance between your dataset size, memory available, and read-vs-write patterns.
Once you’ve tuned your eviction policy, the next challenge is often optimizing disk I/O for data that has been evicted.