Test D1 read replication
In this tutorial, you will create a basic Worker script to test the effect of D1 read replication, and see the difference in the request latency.
This tutorial assumes you have completed and understood the D1 get started tutorial.
Create a new Worker as the means to query your database.
npm create cloudflare@latest -- <DATABASE_NAME>Create a database located far away by specifying a location hint which is far away from the region you are located in.
npx wrangler d1 create <DATABASE_NAME> --location=apac✅ Successfully created DB '<DATABASE_NAME>' in region APACCreated your new D1 database.
{ "d1_databases": [ { "binding": "DB", "database_name": "<DATABASE_NAME>", "database_id": "<DATABASE_ID>" } ]}This creates a new D1 database and outputs the binding configuration needed in the next step.
Modify your wrangler.jsonc file to include the output of the CLI to bind your D1 database to your Worker.
Populate your database with the table from the D1 get started tutorial.
-
Copy the following code and save it as a
schema.sqlfile in the Worker directory you created in step 1:DROP TABLE IF EXISTS Customers;CREATE TABLE IF NOT EXISTS Customers (CustomerId INTEGER PRIMARY KEY, CompanyName TEXT, ContactName TEXT);INSERT INTO Customers (CustomerID, CompanyName, ContactName) VALUES (1, 'Alfreds Futterkiste', 'Maria Anders'), (4, 'Around the Horn', 'Thomas Hardy'), (11, 'Bs Beverages', 'Victoria Ashworth'), (13, 'Bs Beverages', 'Random Name'); -
Initialize your database to run remotely.
Terminal window npx wrangler d1 execute <DATABASE_NAME> --remote --file=./schema.sql
Write a Worker file which queries the table and outputs both the results with the query latency.
export default { async fetch(request, env) { const { pathname } = new URL(request.url); const companyName1 = `Bs Beverages`; const stmt = env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`); const session = env.DB.withSession("first-unconstrained");
if (pathname === `/run`) { const tsStart1 = Date.now(); const { results, meta } = await stmt.bind(companyName1).run(); const d1Duration1 = Date.now() - tsStart1; return Response.json({ results, meta, d1Duration1 });
} else if (pathname === `/withsession`) { const tsStart2 = Date.now(); const { results, meta } = await session.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`).bind(companyName1).run(); const d1Duration2 = Date.now() - tsStart2; return Response.json({ results, meta, d1Duration2 }); } return new Response( `Welcome to the D1 read replication demo!
Add one of the following slugs below to see the effects of using D1 read replication.
\n/run - Queries the table without using read replication
\n/withsession - Queries the table using read replication (using "first-unconstrained")
\nUse the two options to compare the difference in query latency.` ); } };Use the REST API to enable read replication on your D1 database.
Run the following curl command on your terminal, with the details of your account ID and database ID.
curl -X PUT "https://api.cloudflare.com/client/v4/accounts/{account_id}/d1/database/{database_id}" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"read_replication": {"mode": "auto"}}'Deploy your Worker.
npx wrangler deployOnce deployed, you can compare the query latency when using read replication.
- Use the
/runURL to send a read query without read replication. - Use the
/withsessionURL to send a read query with read replication.
For both queries, the Worker script returns the meta object, which contains:
served_by_primary: indicates whether the query was served by the primary database instanceserved_by_region: shows the location of the database instance that processed the query
The d1Duration variable shows the whole round-trip latency.
By completing this tutorial, you have:
- Created a D1 database using a location hint.
- Created a Worker script which uses read replication.
- Deployed the Worker to test the difference in query latency when using read replication.
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Products
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark