Aerospike memory-size vs data-size: Choosing a Namespace Storage Engine
Choosing between Aerospike's memory and device namespaces is a capacity-versus-latency decision with a hidden RAM cost: the primary index always lives in memory.
08 Sept 2025, 11:52 UTC

You have a key-value dataset that no longer fits comfortably in RAM. Maybe it is a session cache that has grown past your node memory, or a user-profile store where the working set is large but the hot subset is small. The immediate question is whether to keep everything in memory or move record data to flash. In Aerospike, that choice is made per namespace, and it is not just a capacity decision—it changes how reads behave, how writes are buffered, and how hard it is to change your mind later.
The useful takeaway: memory namespaces give you the lowest and most predictable latency, but they are hard-bounded by memory-size. device namespaces extend capacity onto SSDs, but they introduce variable read latency for cold records and require tuning. In both cases, the primary index consumes RAM, so moving data to flash does not eliminate your memory footprint.
What memory and device namespaces actually store
An Aerospike namespace is a container for records, similar to a table in a relational database. Each namespace uses one of two storage engines.
A memory namespace keeps both the record data and the primary index in RAM. The primary index is the in-memory map from primary key to record location; without it, Aerospike cannot find anything. Because everything lives in RAM, reads are fast and predictable, but the namespace is capped by the memory-size parameter. Once that limit is reached, writes fail unless records expire via TTL or are explicitly deleted.
A device namespace stores record data on a block device—typically an SSD—while the primary index remains in RAM. Point lookups by primary key still start in memory, so finding the record is fast. If the record data is not cached, Aerospike fetches it from flash, which adds latency. The namespace is bounded by data-size instead of memory-size.
Inspecting the active configuration
Before changing anything, confirm what your cluster is actually running. The authoritative source is aerospike.conf (commonly /etc/aerospike/aerospike.conf, though the path varies by packaging), but you can query the live configuration with the admin tool.
Run the following from a host that has asadm installed and network access to an Aerospike node. You need administrative privileges on the database, typically via a user with the sys-admin role or equivalent.
asadm -e 'show config namespace'
In the output, a memory-backed namespace declares a memory-size parameter, while a device-backed namespace declares a data-size parameter. Confirm that the active configuration matches your intent; if it does not, the server may be running with an older file or a pending change.
To see how full the namespace is, check namespace statistics:
asadm -e 'show stat namespace'
Compare the objects count against your configured limit. For device namespaces, also watch device_used_pct. For memory namespaces, watch evicted-objects; a non-zero value indicates pressure at the memory ceiling, which means writes may start failing once the limit is reached.
The capacity-versus-latency trade-off
If your dataset is small, hot, and you need the tightest latency distribution, memory is the straightforward choice. The risk is operational: when the namespace fills, new writes stop until space is reclaimed. TTLs help, but only if your data naturally expires.
device storage buys you capacity at a lower dollar-per-GB cost, but it is not a drop-in replacement for RAM. Cold records incur a flash fetch, which introduces read amplification—one logical read can trigger multiple physical I/Os depending on the device and record layout. Under sustained write load, you also need to tune write-cache sizes and defragmentation thresholds; otherwise, background cleanup can cause latency spikes.
There is a hidden cost in both cases: the primary index and any secondary indexes always consume RAM. A device namespace with a very large number of small records can exhaust memory through index growth long before the SSD fills.
Why switching engines later is expensive
The most important limitation is that you cannot flip an existing namespace from memory to device with a rolling restart or a dynamic configuration change. The storage layout is fundamentally different. The supported path is to create a new namespace with the desired engine and migrate data into it, then retire the old namespace. Plan for this before you deploy, because retrofitting a full dataset is a heavier operation than adjusting a size parameter.
Device performance also depends heavily on the underlying SSD and filesystem. Unsupported configurations can increase write amplification or wear the drive prematurely. Very short TTLs on a device namespace do not eliminate cleanup work; expired records still require background scanning and deletion, which adds I/O overhead.
A practical decision path
Start by estimating your steady-state record count and working-set size. If the entire dataset fits in RAM with headroom for index growth, choose memory. If the dataset is large but the hot subset is small, choose device and accept variable read latency for cache misses.
After you deploy, verify the outcome rather than assuming it. Run asadm -e 'show stat namespace' and confirm that objects is stable and device_used_pct or evicted-objects behaves as expected. For a device namespace, deliberately read a record you know is cold and measure the latency difference against a hot read; that gap is your real-world storage fetch penalty. Finally, check the Aerospike documentation for your specific server major version, because device storage parameters and defaults have changed across releases.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.