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

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 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, 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, 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), 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 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 or 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 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:

// 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.

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, 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, 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →