# How Meetily’s Incremental Audio Saver Ensures Recording Persistence During Crashes and Power Loss

> Discover how Meetily's incremental audio saver ensures recording persistence during crashes and power loss by writing audio to disk in 30-second atomic checkpoint files for automated recovery.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: how-to-guide
- Published: 2026-08-02

---

**Meetily’s incremental audio saver writes raw audio to disk in 30-second atomic checkpoint files, enabling complete recording recovery after unexpected crashes or power failures through automated FFmpeg merging.**

Meetily is an open-source meeting assistant built with Tauri and Rust. Its **incremental audio saver** module ensures no recorded audio is lost during system interruptions by persisting data to disk every 30 seconds rather than buffering entirely in memory.

## Core Architecture of the Two-Stage Pipeline

The system implements a **two-stage pipeline** that separates continuous audio capture from final file assembly. This design minimizes memory usage while maximizing durability against process termination.

### The 30-Second Checkpoint Strategy

In [`frontend/src-tauri/src/audio/incremental_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/incremental_saver.rs), the `add_chunk()` method (lines 52-70) accumulates audio samples and monitors the total count against `checkpoint_interval_samples`. When the buffer reaches the 30-second threshold, the system triggers `save_checkpoint()` to flush data to disk.

This frequent flushing ensures that **maximum data loss is limited to 30 seconds** of audio if a crash occurs between checkpoints.

## Atomic Checkpoint Persistence

Each checkpoint file is written using atomic operations to prevent corruption during write operations or power loss.

### Safe File Writing in save_checkpoint()

The `save_checkpoint()` implementation (lines 77-90 in [`incremental_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/incremental_saver.rs)) encodes buffered samples to MP4 format using `encode_single_audio`, then writes to a temporary location before renaming. This **atomic rename operation** guarantees that checkpoint files are never partially written, even if the process terminates mid-write.

Checkpoints are stored in a hidden `.checkpoints/` folder within the meeting directory, keeping intermediate files organized and invisible to users during active recording.

## Graceful Finalization Process

When recording ends normally, the system consolidates all checkpoints into a single output file without re-encoding.

### The finalize() Method

Located at lines 14-45 of [`incremental_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/incremental_saver.rs), `finalize()` first saves any remaining buffered audio as a final checkpoint. It then invokes `merge_checkpoints()` to concatenate all MP4 files using **FFmpeg's concat demuxer**, which combines segments without re-encoding to preserve audio quality and processing speed.

After successful merging, the `.checkpoints/` directory is automatically removed via the `cleanup_checkpoints` command (lines 73-89) to eliminate temporary data.

## Crash Recovery Implementation

If the application crashes or loses power before `finalize()` executes, the checkpoint files remain intact on disk for later reconstruction.

### The recover_audio_from_checkpoints Command

The Tauri command `recover_audio_from_checkpoints` (lines 38-71 in [`incremental_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/incremental_saver.rs)) scans for existing checkpoint files in the `.checkpoints/` folder. It constructs a [`concat_list.txt`](https://github.com/Zackriya-Solutions/meetily/blob/main/concat_list.txt) file and executes the same FFmpeg concatenation process used during normal finalization.

The command returns an `AudioRecoveryStatus` enum indicating whether recovery succeeded, partially succeeded, or failed, allowing the frontend to notify users appropriately.

### Automatic Recovery on Startup

Meetily can invoke this recovery command automatically on application startup. If a meeting folder contains orphaned checkpoints from a previous crash, the system reconstructs the `audio.mp4` file without requiring user intervention.

## Practical Implementation Examples

To enable incremental saving when starting a recording session:

```rust
let mut saver = RecordingSaver::new();
saver.set_meeting_name(Some("Team Sync".into()));
let audio_sender = saver.start_accumulation(true); // true enables incremental saver

// Stream audio chunks from capture pipeline
audio_sender.send(audio_chunk).unwrap();

```

To finalize and merge checkpoints when stopping:

```rust
let final_path = saver
    .stop_and_save(&app_handle, Some(recording_duration))
    .await?
    .expect("Audio was saved");
println!("Final audio stored at {}", final_path);

```

To recover audio after a crash or power loss:

```rust
let recovery = recover_audio_from_checkpoints(
    "/path/to/meeting_folder".into(),
    48000,
).await?;

match recovery.status.as_str() {
    "success" => println!("Recovered: {}", recovery.audio_file_path.unwrap()),
    "partial" => println!("Partial recovery: {}", recovery.message),
    _ => println!("Recovery failed: {}", recovery.message),
}

```

## Key Source Files

The incremental audio saver spans several modules in the `frontend/src-tauri/src/audio/` directory:

- **[`incremental_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/incremental_saver.rs)** – Core checkpoint logic, finalization, and recovery
- **[`recording_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_saver.rs)** – Orchestrates recording sessions and meeting folder creation
- **[`recording_state.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_state.rs)** – Defines the `AudioChunk` structure used for buffering
- **[`ffmpeg.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/ffmpeg.rs)** – Provides `find_ffmpeg_path()` for checkpoint merging
- **[`encode.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/encode.rs)** – Implements `encode_single_audio` for MP4 encoding

## Summary

- **Atomic checkpoints** written every 30 seconds ensure no more than half a minute of audio is at risk during crashes
- **Disk-based persistence** survives process termination and power loss through durable file system operations
- **Automatic recovery** via `recover_audio_from_checkpoints` reconstructs recordings from orphaned checkpoint files
- **FFmpeg concatenation** merges segments without re-encoding, preserving quality and performance
- **Cleanup operations** remove temporary `.checkpoints/` directories only after successful finalization

## Frequently Asked Questions

### How much audio data could be lost during a system crash?

At most 30 seconds of audio. The `checkpoint_interval_samples` threshold triggers a disk write every 30 seconds, meaning any crash occurring between checkpoints only loses the buffered audio since the last successful write to the `.checkpoints/` folder.

### Does the recovery process require manual user intervention?

No. While users can trigger recovery manually via the Tauri command, Meetily can automatically scan for checkpoint files on startup and reconstruct the audio without user action. The `AudioRecoveryStatus` return value indicates whether the operation succeeded, partially succeeded, or failed.

### Why does Meetily use MP4 format for checkpoints instead of raw PCM?

MP4 provides efficient compression while maintaining seekability for FFmpeg concatenation. The `encode_single_audio` function in [`encode.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/encode.rs) handles the encoding, allowing the concat demuxer to merge files without re-encoding, which would be computationally expensive with raw PCM streams.

### Is incremental saving enabled by default in Meetily?

Incremental saving is opt-in via the `start_accumulation(true)` parameter in `RecordingSaver`. When enabled, the system creates the `.checkpoints/` directory and begins the 30-second checkpoint cycle; when disabled, audio remains in memory until finalization.