[PR #15052] Fix: Add VACUUM to database cleanup on shutdown #46240

Open
opened 2026-04-25 01:44:24 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/ollama/ollama/pull/15052
Author: @hnshah
Created: 3/25/2026
Status: 🔄 Open

Base: mainHead: fix-sqlite-vacuum


📝 Commits (1)

  • aef652c Fix: Add VACUUM to database cleanup on shutdown (#15021)

📊 Changes

1 file changed (+13 additions, -0 deletions)

View changed files

📝 app/store/database.go (+13 -0)

📄 Description

Problem

SQLite databases grow indefinitely without VACUUM. Deleted chats and messages mark pages as free but don't return space to the OS. This leads to multi-gigabyte database files that never shrink.

Fixes #15021

Root Cause

The Close() method in app/store/database.go only checkpoints the WAL but never runs VACUUM to reclaim space from deleted records.

Solution

Added VACUUM and REINDEX to the database Close() method:

  • VACUUM reclaims disk space from deleted records
  • REINDEX optimizes query performance
  • Both run on shutdown (safe, no concurrent access)
  • Error handling logs warnings but doesn't fail close

Testing

Environment:

  • macOS 25.3.0
  • M3 Ultra, 256GB RAM
  • Ollama v0.18.2

Results:

  • Built successfully (61MB binary, no warnings)
  • Server starts and responds correctly
  • Test database: 49% space reclaimed after deleting half the data
    • Before delete: 0.56 MB
    • After delete (no VACUUM): 0.57 MB
    • After VACUUM: 0.29 MB
    • Space reclaimed: 0.28 MB (49.0% reduction)

Test code:
Created 10K rows, deleted 5K rows, ran VACUUM - confirmed space reclamation works as expected.

Code Changes

Before:

func (db *database) Close() error {
	_, _ = db.conn.Exec("PRAGMA wal_checkpoint(TRUNCATE);")
	return db.conn.Close()
}

After:

func (db *database) Close() error {
	// Checkpoint WAL to ensure all writes are flushed
	_, _ = db.conn.Exec("PRAGMA wal_checkpoint(TRUNCATE);")

	// Vacuum database to reclaim disk space from deleted records
	if _, err := db.conn.Exec("VACUUM;"); err != nil {
		slog.Warn("failed to vacuum database during close", "error", err)
	}

	// Reindex to optimize query performance after vacuum
	if _, err := db.conn.Exec("REINDEX;"); err != nil {
		slog.Warn("failed to reindex database during close", "error", err)
	}

	return db.conn.Close()
}

Questions

  1. Is shutdown timing acceptable? (VACUUM can take seconds for very large DBs)
  2. Should we add a configuration option?
  3. Should we add a size threshold before running VACUUM?

Happy to test additional scenarios or adjust the approach based on your feedback!


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/ollama/ollama/pull/15052 **Author:** [@hnshah](https://github.com/hnshah) **Created:** 3/25/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix-sqlite-vacuum` --- ### 📝 Commits (1) - [`aef652c`](https://github.com/ollama/ollama/commit/aef652c175c7b81b2eeb9e1370a33325d37966c3) Fix: Add VACUUM to database cleanup on shutdown (#15021) ### 📊 Changes **1 file changed** (+13 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `app/store/database.go` (+13 -0) </details> ### 📄 Description ## Problem SQLite databases grow indefinitely without VACUUM. Deleted chats and messages mark pages as free but don't return space to the OS. This leads to multi-gigabyte database files that never shrink. **Fixes #15021** ## Root Cause The `Close()` method in `app/store/database.go` only checkpoints the WAL but never runs VACUUM to reclaim space from deleted records. ## Solution Added VACUUM and REINDEX to the database Close() method: - `VACUUM` reclaims disk space from deleted records - `REINDEX` optimizes query performance - Both run on shutdown (safe, no concurrent access) - Error handling logs warnings but doesn't fail close ## Testing **Environment:** - macOS 25.3.0 - M3 Ultra, 256GB RAM - Ollama v0.18.2 **Results:** - ✅ Built successfully (61MB binary, no warnings) - ✅ Server starts and responds correctly - ✅ Test database: **49% space reclaimed** after deleting half the data - Before delete: 0.56 MB - After delete (no VACUUM): 0.57 MB - After VACUUM: 0.29 MB - **Space reclaimed: 0.28 MB (49.0% reduction)** **Test code:** Created 10K rows, deleted 5K rows, ran VACUUM - confirmed space reclamation works as expected. ## Code Changes **Before:** ```go func (db *database) Close() error { _, _ = db.conn.Exec("PRAGMA wal_checkpoint(TRUNCATE);") return db.conn.Close() } ``` **After:** ```go func (db *database) Close() error { // Checkpoint WAL to ensure all writes are flushed _, _ = db.conn.Exec("PRAGMA wal_checkpoint(TRUNCATE);") // Vacuum database to reclaim disk space from deleted records if _, err := db.conn.Exec("VACUUM;"); err != nil { slog.Warn("failed to vacuum database during close", "error", err) } // Reindex to optimize query performance after vacuum if _, err := db.conn.Exec("REINDEX;"); err != nil { slog.Warn("failed to reindex database during close", "error", err) } return db.conn.Close() } ``` ## Questions 1. Is shutdown timing acceptable? (VACUUM can take seconds for very large DBs) 2. Should we add a configuration option? 3. Should we add a size threshold before running VACUUM? Happy to test additional scenarios or adjust the approach based on your feedback! --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-25 01:44:25 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/ollama#46240