---
title: D1-compatible SQLite
description: "A SQLite database bound to env.NAME, with the D1 prepared-statement API and online backups."
---

A SQLite database with the D1 binding API. Each database is its own SQLite file.

## Configuration

```jsonc
"d1_databases": ["DB"]
```

Bare names are auto-provisioned on deploy; see [Storage resources](/docs/storage).

## Usage

```js
const row = await env.DB.prepare("SELECT * FROM users WHERE id = ?").bind(id).first();
const name = await env.DB.prepare("SELECT name FROM users WHERE id = ?").bind(id).first("name");
const res = await env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind(name).run();
// res.meta.last_row_id, res.meta.changes
const { results } = await env.DB.prepare("SELECT * FROM users").all();
await env.DB.exec("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");
await env.DB.batch([stmtA, stmtB]);
```

## Promises and the compatibility date

From compatibility date `2026-10-24`, `prepare().raw()`, `.run()`, `.all()`, `.first()`, `batch()` and `exec()` return Promises, as on Workers. Before that date they are synchronous and return their value directly. `await` works at both, so the examples above are correct at every date.

A call that fails rejects its Promise (a foreign-key violation, say, which is enforced from `2026-10-24`). If you do not await it, nothing catches the error, and a `try` / `catch` around the call does not either. As on Workers the rejection is reported (a log line, and an `unhandledrejection` event when you listen for one) and the process and your other requests carry on; the write still failed. Await the call to handle the error.

## Methods

| Method | Signature | Returns |
| --- | --- | --- |
| `prepare(sql)` | SQL with `?` parameters | a prepared statement |
| `.bind(...values)` | strings, numbers, booleans or `null` | the statement |
| `.first(column?)` | | (a Promise from `2026-10-24`) the first row, or one column of it; `null` when there are no rows |
| `.run()` | | (a Promise from `2026-10-24`) `{ results, success, meta: { last_row_id, changes } }` |
| `.all()` | | (a Promise from `2026-10-24`) `{ results, success, meta }` |
| `.raw()` | | (a Promise from `2026-10-24`) rows as arrays of column values |
| `batch(statements)` | prepared statements | (a Promise from `2026-10-24`) one result per statement |
| `exec(sql)` | SQL script, no parameters | (a Promise from `2026-10-24`) runs every statement; use it for multi-statement DDL |
| `backup(name?)` | | `{ path, bytes }` |

`backup()` is a Sproutboat addition to the D1 API. It writes an online, integrity-checked copy of the database with `VACUUM INTO`, named `name` or a timestamp. On a [standalone binary](/docs/get-started/standalone) it lands in `<data>/backups/`. On the platform it is written on the server next to the database.

## Related

- [Storage resources and auto-provisioning](/docs/storage)
