# How to Configure Volumes with Journaling Modes for Data Integrity in Apple Container

> Configure Apple Container volumes with journaling modes for data integrity. Learn how to use the journal driver option to protect your data during ext4 image formatting.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-21

---

**Configure volumes with journaling modes by passing the `--opt journal=<mode>[:<size>]` driver option to `container volume create`, which the `VolumesService` parses into an `EXT4.JournalConfig` and applies during the ext4 image formatting process.**

The Apple Container project stores volume data on ext4-formatted block devices and exposes fine-grained control over data integrity through configurable journaling modes. When you create a volume, you can select between three journaling strategies that trade off performance against crash safety guarantees. This guide explains how to configure volumes with journaling modes using both CLI commands and Swift API calls, referencing the implementation in [`Sources/Services/ContainerAPIService/Server/Volumes/VolumesService.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Volumes/VolumesService.swift).

## Understanding Journaling Modes and Data Integrity Guarantees

The Container runtime supports the three standard ext4 journaling modes. Each mode determines what gets written to the journal and how strictly data ordering is enforced:

- **ordered** – Metadata is journaled, and data is written to storage before its metadata is committed. This is the kernel default and offers a balance of safety and speed.
- **writeback** – Only metadata is journaled; data ordering relative to metadata commits is not guaranteed. This provides the fastest performance but the least safety.
- **journal** – Both metadata and data are journaled, providing the highest level of protection against corruption at the cost of increased write amplification.

According to the command reference in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md) (lines 886‑893), you specify these modes through the `journal` driver option when creating a volume.

## Implementation Flow in VolumesService

When you create a volume with a journaling option, the `VolumesService` handles the configuration through a three-phase process before the filesystem is created.

### Parsing the Driver Option (Lines 339‑340)

The service extracts the `journal` value from the driver options dictionary. This occurs in the volume creation flow where the service validates input parameters before formatting the block device.

```swift
let journalConfig = try driverOpts["journal"].map { try Self.parseJournalConfig($0) }

```

### Validating Mode and Size with parseJournalConfig (Lines 269‑288)

The static method `parseJournalConfig` validates the mode string and optional size suffix. It splits the input on the colon character, maps the mode string to an `EXT4.JournalConfig.JournalMode` enum case, and converts size suffixes (like `64m` or `1g`) to bytes.

```swift
static func parseJournalConfig(_ value: String) throws -> EXT4.JournalConfig {
    let parts = value.split(separator: ":", maxSplits: 1)
    // ...
    switch modeString {
        case "writeback": mode = .writeback
        case "ordered":   mode = .ordered
        case "journal":   mode = .journal
        // ...
    }
    let size = // ... optional size parsing
    return EXT4.JournalConfig(size: size, defaultMode: mode)
}

```

### Creating the EXT4 Image with Journal Configuration (Lines 290‑299)

The validated `JournalConfig` is passed to the `EXT4.Formatter` initializer when creating the underlying image file. This is the point where the journaling mode is actually applied to the filesystem structures on disk.

```swift
let formatter = try EXT4.Formatter(
    FilePath(blockPath),
    blockSize: 4096,
    minDiskSize: sizeInBytes,
    journal: journal
)

```

## Configuring Volumes via the Command Line

Use the `--opt` flag to specify the journaling mode and optional journal size when creating volumes. The syntax follows the pattern `journal=<mode>[:<size>]`.

```bash

# Ordered journaling with default journal size (balanced safety/performance)

container volume create --opt journal=ordered myvolume

# Writeback journaling with a 64 MiB journal (fastest, least safe)

container volume create --opt journal=writeback:64m myvolume

# Full data journaling with explicit 10 GiB volume size (highest integrity)

container volume create \
    --opt journal=journal \
    --opt size=10g \
    myvolume

```

## Programmatic Configuration with Swift

You can configure journaling modes programmatically by passing the same driver options to the `VolumesService` API. The Swift implementation mirrors the CLI behavior, using the `parseJournalConfig` method internally.

```swift
import ContainerAPIService

let volumes = try await VolumesService(
    resourceRoot: rootPath,
    containersService: containers,
    log: logger
)

// Driver options dictionary uses the same keys as the CLI
let driverOptions: [String: String] = [
    "journal": "writeback:64m",  // mode and optional size
    "size": "10g"                // overall volume size
]

let volume = try await volumes.create(
    name: "myvolume",
    driver: "local",
    driverOpts: driverOptions,
    labels: [:]
)

print("Created volume '\(volume.name)' with journal mode \(driverOptions["journal"]!)")

```

## Summary

- Apple Container supports three ext4 journaling modes—**`ordered`**, **`writeback`**, and **`journal`**—that configure the trade-off between data integrity and performance.
- Configure the mode using the `--opt journal=<mode>[:<size>]` syntax when running `container volume create`.
- The `VolumesService.parseJournalConfig` method (lines 269‑288) validates the mode string and optional size before filesystem creation.
- Journal configuration is applied during volume creation via `EXT4.Formatter` in [`VolumesService.swift`](https://github.com/apple/container/blob/main/VolumesService.swift) (lines 290‑299).

## Frequently Asked Questions

### What is the default journaling mode if I don't specify the journal option?

If you omit the `journal` driver option, the Container runtime does not explicitly set a mode, allowing the ext4 kernel default (typically `ordered`) to apply. However, volumes created without this option will not have custom journal sizing unless explicitly specified.

### Can I change the journaling mode on an existing volume?

No, the journaling mode is determined at volume creation time when `EXT4.Formatter` initializes the filesystem image. To change modes, you must create a new volume with the desired `journal` option and migrate your data.

### How does the journal size parameter affect performance?

Larger journal sizes allow more transactions to be buffered before committing to disk, which can improve write throughput for bursty workloads but increases memory usage and filesystem check time after a crash. The size suffix (e.g., `64m`, `1g`) configures the dedicated journal area on the block device.

### Which journaling mode should I use for maximum data integrity?

Use the **`journal`** mode (full data journaling) when you require the highest level of data integrity, as it journals both metadata and file contents. This prevents data corruption at the cost of significantly higher write amplification compared to `ordered` or `writeback` modes.