### Run S3 Backend Example with Environment Variables Source: https://github.com/benbjohnson/litestream/blob/main/_examples/library/README.md Navigate to the 's3' directory and set the required AWS and Litestream environment variables before running the Go program. This example demonstrates restoring from S3 and background replication. ```bash cd s3 # Set required environment variables export AWS_ACCESS_KEY_ID="your-access-key" export AWS_SECRET_ACCESS_KEY="your-secret-key" export LITESTREAM_BUCKET="your-bucket-name" export LITESTREAM_PATH="databases/myapp" # optional, defaults to "litestream" export AWS_REGION="us-east-1" # optional, defaults to "us-east-1" go run main.go ``` -------------------------------- ### SQLite File Structure Example Source: https://github.com/benbjohnson/litestream/blob/main/docs/SQLITE_INTERNALS.md Illustrates the typical files associated with an SQLite database when using the WAL mode. ```text database.db # Main database file (pages) database.db-wal # Write-ahead log database.db-shm # Shared memory file ``` -------------------------------- ### Verify Test Environment Setup Source: https://github.com/benbjohnson/litestream/blob/main/cmd/litestream-test/scripts/README.md Executes the script to validate the test environment setup, including required binaries and dependencies. ```bash ./cmd/litestream-test/scripts/verify-test-setup.sh ``` -------------------------------- ### Find Code Examples in Docs Source: https://github.com/benbjohnson/litestream/blob/main/docs/DOC_MAINTENANCE.md Use `rg` to search for fenced code blocks in documentation files. This helps locate all Go code examples. ```bash # Find all code examples in documentation rg "^(```(go|golang))" docs/ CLAUDE.md AGENTS.md .claude/ ``` -------------------------------- ### Setup Homebrew Tap Script Source: https://github.com/benbjohnson/litestream/blob/main/scripts/README.md Automates the setup of a Homebrew tap for Litestream distribution. This script is part of the release process. ```bash ./scripts/setup-homebrew-tap.sh ``` -------------------------------- ### Reading an LTX File with Go Source: https://github.com/benbjohnson/litestream/blob/main/skills/litestream/references/LTX_FORMAT.md Go code example demonstrating how to read an LTX file using `ltx.NewDecoder`, including decoding the header, pages, and trailer. ```go dec := ltx.NewDecoder(reader) header, err := dec.Header() for { var hdr ltx.PageHeader data := make([]byte, header.PageSize) if err := dec.DecodePage(&hdr, data); err == io.EOF { break } // Process hdr.Pgno and data } trailer := dec.Trailer() ``` -------------------------------- ### Run Basic File Backend Example Source: https://github.com/benbjohnson/litestream/blob/main/_examples/library/README.md Navigate to the 'basic' directory and run the Go program to set up local filesystem replication. This creates a database file and a replica directory. ```bash cd basic go run main.go ``` -------------------------------- ### Verify Test Environment Setup Source: https://github.com/benbjohnson/litestream/blob/main/cmd/litestream-test/scripts/README.md Executes scripts to verify the test environment setup before running other tests. This ensures all prerequisites are met for reliable testing. ```bash ./cmd/litestream-test/scripts/verify-test-setup.sh ./cmd/litestream-test/scripts/test-rapid-checkpoints.sh ``` -------------------------------- ### LTX Filename Convention Example Source: https://github.com/benbjohnson/litestream/blob/main/skills/litestream/references/LTX_FORMAT.md Illustrates the naming convention for LTX files, which includes the minimum and maximum transaction IDs. ```text Format: MMMMMMMMMMMMMMMM-NNNNNNNNNNNNNNNN.ltx MinTXID (16 hex) MaxTXID (16 hex) Example: 0000000000000001-0000000000000064.ltx (TXID 1-100) 0000000000000065-00000000000000c8.ltx (TXID 101-200) ``` -------------------------------- ### v0.3.x Path Structure Example Source: https://github.com/benbjohnson/litestream/blob/main/docs/REPLICA_CLIENT_GUIDE.md Illustrates the file path structure used for v0.3.x Litestream backups, including generations, snapshots, and WAL segments. ```text generations/ {generation-id}/ # 16-char hex (validated by IsGenerationIDV3) snapshots/ {index:08x}.snapshot.lz4 wal/ {index:08x}_{offset:08x}.wal.lz4 ``` -------------------------------- ### Example Vague Test Plan (Bash) Source: https://github.com/benbjohnson/litestream/blob/main/AI_PR_GUIDE.md Demonstrates the correct way to specify test commands in a PR. Always include exact commands rather than vague descriptions. ```bash go test -race -v -run TestSpecificFunction ./... ``` -------------------------------- ### Go Example: Using Litestream VFS Source: https://github.com/benbjohnson/litestream/blob/main/docs/VFS.md Connects to a SQLite database using the Litestream VFS in Go. Requires setting the `LITESTREAM_REPLICA_URL` environment variable before opening the database connection. ```go import ( "database/sql" "os" _ "github.com/mattn/go-sqlite3" ) func main() { os.Setenv("LITESTREAM_REPLICA_URL", "s3://my-bucket/mydb") db, err := sql.Open("sqlite3", "file:mydb.db?vfs=litestream") if err != nil { panic(err) } defer db.Close() rows, err := db.Query("SELECT * FROM users") // ... } ``` -------------------------------- ### Python Example: Using Litestream VFS Source: https://github.com/benbjohnson/litestream/blob/main/docs/VFS.md Connects to a SQLite database using the Litestream VFS in Python. Requires setting the `LITESTREAM_REPLICA_URL` environment variable and loading the extension. ```python import os import sqlite3 os.environ["LITESTREAM_REPLICA_URL"] = "s3://my-bucket/mydb" conn = sqlite3.connect(":memory:") conn.enable_load_extension(True) conn.load_extension("./dist/litestream-vfs.so") # Open database using the litestream VFS conn = sqlite3.connect("file:mydb.db?vfs=litestream") cursor = conn.execute("SELECT * FROM users") for row in cursor: print(row) ``` -------------------------------- ### Install Python Packages for S3 Mock Source: https://github.com/benbjohnson/litestream/blob/main/cmd/litestream-test/S3-RETENTION-TESTING.md Installs the necessary Python packages for running the S3 mock server and interacting with AWS services. ```bash pip3 install moto boto3 ``` -------------------------------- ### Run Overnight Test Pattern Source: https://github.com/benbjohnson/litestream/blob/main/cmd/litestream-test/README.md Populate a database, start Litestream replication in the background, and then load data with a specific pattern and duration. ```bash litestream-test populate -db /tmp/test.db -target-size 100MB ``` ```bash litestream replicate -config litestream.yml & ``` ```bash litestream-test load -db /tmp/test.db \ -duration 8h \ -write-rate 100 \ -pattern wave \ -workers 4 ``` -------------------------------- ### Basic Test Workflow Source: https://github.com/benbjohnson/litestream/blob/main/cmd/litestream-test/README.md A typical workflow for testing Litestream replication, including populating a database, starting replication, generating load, and validating the replica. ```bash litestream-test populate -db /tmp/test.db -target-size 100MB litestream replicate /tmp/test.db file:///tmp/replica & LITESTREAM_PID=$! litestream-test load -db /tmp/test.db -duration 5m -write-rate 50 kill $LITESTREAM_PID wait litestream-test validate -source-db /tmp/test.db -replica-url file:///tmp/replica ``` -------------------------------- ### Install litestream-vfs Gem Source: https://github.com/benbjohnson/litestream/blob/main/packages/ruby/README.md Install the litestream-vfs gem using the gem command or add it to your Gemfile. ```bash gem install litestream-vfs ``` ```ruby gem "litestream-vfs" ``` -------------------------------- ### Install Litestream VFS Source: https://github.com/benbjohnson/litestream/blob/main/packages/npm/litestream-vfs/README.md Install the litestream-vfs package using npm. This command will also handle the installation of the correct platform-specific binary via optionalDependencies. ```bash npm install litestream-vfs ``` -------------------------------- ### Direct SQLite Access in Go Source: https://github.com/benbjohnson/litestream/blob/main/docs/SQLITE_INTERNALS.md Demonstrates opening SQLite database connections in Go using both the standard database/sql package and the modernc.org/sqlite driver for low-level access. Includes an example for direct page reading, which requires special builds. ```go // Using database/sql for queries db, err := sql.Open("sqlite3", "database.db") // Using modernc.org/sqlite for low-level access conn, err := sqlite.Open("database.db") // Direct page access (requires special builds) page := readPage(conn, pageNumber) ``` -------------------------------- ### Run Individual Test Script Source: https://github.com/benbjohnson/litestream/blob/main/cmd/litestream-test/scripts/README.md Example of how to run a single, specific test script. This is useful for targeted testing or debugging. ```bash ./cmd/litestream-test/scripts/test-fresh-start.sh ``` -------------------------------- ### Error Propagation Example in Litestream Source: https://github.com/benbjohnson/litestream/blob/main/skills/litestream/references/ARCHITECTURE.md This shows a typical error propagation path within Litestream, starting from a storage backend operation and moving up through the replica and database layers. It highlights how errors are handled and logged. ```go ReplicaClient.WriteLTXFile() error → Replica.Sync() error → DB.Sync() error → Store.monitorDB() // logs error, continues ``` -------------------------------- ### Writing an LTX File with Go Source: https://github.com/benbjohnson/litestream/blob/main/skills/litestream/references/LTX_FORMAT.md Go code example demonstrating how to write an LTX file using `ltx.NewEncoder`, including encoding the header, pages, index, and trailer, while skipping the lock page. ```go enc := ltx.NewEncoder(writer) enc.EncodeHeader(header) for _, page := range pages { if page.Number == ltx.LockPgno(pageSize) { continue // Skip lock page } enc.EncodePage(pageHeader, pageData) } enc.EncodePageIndex(index) enc.EncodeTrailer() enc.Close() ``` -------------------------------- ### Example Behavior Change Comparison (Markdown Table) Source: https://github.com/benbjohnson/litestream/blob/main/AI_PR_GUIDE.md Illustrate behavioral changes using a Before/After comparison table. This clearly shows the impact of the PR. ```markdown ## Behavior Change | Scenario | Before | After | |----------|--------|-------| | Checkpoint with no changes | Creates snapshot | No snapshot | | Checkpoint with changes | Creates snapshot | Creates snapshot | ``` -------------------------------- ### Example Multi-PR Work Phasing (Markdown) Source: https://github.com/benbjohnson/litestream/blob/main/AI_PR_GUIDE.md For large features implemented across multiple PRs, outline the phases. This provides context and shows the overall plan. ```markdown This is Phase 1 of 3 for distributed leasing: 1. **This PR**: Lease client interface 2. Future: Store integration 3. Future: Distributed coordination ``` -------------------------------- ### Setup S3 Client with Environment Variables Source: https://github.com/benbjohnson/litestream/blob/main/docs/TESTING_GUIDE.md Configures an S3 replica client using environment variables for credentials, region, and bucket. Provides default values for region and bucket if not specified. The path is dynamically generated using a timestamp. ```go func setupS3Client() *s3.ReplicaClient { return &s3.ReplicaClient{ AccessKeyID: os.Getenv("AWS_ACCESS_KEY_ID"), SecretAccessKey: os.Getenv("AWS_SECRET_ACCESS_KEY"), Region: getEnvOrDefault("AWS_REGION", "us-east-1"), Bucket: getEnvOrDefault("TEST_S3_BUCKET", "litestream-test"), Path: fmt.Sprintf("test-%d", time.Now().Unix()), } } func getEnvOrDefault(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue } ``` -------------------------------- ### Run Individual Fresh Start Test Source: https://github.com/benbjohnson/litestream/blob/main/tests/integration/README.md Executes a single integration test function for a fresh start scenario. Useful for targeted debugging or verification. ```bash # Fresh start test go test -v -tags=integration ./tests/integration/... -run=TestFreshStart ``` -------------------------------- ### Error Wrapping Example Source: https://github.com/benbjohnson/litestream/blob/main/skills/litestream/SKILL.md Demonstrates the recommended way to wrap errors in Go using `fmt.Errorf` for better context and traceability. This pattern helps in debugging by preserving the original error. ```go fmt.Errorf("context: %w", err) ``` -------------------------------- ### Run Quick Integration Tests Source: https://github.com/benbjohnson/litestream/blob/main/tests/integration/README.md Executes fast integration tests suitable for CI. Includes tests for fresh start, database integrity, and rapid checkpoints. ```bash go test -v -tags=integration -timeout=30m ./tests/integration/ \ -run="TestFreshStart|TestDatabaseIntegrity|TestRapidCheckpoints" ``` -------------------------------- ### Error Propagation Example Source: https://github.com/benbjohnson/litestream/blob/main/docs/ARCHITECTURE.md Illustrates bottom-up error propagation in Litestream, showing how errors from lower-level operations like ReplicaClient.WriteLTXFile() are passed up through Replica.Sync() and DB.Sync(). ```go // Bottom-up error propagation ReplicaClient.WriteLTXFile() error ↓ Replica.Sync() error ↓ DB.Sync() error ↓ Store.monitorDB() // Logs error, continues ``` -------------------------------- ### Example Investigation Artifacts (Markdown) Source: https://github.com/benbjohnson/litestream/blob/main/AI_PR_GUIDE.md Show evidence of a problem using file patterns and debug logs. This helps prove the issue before proposing a solution. ```markdown ## Problem File patterns show excessive snapshot creation after checkpoint: - 21:43 5.2G snapshot.ltx - 21:47 5.2G snapshot.ltx (after checkpoint - should not trigger new snapshot) Debug logs show `verify()` incorrectly detecting position mismatch... ``` -------------------------------- ### Finding a Page using LTX Index Source: https://github.com/benbjohnson/litestream/blob/main/docs/LTX_FORMAT.md Example Go function demonstrating how to find a page's offset within an LTX file using binary search on the page index. Assumes the index is sorted by PageNo. ```go // Finding a page using the index func findPage(index []PageIndexElem, targetPageNo uint32) (offset int64, found bool) { // Binary search idx := sort.Search(len(index), func(i int) bool { return index[i].PageNo >= targetPageNo }) if idx < len(index) && index[idx].PageNo == targetPageNo { return index[idx].Offset, true } return 0, false } ``` -------------------------------- ### Goroutine Management for Background Tasks Source: https://github.com/benbjohnson/litestream/blob/main/docs/ARCHITECTURE.md Manages background tasks using WaitGroup and context cancellation. Use Start() to launch a task and Close() with a context for graceful shutdown with a timeout. ```go // Start background task func (db *DB) Start() { db.wg.Add(1) go func() { defer db.wg.Done() db.monitor() }() } // Stop with timeout func (db *DB) Close(ctx context.Context) error { // Signal shutdown db.cancel() // Wait for goroutines with timeout done := make(chan struct{}) go func() { db.wg.Wait() close(done) }() select { case <-done: return nil case <-ctx.Done(): return ctx.Err() } } ``` -------------------------------- ### Install litestream-vfs Package Source: https://github.com/benbjohnson/litestream/blob/main/packages/python/README.md Install the litestream-vfs package using pip. This command downloads and installs the package and its dependencies. ```bash pip install litestream-vfs ``` -------------------------------- ### Build Litestream from Source Source: https://github.com/benbjohnson/litestream/blob/main/CONTRIBUTING.md Clone the Litestream repository and build the binary locally. This includes instructions for setting up the development environment and running tests. ```bash # Clone the repository git clone https://github.com/benbjohnson/litestream.git cd litestream # Build the binary go build ./cmd/litestream # Run tests go test -v ./... # Install pre-commit hooks (recommended) pre-commit install ``` -------------------------------- ### Populate Database with Various Page Sizes (Bash) Source: https://github.com/benbjohnson/litestream/blob/main/docs/PATTERNS.md Test database population with different page sizes to observe behavior and performance. Adjust the target size as needed. ```bash ./bin/litestream-test populate -db test.db -page-size 4096 -target-size 2GB ``` ```bash ./bin/litestream-test populate -db test.db -page-size 8192 -target-size 2GB ``` -------------------------------- ### SQLite Page Header Structure (Go) Source: https://github.com/benbjohnson/litestream/blob/main/docs/SQLITE_INTERNALS.md Defines the Go struct for parsing the SQLite page header, including page type, free block start, cell count, and cell start offset. ```go type PageHeader struct { PageType byte // 0x02, 0x05, 0x0a, 0x0d FreeBlockStart uint16 // Start of free block list CellCount uint16 // Number of cells CellStart uint16 // Offset to first cell FragmentBytes byte // Fragmented free bytes // Additional fields for interior pages RightChild uint32 // Only for interior pages } ``` -------------------------------- ### Handling Partial Reads Correctly Source: https://github.com/benbjohnson/litestream/blob/main/skills/litestream/references/REPLICA_CLIENT_GUIDE.md Demonstrates the correct way to handle partial reads by checking for zero offset and size, and using DownloadRange when necessary. ```go // WRONG - Ignores offset/size return c.storage.Download(path) // CORRECT if offset == 0 && size == 0 { return c.storage.Download(path) } return c.storage.DownloadRange(path, offset, offset+size-1) ``` -------------------------------- ### Get Litestream Log Output Source: https://github.com/benbjohnson/litestream/blob/main/tests/integration/README.md Retrieve the Litestream log output from a test database instance. Useful for debugging. ```go log, err := db.GetLitestreamLog() fmt.Println(log) ``` -------------------------------- ### Get Current Transaction ID with litestream_txid() Source: https://github.com/benbjohnson/litestream/blob/main/docs/VFS.md Retrieves the current transaction ID as a hexadecimal string from the Litestream VFS. ```sql SELECT litestream_txid(); -- Returns: "0000000000000042" ``` -------------------------------- ### Create a New Database with Write Mode Source: https://github.com/benbjohnson/litestream/blob/main/docs/VFS.md Load the Litestream VFS extension and open a new database file. Writes to this database will be automatically synced to remote storage. ```sql .load ./dist/litestream-vfs.so .open file:newdb.db?vfs=litestream CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT); INSERT INTO users (name) VALUES ('Alice'); -- Data is synced to remote storage automatically ``` -------------------------------- ### Core Litestream Library API Pattern Source: https://github.com/benbjohnson/litestream/blob/main/_examples/library/README.md This Go code demonstrates the core pattern for using Litestream as a library. It covers creating a DB wrapper, attaching a replica client (e.g., file or S3), setting up compaction levels, opening the store, and finally opening the application's SQLite connection with DSN parameters for PRAGMAs. ```go import ( "context" "database/sql" "fmt" "time" "github.com/benbjohnson/litestream" "github.com/benbjohnson/litestream/file" // or s3, gs, abs, etc. _ "modernc.org/sqlite" ) // 1. Create database wrapper db := litestream.NewDB("/path/to/db.sqlite") // 2. Create replica client client := file.NewReplicaClient("/path/to/replica") // OR from URL: // client, _ := litestream.NewReplicaClientFromURL("s3://bucket/path") // 3. Attach replica to database replica := litestream.NewReplicaWithClient(db, client) db.Replica = replica client.Replica = replica // file backend only; preserves ownership/permissions // 4. Create compaction levels (L0 required, plus at least one more) levels := litestream.CompactionLevels{ {Level: 0}, {Level: 1, Interval: 10 * time.Second}, } // 5. Create Store to manage DB and background compaction store := litestream.NewStore([]*litestream.DB{db}, levels) // 6. Open Store (opens all DBs, starts background monitors) ctx := context.Background() if err := store.Open(ctx); err != nil { ... } defer store.Close(context.Background()) // 7. Open your app's SQLite connection for normal database operations // Use DSN params for PRAGMAs to ensure they apply to all connections in the pool dsn := fmt.Sprintf("file:%s?_pragma=busy_timeout(5000)&_pragma=journal_mode(wal)", "/path/to/db.sqlite") sqlDB, err := sql.Open("sqlite", dsn) if err != nil { ... } ``` -------------------------------- ### Get Litestream VFS Library Path Source: https://github.com/benbjohnson/litestream/blob/main/packages/ruby/README.md Retrieve the file system path to the loadable Litestream VFS shared library. ```ruby path = LitestreamVfs.loadable_path ``` -------------------------------- ### Initialize Replica Client with Connection Pool Source: https://github.com/benbjohnson/litestream/blob/main/docs/REPLICA_CLIENT_GUIDE.md Initializes a new ReplicaClient with a ConnectionPool. Configures the maximum number of connections and idle timeout for efficient resource management. ```go type ReplicaClient struct { pool *ConnectionPool } func NewReplicaClient(config Config) *ReplicaClient { pool := &ConnectionPool{ MaxConnections: config.MaxConnections, IdleTimeout: config.IdleTimeout, } return &ReplicaClient{ pool: pool, } } ``` -------------------------------- ### Get Test Database Size Source: https://github.com/benbjohnson/litestream/blob/main/tests/integration/README.md Retrieve and log the current size of the test database in megabytes. Useful for monitoring database growth. ```go size, _ := db.GetDatabaseSize() t.Logf("DB size: %.2f MB", float64(size)/(1024*1024)) ``` -------------------------------- ### Get Current View Timestamp with litestream_time() Source: https://github.com/benbjohnson/litestream/blob/main/docs/VFS.md Returns the current view timestamp in RFC3339 format or 'latest' if not in time travel mode. ```sql SELECT litestream_time(); -- Returns: "2024-01-15T10:30:00.123456789Z" or "latest" ``` -------------------------------- ### Example Scope Definition (Markdown) Source: https://github.com/benbjohnson/litestream/blob/main/AI_PR_GUIDE.md Clearly define what is included and excluded in the PR. This prevents scope creep and sets expectations for future work. ```markdown ## Scope This PR adds the lease client interface only. **In scope:** - LeaseClient interface definition - Mock implementation for testing **Not in scope (future PRs):** - Integration with Store - Distributed coordination logic ``` -------------------------------- ### Inspect Replica File Count Source: https://github.com/benbjohnson/litestream/blob/main/tests/integration/README.md Get the number of LTX files in the replica directory for a test database. Useful for verifying replication state. ```go fileCount, _ := db.GetReplicaFileCount() t.Logf("LTX files: %d", fileCount) ``` -------------------------------- ### Configure DB Settings in Go Source: https://github.com/benbjohnson/litestream/blob/main/_examples/library/README.md Set database monitoring, checkpoint intervals, and busy timeouts. Adjust these values to control how often Litestream checks for changes and performs checkpoints. ```go db.MonitorInterval = 1 * time.Second // How often to check for changes db.CheckpointInterval = 1 * time.Minute // Time-based checkpoint interval db.MinCheckpointPageN = 1000 // Page threshold for checkpoint db.BusyTimeout = 1 * time.Second // SQLite busy timeout ``` -------------------------------- ### Configure and Open Database with Litestream VFS Source: https://github.com/benbjohnson/litestream/blob/main/docs/VFS.md Sets the replica URL environment variable and then opens a SQLite database using the Litestream VFS. The `file:mydb.db?vfs=litestream` syntax specifies the database file and the VFS to use. ```bash export LITESTREAM_REPLICA_URL="s3://my-bucket/mydb" .load ./dist/litestream-vfs.so .open file:mydb.db?vfs=litestream SELECT * FROM my_table; ``` -------------------------------- ### Build Litestream Binary Source: https://github.com/benbjohnson/litestream/blob/main/tests/cpu-usage/README.md Build the Litestream binary from the source code. Ensure you are in the repository root directory. ```bash cd ../.. go build -o bin/litestream ./cmd/litestream ``` -------------------------------- ### Get Latest Test Directory and Analyze Source: https://github.com/benbjohnson/litestream/blob/main/scripts/README.md Finds the most recent Litestream test directory and pipes it to the analysis script. Useful for immediate post-test analysis. ```bash ls /tmp/litestream-overnight-* -dt | head -1 ./scripts/analyze-test-results.sh $(ls /tmp/litestream-overnight-* -dt | head -1) ``` -------------------------------- ### DB Component Key Methods in Litestream Source: https://github.com/benbjohnson/litestream/blob/main/docs/ARCHITECTURE.md Lists the essential methods for the DB component, covering lifecycle management, WAL monitoring, checkpointing, replication, and compaction. ```go // Lifecycle func (db *DB) Open() error func (db *DB) Close(ctx context.Context) error // Monitoring func (db *DB) monitor() // Background WAL monitoring func (db *DB) checkWAL() (bool, error) // Check for WAL changes // Checkpointing func (db *DB) Checkpoint(mode string) error func (db *DB) autoCheckpoint() error // Replication func (db *DB) WALReader(pgno uint32) (io.ReadCloser, error) func (db *DB) Sync(ctx context.Context) error // Compaction func (db *DB) Compact(ctx context.Context, destLevel int) (*ltx.FileInfo, error) ``` -------------------------------- ### List Databases with JSON Output Source: https://github.com/benbjohnson/litestream/blob/main/docs/CLI_JSON_OUTPUT.md Use the `-json` flag with the `litestream databases` command to get a JSON array of configured databases. This is useful for scripting and automation. ```json [ { "path": "/var/lib/app.db", "replica": "s3" } ] ``` -------------------------------- ### Show Version Source: https://github.com/benbjohnson/litestream/blob/main/cmd/litestream-test/README.md Display the version information for the litestream-test CLI. ```bash litestream-test version ``` -------------------------------- ### Build Project Binaries Source: https://github.com/benbjohnson/litestream/blob/main/CONTRIBUTING.md Builds the main Litestream binary and the test binary. These are required for running tests. ```bash go build -o bin/litestream ./cmd/litestream ``` ```bash go build -o bin/litestream-test ./cmd/litestream-test ``` -------------------------------- ### Implementing Lazy Pagination for File Loading Source: https://github.com/benbjohnson/litestream/blob/main/skills/litestream/references/REPLICA_CLIENT_GUIDE.md Illustrates the correct approach to load files lazily using pagination, avoiding the potential issue of loading millions of files into memory at once. ```go // WRONG - Could be millions of files allFiles, _ := c.loadAllFiles(level) // CORRECT - Lazy pagination return &lazyIterator{pageSize: 1000}, nil ``` -------------------------------- ### Litestream Restore Pattern Source: https://github.com/benbjohnson/litestream/blob/main/_examples/library/README.md This Go code snippet shows how to implement the restore pattern using Litestream. It initializes a replica client without a database, sets restore options (including optional point-in-time restore), and attempts to restore the database. It also handles cases where no backup is available. ```go import ( "context" "errors" "github.com/benbjohnson/litestream" "github.com/benbjohnson/litestream/file" // Example client ) // Assume 'client' is an initialized ReplicaClient (e.g., file.NewReplicaClient(...)) // Create replica without database for restore replica := litestream.NewReplicaWithClient(nil, client) opt := litestream.NewRestoreOptions() opt.OutputPath = "/path/to/restored.db" // Optional: point-in-time restore // opt.Timestamp = time.Now().Add(-1 * time.Hour) ctx := context.Background() if err := replica.Restore(ctx, opt); err != nil { if errors.Is(err, litestream.ErrTxNotAvailable) || errors.Is(err, litestream.ErrNoSnapshots) { // No backup available, create fresh database } return err } ``` -------------------------------- ### Configure S3 Storage Backend Source: https://github.com/benbjohnson/litestream/blob/main/docs/VFS.md Set AWS credentials and the Litestream replica URL for S3 or S3-compatible services. Include the custom endpoint if necessary. ```bash export AWS_ACCESS_KEY_ID="your-key" export AWS_SECRET_ACCESS_KEY="your-secret" export AWS_REGION="us-east-1" # For S3-compatible services: export LITESTREAM_REPLICA_URL="s3://bucket/path?endpoint=https://custom.endpoint.com" ``` -------------------------------- ### Test Litestream Configuration Source: https://github.com/benbjohnson/litestream/blob/main/docs/PROVIDER_COMPATIBILITY.md Test connectivity and configuration without starting replication. Use 'litestream snapshots' to list existing backups or 'litestream restore' to perform a test restore. ```bash # List any existing backups litestream snapshots s3://bucket/path?endpoint=... ``` ```bash # Perform a test restore (requires existing backup) litestream restore -o /tmp/test.db s3://bucket/path?endpoint=... ``` -------------------------------- ### DO: Leverage Existing Mechanisms for Snapshots Source: https://github.com/benbjohnson/litestream/blob/main/docs/PATTERNS.md Utilize existing functions like `db.verify()` to trigger snapshots, as they are designed to handle the logic correctly and efficiently. ```go // CORRECT - Use what's already there func triggerSnapshot() error { return db.verify() // Already handles snapshot logic correctly } ``` -------------------------------- ### Configure GCS Storage Backend Source: https://github.com/benbjohnson/litestream/blob/main/docs/VFS.md Set the Google Cloud credentials path and the Litestream replica URL for Google Cloud Storage. ```bash export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json" export LITESTREAM_REPLICA_URL="gs://bucket/path" ``` -------------------------------- ### Mock Replica Client Implementation Source: https://github.com/benbjohnson/litestream/blob/main/docs/REPLICA_CLIENT_GUIDE.md A mock implementation of the ReplicaClient for testing purposes. It allows injecting errors and stores file data in memory. ```go // mock/replica_client.go type ReplicaClient struct { mu sync.Mutex files map[string]*ltx.FileInfo data map[string][]byte errors map[string]error // Inject errors for testing } func (c *ReplicaClient) WriteLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID, r io.Reader) (*ltx.FileInfo, error) { c.mu.Lock() defer c.mu.Unlock() // Check for injected error key := fmt.Sprintf("write-%d-%d-%d", level, minTXID, maxTXID) if err, ok := c.errors[key]; ok { return nil, err } // Store data data, err := io.ReadAll(r) if err != nil { return nil, err } path := ltxPath(level, minTXID, maxTXID) c.data[path] = data info := <x.FileInfo{ Level: level, MinTXID: minTXID, MaxTXID: maxTXID, Size: int64(len(data)), CreatedAt: time.Now(), } c.files[path] = info return info, nil } ``` -------------------------------- ### Get Replication Lag with litestream_lag() Source: https://github.com/benbjohnson/litestream/blob/main/docs/VFS.md Calculates and returns the number of seconds since the last successful poll for new LTX files. Returns -1 if no successful poll has occurred. ```sql SELECT litestream_lag(); -- Returns: 2 (seconds behind primary) ``` -------------------------------- ### Get Path to Litestream Shared Library Source: https://github.com/benbjohnson/litestream/blob/main/packages/python/README.md Retrieve the file system path to the Litestream VFS shared library. This is useful if you need to manually load the library with other SQLite bindings. ```python path = litestream_vfs.loadable_path() ``` -------------------------------- ### Create Test SQLite Database Source: https://github.com/benbjohnson/litestream/blob/main/docs/TESTING_GUIDE.md Helper function to create a new SQLite database for testing. It sets up the database in WAL mode and initializes a basic schema. The database is automatically cleaned up after the test. ```go // testutil/db.go package testutil import ( "database/sql" "testing" "path/filepath" ) func NewTestDB(t testing.TB) *litestream.DB { t.Helper() path := filepath.Join(t.TempDir(), "test.db") // Create SQLite database conn, err := sql.Open("sqlite", path+"?_journal=WAL") require.NoError(t, err) _, err = conn.Exec(" CREATE TABLE test ( id INTEGER PRIMARY KEY, data BLOB ) ") require.NoError(t, err) conn.Close() // Open with Litestream db := litestream.NewDB(path) db.MonitorInterval = 10 * time.Millisecond // Speed up for tests db.MinCheckpointPageN = 100 // Lower threshold for tests err = db.Open() require.NoError(t, err) t.Cleanup(func() { db.Close(context.Background()) }) return db } ``` -------------------------------- ### SQLite RESTART Checkpoint Source: https://github.com/benbjohnson/litestream/blob/main/docs/SQLITE_INTERNALS.md Executes a restart checkpoint on the SQLite WAL. Similar to a FULL checkpoint, but also ensures the next writer starts at the beginning of the WAL and resets the WAL file. ```sql PRAGMA wal_checkpoint(RESTART); ``` -------------------------------- ### Get Daemon Info with JSON Output Source: https://github.com/benbjohnson/litestream/blob/main/docs/CLI_JSON_OUTPUT.md Use the `-json` flag with the `litestream info` command to retrieve daemon process information. This includes version, PID, uptime, and database count. ```json { "version": "v0.5.0", "pid": 12345, "uptime_seconds": 300, "started_at": "2026-04-24T12:00:00Z", "database_count": 2 } ``` -------------------------------- ### Mock Replica Client for Testing Source: https://github.com/benbjohnson/litestream/blob/main/docs/TESTING_GUIDE.md A mock implementation of ReplicaClient used for simulating network conditions and failures during tests. It allows control over latency, failure rates, and eventual consistency. ```go type MockReplicaClient struct { mu sync.Mutex files map[string]*ltx.FileInfo data map[string][]byte // Control behavior FailureRate float64 Latency time.Duration EventualDelay time.Duration } func (m *MockReplicaClient) WriteLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID, r io.Reader) (*ltx.FileInfo, error) { // Simulate latency if m.Latency > 0 { time.Sleep(m.Latency) } // Simulate failures if m.FailureRate > 0 && rand.Float64() < m.FailureRate { return nil, errors.New("simulated failure") } // Simulate eventual consistency if m.EventualDelay > 0 { time.AfterFunc(m.EventualDelay, func() { m.mu.Lock() defer m.mu.Unlock() // Make file available after delay }) } // Store file data, err := io.ReadAll(r) if err != nil { return nil, err } m.mu.Lock() defer m.mu.Unlock() key := fmt.Sprintf("%d-%016x-%016x", level, minTXID, maxTXID) info := <x.FileInfo{ Level: level, MinTXID: minTXID, MaxTXID: maxTXID, Size: int64(len(data)), CreatedAt: time.Now(), } m.files[key] = info m.data[key] = data return info, nil } ``` -------------------------------- ### Run Full Test Suite with Race Detection Source: https://github.com/benbjohnson/litestream/blob/main/skills/litestream/references/TESTING_GUIDE.md Execute the entire test suite with race detection enabled. Use this for comprehensive testing. ```bash go test -race -v ./... ``` -------------------------------- ### Get Litestream Status as JSON Source: https://github.com/benbjohnson/litestream/blob/main/docs/CLI_JSON_OUTPUT.md Outputs replication status for configured databases. The JSON output provides details on each database's status, latest transaction ID, and WAL file size. ```json [ { "database": "/var/lib/app.db", "status": "ok", "local_txid": "0000000000000004", "wal_size": "32 kB" } ] ``` -------------------------------- ### Mock Database for Testing Source: https://github.com/benbjohnson/litestream/blob/main/docs/TESTING_GUIDE.md A mock implementation of a database used for testing Litestream's replication and sync functionalities. It allows simulating sync delays and checking database state. ```go type MockDB struct { mu sync.Mutex path string replicas []*Replica closed bool // Control behavior CheckpointFailures int SyncDelay time.Duration } func (m *MockDB) Sync(ctx context.Context) error { if m.SyncDelay > 0 { select { case <-time.After(m.SyncDelay): case <-ctx.Done(): return ctx.Err() } } m.mu.Lock() defer m.mu.Unlock() if m.closed { return errors.New("database closed") } for _, r := range m.replicas { if err := r.Sync(ctx); err != nil { return err } } return nil } ``` -------------------------------- ### Unit Test for Writing and Opening LTX Files Source: https://github.com/benbjohnson/litestream/blob/main/docs/REPLICA_CLIENT_GUIDE.md Tests the WriteLTXFile and OpenLTXFile methods of the ReplicaClient. It verifies that a file can be written, opened, and its content read correctly, and checks for expected file existence. ```go // replica_client_test.go func TestReplicaClient_WriteLTXFile(t *testing.T) { client := NewReplicaClient(testConfig) ctx := context.Background() // Test data data := []byte("test ltx content") reader := bytes.NewReader(data) // Write file info, err := client.WriteLTXFile(ctx, 0, 1, 100, reader) assert.NoError(t, err) assert.Equal(t, int64(len(data)), info.Size) // Verify file exists rc, err := client.OpenLTXFile(ctx, 0, 1, 100, 0, 0) assert.NoError(t, err) defer rc.Close() // Read and verify content content, err := io.ReadAll(rc) assert.NoError(t, err) assert.Equal(t, data, content) } func TestReplicaClient_PartialRead(t *testing.T) { client := NewReplicaClient(testConfig) ctx := context.Background() // Write test file data := bytes.Repeat([]byte("x"), 1000) _, err := client.WriteLTXFile(ctx, 0, 1, 100, bytes.NewReader(data)) require.NoError(t, err) // Test partial read rc, err := client.OpenLTXFile(ctx, 0, 1, 100, 100, 50) require.NoError(t, err) defer rc.Close() partial, err := io.ReadAll(rc) assert.NoError(t, err) assert.Equal(t, 50, len(partial)) assert.Equal(t, data[100:150], partial) } func TestReplicaClient_NotFound(t *testing.T) { client := NewReplicaClient(testConfig) ctx := context.Background() // Try to open non-existent file _, err := client.OpenLTXFile(ctx, 0, 999, 999, 0, 0) assert.True(t, errors.Is(err, os.ErrNotExist)) } ``` -------------------------------- ### Get Loadable Path for Litestream VFS Source: https://github.com/benbjohnson/litestream/blob/main/packages/npm/litestream-vfs/README.md Import and use the getLoadablePath function from the litestream-vfs package to obtain the path to the VFS shared library. This path can then be used with SQLite bindings like better-sqlite3. ```javascript const { getLoadablePath } = require("litestream-vfs"); const path = getLoadablePath(); // Use `path` with better-sqlite3 or other SQLite bindings ``` -------------------------------- ### Test S3 Access Point ARN Support Source: https://github.com/benbjohnson/litestream/blob/main/cmd/litestream-test/scripts/README.md Tests S3 Access Point ARN support, verifying automatic endpoint configuration without manual setup. Requires setting the LITESTREAM_S3_ACCESS_POINT_ARN environment variable. ```bash export LITESTREAM_S3_ACCESS_POINT_ARN='arn:aws:s3:us-east-2:123456789012:accesspoint/my-access-point' ./cmd/litestream-test/scripts/test-s3-access-point.sh ``` -------------------------------- ### DO: Read from local disk when available Source: https://github.com/benbjohnson/litestream/blob/main/docs/PATTERNS.md Prioritize reading from local disk during compaction when data is available. This ensures data consistency and avoids issues with eventually consistent remote storage. ```go // CORRECT - Check local first during compaction // db.go:1280-1294 - ALWAYS read from local disk when available f, err := os.Open(db.LTXPath(info.Level, info.MinTXID, info.MaxTXID)) if err == nil { // Use local file - it's complete and consistent return f, nil } // Only fall back to remote if local doesn't exist return replica.Client.OpenLTXFile(...) ``` -------------------------------- ### Logging LTX File Uploads Source: https://github.com/benbjohnson/litestream/blob/main/docs/REPLICA_CLIENT_GUIDE.md Logs debug information before starting an LTX file upload and logs an error or info message upon completion. Uses the standard Go slog logger with contextual fields. ```go func (c *ReplicaClient) WriteLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID, r io.Reader) (*ltx.FileInfo, error) { logger := slog.Default().With( "replica", c.Type(), "level", level, "minTXID", minTXID, "maxTXID", maxTXID, ) logger.Debug("starting ltx upload") info, err := c.upload(ctx, level, minTXID, maxTXID, r) if err != nil { logger.Error("ltx upload failed", "error", err) return nil, err } logger.Info("ltx upload complete", "size", info.Size) return info, nil } ``` -------------------------------- ### Write New LTX File Source: https://github.com/benbjohnson/litestream/blob/main/docs/LTX_FORMAT.md Creates a new LTX file and writes a collection of pages to it. This function handles writing the header, each page with its checksum, the page index, and the trailer. Ensure the `pages` slice is populated correctly and `minTXID`, `maxTXID` are set appropriately. ```go func WriteLTXFile(path string, pages []Page) error { f, err := os.Create(path) if err != nil { return err } defer f.Close() enc := ltx.NewEncoder(f) // Write header header := ltx.Header{ Version: ltx.Version, Flags: 0, PageSize: 4096, PageCount: uint32(len(pages)), MinTXID: minTXID, MaxTXID: maxTXID, } if err := enc.EncodeHeader(header); err != nil { return err } // Write pages and build index var index []PageIndexElem for _, page := range pages { offset := enc.Offset() // Skip lock page if page.Number == LockPageNumber(header.PageSize) { continue } pageHeader := ltx.PageHeader{ PageNo: page.Number, Checksum: calculateChecksum(page.Data), } if err := enc.EncodePage(pageHeader, page.Data); err != nil { return err } index = append(index, PageIndexElem{ PageNo: page.Number, Offset: offset, }) } // Write page index if err := enc.EncodePageIndex(index); err != nil { return err } // Write trailer if err := enc.EncodeTrailer(); err != nil { return err } return enc.Close() } ``` -------------------------------- ### Adjust Soak Test Duration with -test.short Source: https://github.com/benbjohnson/litestream/blob/main/tests/integration/README.md Run an abbreviated version of a soak test by using the '-test.short' flag. This example shows running the comprehensive test for 30 minutes instead of its default 2 hours. ```bash # Run comprehensive test for 30 minutes instead of 2 hours go test -v -tags="integration,soak" -timeout=1h -run=TestComprehensiveSoak ./tests/integration/ -test.short ``` -------------------------------- ### Build and Test Litestream Source: https://github.com/benbjohnson/litestream/blob/main/CLAUDE.md Commands for building the Litestream binary, running tests with race detection, and executing pre-commit hooks. ```bash go build -o bin/litestream ./cmd/litestream ``` ```bash go test -race -v ./... ``` ```bash pre-commit run --all-files ``` -------------------------------- ### Get LTX File Metadata (JSON) Source: https://github.com/benbjohnson/litestream/blob/main/docs/CLI_JSON_OUTPUT.md Use `litestream ltx -json` to retrieve metadata for LTX files associated with a database or replica URL. This output is useful for understanding the transaction history and compaction levels. ```json [ { "level": 0, "min_txid": "0000000000000001", "max_txid": "0000000000000004", "size": 8192, "timestamp": "2026-04-24T12:00:00Z" } ] ``` -------------------------------- ### Generate Go Test Coverage Report Source: https://github.com/benbjohnson/litestream/blob/main/docs/TESTING_GUIDE.md Commands to generate a coverage report, view it in a browser, and check the total coverage percentage. ```bash # Generate coverage report go test -coverprofile=coverage.out ./... # View coverage in browser go tool cover -html=coverage.out # Check coverage percentage go tool cover -func=coverage.out | grep total # Coverage by package go test -cover ./... ``` -------------------------------- ### List Managed Databases (JSON) Source: https://github.com/benbjohnson/litestream/blob/main/docs/CLI_JSON_OUTPUT.md Use `litestream list -json` to get a list of databases managed by the running Litestream daemon. The output includes the database path, replication status, and the last successful sync time. ```json { "databases": [ { "path": "/var/lib/app.db", "status": "replicating", "last_sync_at": "2026-04-24T12:00:00Z" } ] } ``` -------------------------------- ### Configure Replica Settings in Go Source: https://github.com/benbjohnson/litestream/blob/main/_examples/library/README.md Configure replica synchronization interval and enable background monitoring. These settings determine the frequency of data synchronization and whether it runs automatically. ```go replica.SyncInterval = 1 * time.Second // Time between syncs replica.MonitorEnabled = true // Auto-sync in background ``` -------------------------------- ### Run Pre-commit Hooks Source: https://github.com/benbjohnson/litestream/blob/main/AGENTS.md Command to execute all pre-commit hooks to ensure code quality. ```bash pre-commit run --all-files ```