SQLite best practices for Go — WAL mode, foreign_keys, busy_timeout, SetMaxOpenConns, context-aware queries, transactions, migrations
98
99%
Does it follow best practices?
Impact
97%
2.36xAverage score across 5 eval scenarios
Passed
No known issues
{
"instruction": "Always apply SQLite best practices by default: WAL mode, foreign_keys ON (per connection), busy_timeout, SetMaxOpenConns(1), modernc.org/sqlite driver, context-aware queries, proper transactions, and migration patterns",
"relevant_when": "Agent creates or modifies a Go application that uses or will use SQLite",
"context": "SQLite in Go requires specific configuration via connection string pragmas (WAL, foreign_keys, busy_timeout, synchronous). database/sql pool must use SetMaxOpenConns(1) because SQLite only supports one writer. foreign_keys must be set per-connection (via DSN), not once after Open. Use modernc.org/sqlite (pure Go) over mattn/go-sqlite3 (CGO) unless CGO is specifically needed. All queries must use Context variants (QueryContext, ExecContext, BeginTx). Transactions need defer tx.Rollback(). Migrations should run in transactions with version tracking.",
"sources": [
{
"type": "file",
"filename": "skills/sqlite-go-best-practices/SKILL.md",
"tile": "tessl-labs/sqlite-go-best-practices@0.2.0"
}
],
"checklist": [
{
"name": "modernc-driver-used",
"rule": "Agent uses modernc.org/sqlite (pure Go) as the SQLite driver, not mattn/go-sqlite3, unless CGO is specifically required",
"relevant_when": "Agent creates or modifies a Go application that uses SQLite"
},
{
"name": "wal-mode-set",
"rule": "Agent enables WAL journal mode via the connection string pragma (_pragma=journal_mode(WAL)) or by executing PRAGMA journal_mode=WAL immediately after opening",
"relevant_when": "Agent creates a SQLite database connection in Go"
},
{
"name": "foreign-keys-enabled",
"rule": "Agent enables foreign key enforcement via connection string pragma (_pragma=foreign_keys(ON)) so it applies to every connection in the pool, not just once after sql.Open",
"relevant_when": "Agent creates a SQLite database connection in Go"
},
{
"name": "busy-timeout-set",
"rule": "Agent sets a busy_timeout pragma (e.g., _pragma=busy_timeout(5000)) to prevent immediate SQLITE_BUSY errors under contention",
"relevant_when": "Agent creates a SQLite database connection in Go"
},
{
"name": "max-open-conns-1",
"rule": "Agent calls db.SetMaxOpenConns(1) to serialize SQLite access and prevent 'database is locked' errors",
"relevant_when": "Agent configures Go database/sql for SQLite"
},
{
"name": "context-aware-queries",
"rule": "Agent uses QueryContext, QueryRowContext, ExecContext, and BeginTx instead of Query, QueryRow, Exec, and Begin for all database operations",
"relevant_when": "Agent writes Go code that queries or modifies a SQLite database"
},
{
"name": "defer-rows-close",
"rule": "Agent calls defer rows.Close() immediately after every QueryContext call to prevent connection leaks",
"relevant_when": "Agent writes Go code that calls QueryContext on a SQLite database"
},
{
"name": "rows-err-checked",
"rule": "Agent checks rows.Err() after iterating over query results to detect errors that terminated iteration early",
"relevant_when": "Agent writes Go code that iterates over rows from QueryContext"
},
{
"name": "transaction-defer-rollback",
"rule": "Agent uses defer tx.Rollback() immediately after BeginTx to guarantee rollback on any error path (no-op if committed)",
"relevant_when": "Agent writes Go code that uses SQLite transactions"
},
{
"name": "parameterized-queries",
"rule": "Agent uses ? placeholders for all dynamic values in SQL queries, never string interpolation or fmt.Sprintf to build SQL",
"relevant_when": "Agent writes Go code that queries a SQLite database with dynamic values"
}
]
}evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
skills
sqlite-go-best-practices
verifiers