# Low-Latency Write Volume Configuration

## Overview

The Nekuti Matching Engine writes every command to command files before processing them (write-ahead logging). During high-volume periods, the engine optimizes for throughput by writing in larger chunks. I/O contention on the write volume can impact latency, particularly if the snapshotter shares a volume with the engine. To maintain consistently fast write performance, you can configure a separate low-latency volume dedicated to command file writes.

## Use Cases

Configure a separate command write volume when you need:
- **Fast hardware isolation**: Dedicated NVMe storage for command writes
- **IOPS quota separation**: Independent cloud storage IOPS allocation
- **Latency consistency**: Protection from interference by other processes (e.g., snapshotter operations)

## Configuration

### Docker Volume Setup

!!! This setup must be applied simultaneously to both the engine and snapshotter, otherwise they may take inconsistent action, corrupting the engine state.
!!!

Mount the low-latency volume in your Docker configuration:

```yaml
volumes:
  - /path/to/fast-storage:/app/lowlatency
```
Ensure the mounted directory is writable by the engine process.

### Environment Variable Configuration

Enable low-latency command writing by setting:

```yaml
    environment:
      - ENGINE_COMMAND_DIRECTORY=/app/lowlatency
```

Once configured, the engine will write all command files to this fast storage path instead of the default persistence directory. The snapshotter will move older command files to the archive path once snapshots are generated.

## Migration and Off-boarding

### Moving Away from Low-Latency Volume

To transition back to standard persistence storage, undefine the command directory and set the read directory:

```yaml
    environment:
      - ENGINE_PERSISTENCE_READ_DIRECTORY=/app/lowlatency
```

!!! If ENGINE_COMMAND_DIRECTORY is undefined or no longer points to the volume where the most recent commands were written, then data can be lost and the engine state can become inconsistent or corrupted. Always ensure that when offboarding the low-latency directory, ENGINE_PERSISTENCE_READ_DIRECTORY is pointed to the fully-mounted and writable path until all snapshots have been generated and the directory becomes empty. 
!!!

3. **Restart the engine**: New command files will be written to the default persistence directory (`/app/persistence`)

4. **Wait for snapshotter cleanup**: The snapshotter will automatically move remaining command files to the archive directory

5. **Unmount when empty**: Once the low-latency directory is completely empty, it can be safely unmounted

## Directory Environment Variables

The engine supports fine-grained control over storage locations through these environment variables:

| Variable | Purpose | Default |
|----------|---------|---------|
| `ENGINE_COMMAND_DIRECTORY` | Fast/low-latency path for initial command writes | `/app/persistence` |
| `ENGINE_SNAPSHOT_DIRECTORY` | Location for snapshot generation and storage | `/app/persistence` |
| `ENGINE_ARCHIVE_DIRECTORY` | Destination for older snapshots and command files | `/app/persistence/archived` |
| `ENGINE_PERSISTENCE_READ_DIRECTORY` | Read-only source for command files during startup | Not set |

### Directory Relationships

- **Command files** are initially written to `ENGINE_COMMAND_DIRECTORY`
- **Snapshots** are created in `ENGINE_SNAPSHOT_DIRECTORY`
- **Archived files** are moved to `ENGINE_ARCHIVE_DIRECTORY` by the snapshotter
- **Read directory** allows reading commands from a different location during startup

## Operational Workflow

### Normal Operation
1. Engine writes commands to `ENGINE_COMMAND_DIRECTORY`
2. Snapshotter generates snapshots in `ENGINE_SNAPSHOT_DIRECTORY`
3. After snapshot completion, snapshotter moves older command files and snapshots to `ENGINE_ARCHIVE_DIRECTORY`

### Performance Isolation
The separation ensures that:
- Command writes always use the fastest available storage
- Snapshotter operations don't interfere with command write latency
- Archive operations don't impact real-time performance
