# How Meetily's Incremental Saver Prevents Data Loss During Recording: A Technical Deep Dive

> Discover how Meetily's incremental saver prevents data loss during recording by writing audio chunks and transcript updates in real-time to checkpoint files for guaranteed data recovery.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: deep-dive
- Published: 2026-07-22

---

**Meetily's incremental saver prevents data loss by writing audio chunks to numbered checkpoint files in real-time while atomically persisting transcript updates, ensuring that even if the application crashes or power is lost, all recorded data up to the last checkpoint remains recoverable from the filesystem.**

Meetily is an open-source meeting recording application built with a **Tauri-based Rust core** that captures audio locally on your machine. To protect against unexpected crashes, power failures, or abrupt application termination during active recordings, the system implements a robust incremental saving architecture that persists data chunk-by-chunk rather than buffering everything in memory until the session ends. This approach ensures that both audio streams and transcription segments survive unexpected termination, allowing users to recover meetings from the last successfully written checkpoint.

## Core Architecture: Three Cooperating Components

The incremental saving system consists of three primary components working together to orchestrate data persistence. Each component handles a specific aspect of the recording lifecycle, from folder creation to final audio merging.

### RecordingSaver: The Central Orchestrator

The **`RecordingSaver`** struct in [`frontend/src-tauri/src/audio/recording_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/recording_saver.rs) manages the entire saving flow and serves as the primary interface between the recording pipeline and the filesystem. When instantiated via `RecordingSaver::new()`, it initializes a clean state for a new meeting session【/frontend/src-tauri/src/audio/recording_saver.rs#L36-L45】.

The `start_accumulation(auto_save)` method opens an unbounded channel for audio chunks and, when `auto_save` is enabled, calls `initialize_meeting_folder(..., true)` to establish the checkpoint system. During recording, `add_transcript_segment()` appends transcription segments to an in-memory vector and immediately persists them to [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json), ensuring text data never remains in volatile memory for extended periods【/frontend/src-tauri/src/audio/recording_saver.rs#L94-L119】.

### IncrementalAudioSaver: Real-Time Checkpoint Creation

The **`IncrementalAudioSaver`** struct, defined 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), handles the audio-specific persistence logic. It is instantiated only when checkpointing is required, receiving the meeting folder path and sample rate (48,000 Hz) via `IncrementalAudioSaver::new(meeting_folder.clone(), 48_000)`【/frontend/src-tauri/src/audio/recording_saver.rs#L38-L45】.

Within the async accumulation loop, each incoming `AudioChunk` is immediately forwarded to the saver via `saver_guard.add_chunk(chunk)`【/frontend/src-tauri/src/audio/recording_saver.rs#L96-L104】. Rather than accumulating audio in memory, the saver writes each chunk to a separate numbered checkpoint file on disk, creating a sequence of incremental audio fragments that can survive application crashes.

### Folder Structure and Preferences

The **`RecordingPreferences`** module and `audio_processing::create_meeting_folder` utility establish the physical storage hierarchy. When `initialize_meeting_folder` is called, it invokes `create_meeting_folder(&base_folder, meeting_name, create_checkpoints)` to build the directory structure within the base recordings directory (typically `~/Library/Application Support/Meetily/recordings` on macOS)【/frontend/src-tauri/src/audio/recording_saver.rs#L30-L36】.

When checkpoints are enabled, the system creates a `.checkpoints` subdirectory inside the meeting folder to house the temporary audio fragments before final merging.

## Chunk-by-Chunk Persistence Strategy

The primary defense against data loss is **chunk-by-chunk persistence**. As the audio capture pipeline produces `AudioChunk` structures (defined in [`frontend/src-tauri/src/audio/recording_state.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/recording_state.rs)), the `IncrementalAudioSaver` immediately writes each chunk to a numbered checkpoint file on the filesystem.

This approach guarantees that if the application crashes or the system loses power, the already-written checkpoints remain intact on disk. Unlike traditional recording systems that buffer the entire audio stream in RAM and write a single file at the end, Meetily's incremental approach ensures that the only data lost is the small portion currently being processed in memory, typically representing less than a second of recording time.

## Atomic Metadata and Transcript Updates

Beyond audio data, Meetily protects meeting metadata and transcription segments through **atomic file operations**. Both `write_metadata` and `write_transcripts_json` functions in [`recording_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_saver.rs) implement a write-to-temp-then-rename pattern to prevent partially written files【/frontend/src-tauri/src/audio/recording_saver.rs#L73-L84】【/frontend/src-tauri/src/audio/recording_saver.rs#L85-L100】.

When updating [`metadata.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/metadata.json) or [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json), the system first writes the new content to a temporary file, then uses `std::fs::rename` to atomically replace the existing file. This ensures that a power loss or crash during a write operation never leaves a corrupted or truncated JSON file on disk. The transcript file stores an array of `TranscriptSegment` objects, each containing timing information, confidence scores, and text content, all preserved with the same atomic guarantees.

## Graceful Finalization and Recovery

When the user stops recording, the **`stop_and_save`** method orchestrates a graceful shutdown sequence. First, it disables the accumulation loop and allows any in-flight chunks to finish processing. Then it calls `incremental_saver.finalize()` to merge all numbered checkpoint files into the final `audio.mp4` container【/frontend/src-tauri/src/audio/recording_saver.rs#L82-L90】.

Even if the finalization process is interrupted, the individual checkpoint files remain available for manual recovery. The method updates [`metadata.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/metadata.json) to mark the recording as `"completed"` and emits a Tauri event `"recording-saved"` containing the file paths for both the final audio and transcript files, notifying the frontend that the operation succeeded【/frontend/src-tauri/src/audio/recording_saver.rs#L99-L108】.

## Optional Auto-Save Configuration

The incremental system supports flexible configuration through the `auto_save` parameter in `start_accumulation()`. When set to `false`, the system disables audio checkpointing while maintaining atomic transcript persistence. This mode is useful for users who prioritize disk space over audio recovery, as it eliminates the storage overhead of checkpoint files while still protecting transcription data through the same atomic JSON writes.

## Practical Implementation Example

The following Rust code demonstrates the complete lifecycle of Meetily's incremental saving system, from initialization to finalization:

```rust
// 1️⃣ Create a saver and start recording with auto-save enabled
let mut saver = RecordingSaver::new();
saver.set_meeting_name(Some("Team Standup".into()));
let audio_sender = saver.start_accumulation(true); // true → enable incremental audio saver

// 2️⃣ During recording, feed raw audio chunks (produced by the capture pipeline)
audio_sender.send(audio_chunk).unwrap();

// 3️⃣ Add a transcript segment – the saver writes it to disk immediately
saver.add_transcript_segment(TranscriptSegment {
    id: "seg_001".into(),
    text: "Welcome everyone".into(),
    audio_start_time: 0.0,
    audio_end_time: 2.1,
    duration: 2.1,
    display_time: "[00:00]".into(),
    confidence: 0.98,
    sequence_id: 1,
});

// 4️⃣ When the user stops recording, finalize everything
let final_path = saver.stop_and_save(&app_handle, Some(recording_seconds)).await?;
println!("Saved final audio to {}", final_path.unwrap());

```

This pattern ensures that every audio chunk and transcript segment is persisted to disk as soon as it is generated, minimizing the window of vulnerability to data loss.

## Summary

- **Chunk-by-chunk persistence**: Each `AudioChunk` is immediately written to a numbered checkpoint file in the `.checkpoints` directory, ensuring minimal data loss during crashes.
- **Atomic file operations**: Metadata and transcript updates use temporary files followed by `std::fs::rename` to prevent corruption during power failures.
- **Graceful degradation**: If finalization fails, individual checkpoint files remain recoverable and can be manually merged or processed.
- **Configurable protection**: The `auto_save` parameter allows users to disable audio checkpointing while maintaining transcript persistence to balance safety against disk usage.
- **Tauri integration**: The system emits `"recording-saved"` events to notify the frontend of successful completion, with all file paths resolved through the Rust core in [`frontend/src-tauri/src/audio/recording_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/recording_saver.rs).

## Frequently Asked Questions

### How does Meetily recover data if the application crashes during an active recording?

If Meetily crashes while recording, the **checkpoint files** written by `IncrementalAudioSaver` remain intact in the `.checkpoints` subdirectory of the meeting folder. Each chunk is saved as a separate numbered file the moment it arrives, so only the audio currently being processed in memory (typically less than one second) is lost. Users can recover the meeting by locating these checkpoint files in the meeting directory and processing them through the standard finalization pipeline or external tools.

### What is the difference between checkpoint files and the final audio file?

**Checkpoint files** are temporary audio fragments written incrementally during recording to prevent data loss, while the **final audio file** (`audio.mp4`) is created only when `stop_and_save()` calls `incremental_saver.finalize()`. The finalization process merges all checkpoint files into a single container and removes the temporary fragments. Checkpoints exist only to provide crash recovery; they are not meant for direct playback and are cleaned up after successful finalization.

### Can I disable incremental saving to reduce disk space usage?

Yes. When calling `start_accumulation(auto_save)`, passing `false` for the `auto_save` parameter disables the `IncrementalAudioSaver` entirely, preventing the creation of checkpoint files. In this mode, only transcript data is persisted atomically to [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json), which significantly reduces disk I/O and storage requirements. However, audio data will not survive a crash unless the recording is properly finalized, making this mode suitable only for non-critical recordings or systems with limited storage.

### Where are the checkpoint files and recordings stored on my system?

Meetily stores recordings in the base directory provided by `RecordingPreferences`, which defaults to `~/Library/Application Support/Meetily/recordings` on macOS and equivalent paths on other platforms. Each meeting receives its own subfolder containing [`metadata.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/metadata.json), [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json), and optionally a `.checkpoints` directory housing the incremental audio fragments. The final merged audio is saved as `audio.mp4` in the meeting's root folder after successful finalization.