---
title: "Use SQLite for a small or embedded · Agent Wranglers"
url: https://agentwranglers.se/playbook/stack/databases-and-storage/sqlite
updated: 2026-10-21
licence: "All rights reserved"
---

# Use SQLite for a small or embedded database

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- Level: Recommended
- Chapter: [Databases and storage](https://agentwranglers.se/playbook/stack/databases-and-storage)
- Rule: Use SQLite when one server process owns the data. Examples are a small site, a phone app, a test suite or a local tool.
- Cost: Open source. Public domain, free to copy and ship inside any app.
- How: SQLite 3.0.0 came out on 18 June 2004, and 3.54.1 came out on 16 October 2026. Its developers plan to support it through the year 2050. It came second in the Stack Overflow Developer Survey 2026, at 42.1%. The code is in the public domain, so it needs no licence. The file format is documented, and the US Library of Congress lists it as a recommended storage format. SQLite's own guide says sites under 100,000 hits a day work fine with it. Turn on write-ahead logging so readers never wait for the one writer. Choose something else when several servers write to the same data at once, and use PostgreSQL there. Back up the file and test the copy, as [Prove restores work](https://agentwranglers.se/playbook/data/backups-and-recovery/restore-tests) says.
- Check: Only one server process opens the database file for writing. `PRAGMA journal_mode` returns `wal`, and `PRAGMA busy_timeout` returns at least 5000.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
import Database from 'better-sqlite3';

const BUSY_TIMEOUT_MS = 5000;
const db = new Database('shop.db');
db.pragma('journal_mode = WAL');
db.pragma(`busy_timeout = ${BUSY_TIMEOUT_MS}`);
```

### Python example

```python
import sqlite3

BUSY_TIMEOUT_MS = 5000

db = sqlite3.connect("shop.db")
db.execute("PRAGMA journal_mode = WAL")
db.execute(f"PRAGMA busy_timeout = {BUSY_TIMEOUT_MS}")
```

## Sources

- [SQLite long-term support](https://www.sqlite.org/lts.html)
- [When to use SQLite](https://www.sqlite.org/whentouse.html)

## Related rules

- [Prove restores work](https://agentwranglers.se/playbook/data/backups-and-recovery/restore-tests) in Data

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/stack/databases-and-storage/sqlite">Agent Wranglers software choices playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Use PostgreSQL for the main database](https://agentwranglers.se/playbook/stack/databases-and-storage/postgresql)
- Next: [Use Redis 8 or Valkey for caches and queues](https://agentwranglers.se/playbook/stack/databases-and-storage/redis-or-valkey)
- [Databases and storage](https://agentwranglers.se/playbook/stack/databases-and-storage)
