> For the complete documentation index, see [llms.txt](https://docs.rumi.systems/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rumi.systems/performance/benchmark-suite/modules/persistence-module.md).

# Persistence Module

The Persistence module benchmarks Rumi's persistence mechanisms for messages and data.

## Overview

Rumi provides multiple persistence mechanisms:

* **Message Logger**: Persists individual messages
* **Packet Logger**: Persists message packets
* **Store Logger**: Persists transactional state changes

This benchmark measures the throughput and latency of each persistence mechanism.

## Test Programs

### MessageLogger

**Class**: `com.neeve.perf.persist.MessageLogger`

Benchmarks single-message persistence performance.

### PacketLogger

**Class**: `com.neeve.perf.persist.PacketLogger`

Benchmarks message packet persistence performance.

### StoreLogger

**Class**: `com.neeve.perf.persist.StoreLogger`

Benchmarks transactional state persistence performance.

## Command-Line Parameters

### Common Parameters (All Loggers)

| Short | Long                   | Default | Description                                       |
| ----- | ---------------------- | ------- | ------------------------------------------------- |
| `-c`  | `--count`              | varies  | Number of messages/packets to persist             |
| `-t`  | `--warmupTime`         | 2       | Warmup time in seconds                            |
| `-r`  | `--rate`               | -1      | Persist rate (-1 = unlimited)                     |
| `-i`  | `--initialLogLength`   | 1       | Preallocated log length (GB)                      |
| `-z`  | `--zeroOutInitial`     | false   | Zero out preallocated length                      |
| `-a`  | `--writeBufferSize`    | 8192    | Write buffer size (bytes)                         |
| `-b`  | `--readBufferSize`     | 8192    | Read buffer size (bytes)                          |
| `-f`  | `--flushOnCommit`      | false   | Flush on every commit                             |
| `-y`  | `--syncOnCommit`       | false   | Sync on every commit (MessageLogger, StoreLogger) |
| `-d`  | `--detached`           | false   | Enable detached writes                            |
| `-q`  | `--queueDepth`         | 1024    | Queue depth for detached writes                   |
| `-j`  | `--affinity`           | null    | CPU affinity mask                                 |
| `-a`  | `--noLatencyWrites`    | false   | Don't write latencies to file                     |
| `-b`  | `--printIntervalStats` | false   | Print interval stats                              |
| `-h`  | `--help`               | false   | Print help                                        |

### MessageLogger-Specific

| Short | Long             | Default | Description                  |
| ----- | ---------------- | ------- | ---------------------------- |
| `-k`  | `--logLocation`  | .       | Log directory                |
| `-m`  | `--logMode`      | rw      | Log open mode (rw, rws, rwd) |
| `-n`  | `--numPerCommit` | 1       | Number of writes per commit  |

### PacketLogger-Specific

| Short | Long                            | Default | Description                  |
| ----- | ------------------------------- | ------- | ---------------------------- |
| `-l`  | `--logLocation`                 | .       | Log directory                |
| `-v`  | `--populateStorePacketMetadata` | false   | Populate ODS packet metadata |
| `-e`  | `--readUsingMappedMemory`       | true    | Use memory-mapped reads      |
| `-t`  | `--tail`                        | false   | Concurrent read/write mode   |

### StoreLogger-Specific

| Short | Long                | Default | Description                  |
| ----- | ------------------- | ------- | ---------------------------- |
| `-o`  | `--logMode`         | rw      | Log open mode (rw, rws, rwd) |
| `-n`  | `--numPerCommit`    | 1       | Number of writes per commit  |
| `-k`  | `--lazyDeserialize` | true    | Skip getObject() on read     |

## Running Benchmarks

### Message Logger Test

```bash
$JAVA_HOME/bin/java -cp "libs/*" com.neeve.perf.persist.MessageLogger \
  -k ./logs \
  -c 1000000 \
  -r -1 \
  -f false \
  -y false
```

### Packet Logger Test

```bash
$JAVA_HOME/bin/java -cp "libs/*" com.neeve.perf.persist.PacketLogger \
  -l ./logs \
  -c 1000000 \
  -r -1 \
  -f false \
  -y false
```

### Store Logger Test

```bash
$JAVA_HOME/bin/java -cp "libs/*" com.neeve.perf.persist.StoreLogger \
  -c 1000000 \
  -r -1 \
  -f false \
  -y false
```

## Key Parameters

### flushOnCommit / syncOnCommit

Controls durability vs performance tradeoff:

**false (default)**:

* Higher throughput
* Lower latency
* Data buffered in OS cache
* Risk of data loss on system crash

**true**:

* Guaranteed durability
* Lower throughput
* Higher latency
* Data flushed/synced to physical media

### writeBufferSize

Size of write buffer (default: 8192 bytes):

```bash
-a 65536  # Larger buffer = better throughput
```

## Interpreting Results

### Typical Results (Linux x86-64, NVME SSD)

| Operation     | flushOnWrite=false | flushOnWrite=true |
| ------------- | ------------------ | ----------------- |
| Message Write | \~5-10µs           | \~100-200µs       |
| Packet Write  | \~2-5µs            | \~80-150µs        |
| Store Write   | \~3-8µs            | \~90-180µs        |

### Performance Characteristics

1. **Buffered Writes (flushOnWrite=false)**:
   * High throughput (100K-200K writes/sec)
   * Low latency (few microseconds)
   * Suitable when durability can be relaxed
2. **Synchronous Writes (flushOnWrite=true)**:
   * Lower throughput (5K-10K writes/sec)
   * Higher latency (hundreds of microseconds)
   * Guaranteed durability
   * Required for critical data
3. **Storage Media Impact**:
   * **NVME SSD**: \~100µs sync write latency
   * **SATA SSD**: \~200-500µs sync write latency
   * **HDD**: \~5-10ms sync write latency

## Comparison with AEP Module

The [AEP Module](/performance/benchmark-suite/modules/aep-module.md) uses asynchronous persistence:

* **Persistence Module**: Measures pure persistence overhead
* **AEP Module**: Persistence runs concurrently with replication
* **AEP Impact**: Persistence overlaps with network latency

**In AEP benchmark, persistence adds minimal latency due to pipelining**

## Best Practices

### For High Throughput

1. Use buffered writes (flushOnWrite=false)
2. Increase write buffer size
3. Use NVME storage
4. Consider packet-based logging for batch operations

### For Guaranteed Durability

1. Enable flushOnWrite=true
2. Use NVME or high-performance SSD
3. Consider battery-backed write cache
4. Accept throughput/latency tradeoff

## Next Steps

* Review [AEP Module](/performance/benchmark-suite/modules/aep-module.md) to see persistence in end-to-end context
* Review [Storage Module](/performance/benchmark-suite/modules/storage-module.md) for object store benchmarks
* Return to [Benchmark Suite](/performance/benchmark-suite.md) for other modules
