Introduction to D1 SQL Database: Serverless SQLite for Workers
Learn how to use D1, Cloudflare's serverless SQLite database. This guide covers creating your first instance, basic SQL, and configuring bindings in Wrangler.

Previously in this course, we covered integrating R2 with workers, which allowed us to store and retrieve binary assets like images. Now, we’re moving from unstructured storage to structured data. In this lesson, you will learn how to provision a D1 instance, understand the basics of SQL, and bridge your Worker to your database using Wrangler bindings.
What is D1?
D1 is Cloudflare’s serverless relational database, powered by SQLite. Unlike traditional databases where you manage connection pools, hardware provisioning, or complex scaling rules, D1 is designed to be queried directly from your Worker. Because it’s based on SQLite, it provides a familiar, powerful SQL interface while operating in a distributed, edge-native environment.
If you are new to relational databases, I recommend brushing up on the logical vs physical schema to understand how we map application data to storage.
Creating Your First D1 Database
Everything begins with the Wrangler CLI. Before you can write a single line of SQL, you must provision an instance on Cloudflare's global network.
Run the following command in your terminal:
Bashnpx wrangler d1 create my-first-database
Once this finishes, Wrangler will output a binding configuration. It looks something like this:
TOML[[d1_databases]] binding = "DB" database_name = "my-first-database" database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Copy this snippet into your wrangler.toml file. This is the "binding"—it tells your Worker that whenever it sees the variable env.DB, it should direct requests to your specific D1 instance.
SQL Basics: The Language of Data
SQL (Structured Query Language) is how we interact with D1. Even if you've never used a database, you’ve likely encountered the concept of a "table." Think of a table as a spreadsheet with columns (attributes) and rows (records).
Here are the three fundamental commands you will use daily:
| Command | Purpose |
|---|---|
CREATE TABLE | Defines the structure of your data. |
INSERT INTO | Adds a new row of data to a table. |
SELECT | Retrieves data based on specific conditions. |
When designing your tables, remember the importance of primary keys and identifiers to ensure every piece of data is unique and retrievable.
Configuring Bindings in Your Worker
To use the database in your code, you access it via the env object passed to your handler. Because we named the binding DB in our wrangler.toml, it becomes available as env.DB.
Here is a simple example of how to execute a basic SQL query inside a Worker:
JAVASCRIPTexport default { async fetch(request, env, ctx) { // We execute a raw SQL query using the DB binding const { results } = await env.DB.prepare( "SELECT * FROM users WHERE status = ?" ) .bind(CE9178">'active') .all(); return Response.json(results); }, };
Hands-on Exercise
- Provision: Run
npx wrangler d1 create project-dband add the output to yourwrangler.toml. - Explore: Open the Cloudflare Dashboard, navigate to Workers & Pages > D1, and click your new database. Use the "Console" tab to run a simple command:
CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT);. - Verify: Insert a row using
INSERT INTO test (name) VALUES ('Developer');and then select it withSELECT * FROM test;.
Common Pitfalls
- Hardcoding IDs: Never hardcode your
database_idin your actual code; always use thewrangler.tomlbinding. - Synchronous Thinking: Remember that database operations are asynchronous. Always use
awaitwhen calling.prepare()or.all(). - Missing Migrations: While you can run SQL in the dashboard for testing, production databases should always be managed via implementing schema migrations to ensure consistency across environments.
Frequently Asked Questions
Q: Is D1 just a standard SQLite file? A: It uses the SQLite dialect, but it runs on Cloudflare's architecture, meaning it handles replication and global access for you.
Q: Can I connect to D1 from my local machine? A: Yes, Wrangler allows you to run local migrations and queries against a local SQLite file that mimics D1 behavior.
Q: How many D1 databases can I have? A: The number depends on your Cloudflare plan, but for most developers, the generous free tier is more than enough to get started.
Recap
We’ve successfully provisioned a D1 database, linked it to our project via wrangler.toml, and executed our first query. By leveraging SQLite, we gain the power of relational data without the overhead of traditional database management.
Up next: Schema Design for D1, where we will write our first migration file to define the structure for our project.
Work with me

Custom Email & File Storage System on Cloudflare (Google Workspace Alternative)
Your own private email + file storage suite on your domain — unlimited mailboxes, no per-seat fees. A self-owned Google Workspace alternative for a flat ~$5/month.

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app — built with FilamentPHP so you can manage everything without touching the database.


