> 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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.rumi.systems/performance/benchmark-suite/modules/persistence-module.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
