Skip to main content
bun:sql is Bun’s built-in database client. It provides a single unified API for PostgreSQL, MySQL, and SQLite using tagged template literals that automatically escape parameters — no SQL injection possible.
Features:
  • Tagged template literals protect against SQL injection
  • Unified API for PostgreSQL, MySQL, and SQLite
  • Automatic connection pooling
  • Transactions with savepoints and distributed transactions
  • SCRAM-SHA-256 (SASL), MD5, and plain-text authentication
  • TLS/SSL support
  • BigInt support for large integers
  • Binary protocol for better performance

Database support

PostgreSQL

PostgreSQL is the default adapter. It is used when the connection string does not match MySQL or SQLite patterns, or when no connection string is provided and DATABASE_URL points to a Postgres instance.

MySQL

Pass a mysql:// or mysql2:// connection string to enable MySQL:

SQLite

Pass a sqlite:// URL, :memory:, or a file:// path to use SQLite:
Plain filenames like "myapp.db" require an explicit { adapter: "sqlite" } option to avoid being treated as a PostgreSQL connection.

Connection via environment variables

Bun.sql (the default export) reads credentials from environment variables automatically.

PostgreSQL environment variables

MySQL environment variables

SQLite environment variables


Parameterized queries

All values interpolated into template literals are automatically parameterized — they are never interpolated as raw SQL strings.
This generates a prepared statement equivalent to SELECT * FROM users WHERE id = $1 with [42] as the parameter array.

Inserting data

Bulk insert

Picking specific columns


Query results

By default, queries return an array of objects (one per row):

.values() — rows as arrays

Useful when column names are duplicated across joined tables.

.raw() — rows as Buffer arrays


SQL fragments and dynamic queries

Dynamic table names

Conditional clauses

Dynamic column updates

Dynamic WHERE IN lists

PostgreSQL array literals

sql.array is PostgreSQL-only.

Transactions

Savepoints

Distributed transactions (two-phase commit)


Connection pooling

Bun’s SQL client manages a connection pool automatically. No connections are created until the first query runs.

Reserved connections


Prepared statements

By default, Bun caches named prepared statements server-side for better performance. Disable this for compatibility with PGBouncer or when queries are highly dynamic:

Multiple statements and raw SQL

.simple() — multiple statements without parameters

sql.file() — load SQL from a file

sql.unsafe() — raw SQL strings

sql.unsafe() does not escape parameters. Only use this when you fully control the input.

Cancelling queries

Bun’s SQL client is lazy — execution only begins when the query is awaited or .execute() is called. Cancel in-progress queries with .cancel():

Preconnection at startup

Start establishing a PostgreSQL connection before your application code runs:

SSL / TLS


Dynamic passwords

For rotating credentials or token-based auth:

Error handling


BigInt handling

Numbers that exceed 53-bit safe integer range are returned as strings by default:
To get large numbers as bigint instead:

Redis

Bun includes a native Redis client with a Promise-based API. Import via bun:

Connection

By default, redis reads connection info from environment variables (in priority order):
  • REDIS_URL
  • VALKEY_URL
  • Falls back to redis://localhost:6379
Create a custom client for explicit credentials or multiple connections:

Common commands

Pipeline

Send multiple commands in a single round-trip using pipeline():
Bun’s Redis client supports Redis 7.2+ and is compatible with Valkey.