# Architecture of Meetily's Incremental Saver for Preventing Data Loss During Recordings

> Explore Meetily's incremental saver architecture. Discover how its Rust core uses checkpoint files and atomic persistence to prevent data loss in recordings, even during crashes.

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

---

**Meetily's incremental saver architecture employs a Tauri-based Rust core that writes audio chunks to numbered checkpoint files in real-time while atomically persisting transcript updates, ensuring meeting data survives unexpected crashes or power failures.**

Meetily, developed by Zackriya-Solutions, is an open-source meeting recording application that captures audio locally using a robust Rust backend. The architecture of Meetily's incremental saver implements a multi-layered persistence strategy that combines checkpoint-based audio storage with atomic file operations to eliminate data loss risks during active recordings.

## Core Components of the Incremental Architecture

Meetily's data protection system relies on three cooperating components that handle different aspects of the persistence lifecycle.

### 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. Its **`new()`** constructor initializes a clean state, while **`start_accumulation(auto_save)`** opens an unbounded channel for audio chunks and conditionally initializes the checkpoint system.

When `auto_save` is true, the orchestrator calls **`initialize_meeting_folder(..., true)`** to create the `.checkpoints` subdirectory alongside the standard meeting folder hierarchy. The saver also maintains an in-memory vector of transcript segments, immediately persisting each update to [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json) via **`add_transcript_segment()`** whenever new transcription data arrives.

### IncrementalAudioSaver: Real-Time Checkpoint Management

The **`IncrementalAudioSaver`** struct 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 with **`IncrementalAudioSaver::new(meeting_folder.clone(), 48_000)`**, where the second parameter specifies the audio sample rate (48 kHz).

During active recording, each incoming `AudioChunk` structure is immediately written to disk via **`saver_guard.add_chunk(chunk)`** inside the async accumulation loop. The saver creates numbered checkpoint files for each chunk, ensuring that already-written data survives even if the process terminates unexpectedly. When recording stops, **`finalize()`** merges all checkpoint files into the final `audio.mp4` output.

### Atomic File Writers for Metadata Integrity

To prevent corruption of JSON metadata, Meetily uses atomic file replacement operations. Both **`write_metadata`** and **`write_transcripts_json`** functions create temporary files first, then use **`std::fs::rename`** to atomically replace the existing files. This temp-then-rename pattern ensures that power failures never leave partially written [`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) files on disk.

## The Incremental Saving Process

The architecture implements a four-stage pipeline that continuously protects data from capture to finalization.

### Initialization and Folder Structure

The process begins with **`create_meeting_folder`** from [`frontend/src-tauri/src/audio/audio_processing.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/audio_processing.rs), which constructs the directory hierarchy at the base recordings path (typically `~/Library/Application Support/Meetily/recordings`). The function creates `<meeting-name>/` and optionally `<meeting-name>/.checkpoints/` when checkpoint mode is enabled.

### Real-Time Chunk Persistence

While recording, the system operates on an unbounded channel receiving `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). Each chunk is serialized to a separate numbered file in the `.checkpoints` directory immediately upon arrival, providing chunk-by-chunk persistence that minimizes data loss windows to milliseconds rather than minutes.

### Graceful Finalization

When the user stops recording, the **`stop_and_save`** method disables the accumulation loop and waits for in-flight chunks to complete. It then calls **`incremental_saver.finalize()`** to merge all checkpoint files into the final `audio.mp4`. After successful merge, the method updates [`metadata.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/metadata.json) status to `"completed"` and emits a Tauri event `"recording-saved"` containing the final file paths.

## Data Loss Prevention Mechanisms

Meetily implements four specific technical safeguards to ensure recording integrity:

- **Chunk-by-Chunk Persistence**: Each `AudioChunk` is written to a separate checkpoint file immediately upon receipt, ensuring that crash events only lose the most recent milliseconds of audio rather than the entire recording.

- **Atomic Metadata Updates**: All JSON file updates use a temporary file followed by `std::fs::rename`, guaranteeing that [`metadata.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/metadata.json) and [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json) never exist in a partially written state.

- **Graceful Shutdown Sequences**: The `stop_and_save` method properly drains the audio channel before finalization, ensuring that buffers are flushed to disk before the merge operation begins.

- **Optional Auto-Save Modes**: When `auto_save` is set to `false`, the system disables audio checkpointing while maintaining transcript persistence, allowing users to prioritize transcription data over audio storage during resource-constrained scenarios.

## Implementation Example

The following Rust code demonstrates the complete lifecycle of the incremental saver:

```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());

```

## Summary

- **RecordingSaver** in [`recording_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_saver.rs) orchestrates the saving flow, managing meeting folders and transcript persistence.
- **IncrementalAudioSaver** in [`incremental_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/incremental_saver.rs) handles checkpoint-based audio storage using 48 kHz sample rate configurations.
- **Atomic file operations** via temp-then-rename ensure [`metadata.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/metadata.json) and [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json) integrity during power failures.
- **Checkpoint files** in the `.checkpoints` subdirectory provide chunk-level recovery capabilities for audio data.
- **Graceful finalization** merges checkpoints into `audio.mp4` only after all chunks are safely persisted to disk.

## Frequently Asked Questions

### How does Meetily prevent data loss if the application crashes during recording?

Meetily writes each audio chunk to a separate numbered checkpoint file in the `.checkpoints` directory immediately upon receipt. Because these writes occur before the chunk is acknowledged as processed, already-written checkpoints remain on disk even if the application crashes. When the application restarts, the finalization logic can recover from the last successful checkpoint, ensuring minimal data loss limited to only the most recent unwritten milliseconds.

### Where are the incremental checkpoint files stored during a recording?

The checkpoint files are stored in a `.checkpoints` subdirectory within the meeting folder, located at `~/Library/Application Support/Meetily/recordings/<meeting-name>/` on macOS. This folder structure is created by the **`create_meeting_folder`** function in [`audio_processing.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/audio_processing.rs) when `initialize_meeting_folder` is called with the `create_checkpoints` parameter set to `true` at the start of recording.

### What is the difference between auto-save enabled and disabled modes?

When **`start_accumulation(true)`** is called, the system instantiates an `IncrementalAudioSaver` that writes every audio chunk to numbered checkpoint files. When set to `false`, the audio checkpointing is disabled, but the system continues to persist transcript data to [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json) using atomic writes. This mode protects transcription data while eliminating the disk I/O overhead associated with continuous audio checkpointing.

### How does Meetily ensure transcript files are not corrupted during writes?

The system uses atomic file replacement operations implemented in [`recording_saver.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_saver.rs). Both **`write_metadata`** and **`write_transcripts_json`** write new content to temporary files first, then use **`std::fs::rename`** to atomically replace the existing files. This approach ensures that the original file remains intact until the new content is completely written, preventing corruption from partial writes caused by application crashes or system power loss.