How Meetily Stores Meetings, Transcripts, and Summaries in SQLite

Meetily persists all meeting-related data—including transcripts, summaries, and metadata—in a local SQLite database managed by the DatabaseManager struct in the Tauri backend, using sqlx for migrations and connection pooling.

The open-source meeting assistant Meetily (Zackriya-Solutions/meetily) stores every recording, transcription, and AI-generated summary locally using SQLite. This architecture ensures your sensitive meeting data never leaves your device while providing fast, reliable access to historical records. Understanding how Meetily structures its SQLite database reveals the robust data layer powering this privacy-focused application.

Database Architecture and Initialization

The database lifecycle is orchestrated by DatabaseManager in frontend/src-tauri/src/database/manager.rs. This Rust struct handles path resolution, connection pooling, and schema migrations automatically when the application starts.

DatabaseManager and Connection Pooling

When the app launches, DatabaseManager::new_from_app_handle constructs the full path to meeting_minutes.sqlite in the user's application-data directory (e.g., ~/Library/Application Support/Meetily/ on macOS). It initializes a pooled SqlitePool connection using SqlitePool::connect and provides a with_transaction helper for atomic operations. The manager also performs WAL (Write-Ahead Logging) cleanup on shutdown via PRAGMA wal_checkpoint(TRUNCATE) to flush pending writes and remove temporary files.

Migration System

Meetily uses sqlx::migrate!("./migrations") to apply version-controlled schema changes located in frontend/src-tauri/migrations. The system automatically runs migration scripts on startup, ensuring the database schema stays synchronized with the application code. Initial schema creation happens in 20250916100000_initial_schema.sql, while subsequent files like 20251101000000_add_summary_backup.sql and 20251223000000_add_meeting_notes.sql incrementally add tables for summaries and notes.

Core Database Schema

The SQLite schema separates concerns across specialized tables to maintain data integrity and query performance.

Meetings Table

The meetings table stores high-level session metadata including id, title, start_ts, and end_ts. Later migrations such as 20251006000000_add_audio_sync_fields.sql extend this table with audio synchronization metadata like audio_offset.

Transcripts and Speakers Tables

Raw transcription data lives in the transcripts table with columns for meeting_id, speaker_id, text, and ts (timestamp). The 20251110000001_add_speaker_field.sql migration enhanced speaker tracking, while the speakers table maintains distinct speaker identities with id and name columns.

Summaries and Notes Tables

AI-generated meeting summaries are stored in the summaries table (added via 20251101000000_add_summary_backup.sql), while user-created notes reside in meeting_notes (from 20251223000000_add_meeting_notes.sql). Both tables maintain foreign key relationships to the meetings table.

Data Persistence Flow

Meetily's storage pipeline moves audio data through transcription and into SQLite via Tauri commands.

  1. Audio Capture: The application records raw microphone and system audio streams.
  2. Transcription: Speech segments are processed by the Whisper engine, returning text fragments.
  3. Storage: Tauri commands insert transcript rows into the transcripts table, linking them to the active meeting_id and identified speaker_id.
  4. Summary Generation: Post-meeting, AI-generated summaries are written to the summaries table for persistent retrieval.

Working with the Database

Developers can interact with Meetily's storage layer using the DatabaseManager API and sqlx query macros.

To insert a new meeting:

let db = DatabaseManager::new_from_app_handle(&app_handle).await?;

sqlx::query!(
    "INSERT INTO meetings (title, start_ts) VALUES (?, ?)",
    "Team Stand‑up",
    chrono::Utc::now().timestamp()
)
.execute(db.pool())
.await?;

To save transcript fragments during recording:

sqlx::query!(
    "INSERT INTO transcripts (meeting_id, speaker_id, text, ts) VALUES (?, ?, ?, ?)",
    meeting_id,
    speaker_id,
    "We need to finalize the budget.",
    chrono::Utc::now().timestamp()
)
.execute(db.pool())
.await?;

To retrieve transcripts for playback or export:

let rows = sqlx::query!(
    "SELECT text, ts FROM transcripts WHERE meeting_id = ? ORDER BY ts",
    meeting_id
)
.fetch_all(db.pool())
.await?;

Summary

  • Meetily uses a local SQLite database (meeting_minutes.sqlite) managed by the DatabaseManager struct in frontend/src-tauri/src/database/manager.rs.
  • The sqlx migration system in frontend/src-tauri/migrations handles schema evolution, including tables for meetings, transcripts, speakers, summaries, and meeting_notes.
  • Connection pooling via SqlitePool ensures efficient concurrent access, while WAL management guarantees data durability.
  • All meeting metadata, transcription segments, and AI summaries are stored locally with foreign key relationships maintaining data consistency.

Frequently Asked Questions

Where is the Meetily SQLite database stored?

Meetily stores the meeting_minutes.sqlite file in the user's application-data directory, such as ~/Library/Application Support/Meetily/ on macOS or the equivalent Windows/Linux paths. The DatabaseManager::new_from_app_handle function constructs this path dynamically based on the Tauri app handle.

How does Meetily handle database schema updates?

Meetily uses sqlx::migrate!("./migrations") to automatically apply migration scripts from frontend/src-tauri/migrations on application startup. This system runs incremental SQL files—like 20250916100000_initial_schema.sql for initial tables and 20251101000000_add_summary_backup.sql for summary support—ensuring seamless schema evolution without data loss.

What tables does Meetily use to store meeting data?

The core tables include meetings (session metadata), transcripts (speech-to-text segments), speakers (participant identities), summaries (AI-generated meeting recaps), and meeting_notes (user annotations). Additional tables like settings store API keys and configuration data added via migrations such as 20250920155811_add_openrouter_api_key.sql.

How does Meetily ensure data integrity during writes?

The DatabaseManager provides a with_transaction helper that wraps operations in SQLite transactions, ensuring atomic commits or rollbacks. Additionally, WAL (Write-Ahead Logging) mode is used for concurrent read/write safety, and PRAGMA wal_checkpoint(TRUNCATE) runs on shutdown to flush pending changes and prevent corruption.

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 →