Connect to a MySQL database with Cloudflare Workers
In this tutorial, you will learn how to create a Cloudflare Workers application and connect it to a MySQL database using TCP Sockets and Hyperdrive. The Workers application you create in this tutorial will interact with a product database inside of MySQL.
To continue:
- Sign up for a Cloudflare account ↗ if you have not already.
- Install
npm
↗. - Install
Node.js
↗. Use a Node version manager like Volta ↗ or nvm ↗ to avoid permission issues and change Node.js versions. Wrangler requires a Node version of16.17.0
or later. - Make sure you have access to a MySQL database.
First, use the create-cloudflare
CLI ↗ to create a new Worker application. To do this, open a terminal window and run the following command:
npm create cloudflare@latest -- mysql-tutorial
pnpm create cloudflare@latest mysql-tutorial
yarn create cloudflare mysql-tutorial
This will prompt you to install the create-cloudflare
↗ package and lead you through a setup wizard.
For setup, select the following options:
- For What would you like to start with?, choose
Hello World Starter
. - For Which template would you like to use?, choose
Worker only
. - For Which language do you want to use?, choose
TypeScript
. - For Do you want to use git for version control?, choose
Yes
. - For Do you want to deploy your application?, choose
No
(we will be making some changes before deploying).
If you choose to deploy, you will be asked to authenticate (if not logged in already), and your project will be deployed. If you deploy, you can still modify your Worker code and deploy again at the end of this tutorial.
Now, move into the newly created directory:
cd mysql-tutorial
Node.js compatibility is required for database drivers, including mysql2, and needs to be configured for your Workers project.
To enable both built-in runtime APIs and polyfills for your Worker or Pages project, add the nodejs_compat
compatibility flag to your Wrangler configuration file, and set your compatibility date to September 23rd, 2024 or later. This will enable Node.js compatibility for your Workers project.
{ "compatibility_flags": [ "nodejs_compat" ], "compatibility_date": "2024-09-23"}
compatibility_flags = [ "nodejs_compat" ]compatibility_date = "2024-09-23"
Create a Hyperdrive configuration using the connection string for your MySQL database.
npx wrangler hyperdrive create <NAME_OF_HYPERDRIVE_CONFIG> --connection-string="mysql://user:password@HOSTNAME_OR_IP_ADDRESS:PORT/database_name"
This command outputs the Hyperdrive configuration id
that will be used for your Hyperdrive binding. Set up your binding by specifying the id
in the Wrangler file.
{ "name": "hyperdrive-example", "main": "src/index.ts", "compatibility_date": "2024-08-21", "compatibility_flags": [ "nodejs_compat" ], "hyperdrive": [ { "binding": "HYPERDRIVE", "id": "<ID OF THE CREATED HYPERDRIVE CONFIGURATION>" } ]}
name = "hyperdrive-example"main = "src/index.ts"compatibility_date = "2024-08-21"compatibility_flags = ["nodejs_compat"]
# Pasted from the output of `wrangler hyperdrive create <NAME_OF_HYPERDRIVE_CONFIG> --connection-string=[...]` above.[[hyperdrive]]binding = "HYPERDRIVE"id = "<ID OF THE CREATED HYPERDRIVE CONFIGURATION>"
Install the mysql2 ↗ driver:
# mysql2 v3.13.0 or later is requirednpm install mysql2
Create a new connection
instance and pass the Hyperdrive parameters:
// mysql2 v3.13.0 or later is requiredimport { createConnection } from "mysql2/promise";
export interface Env { // If you set another name in the Wrangler config file as the value for 'binding', // replace "HYPERDRIVE" with the variable name you defined. HYPERDRIVE: Hyperdrive;}
export default { async fetch(request, env, ctx): Promise<Response> { // Create a connection using the mysql2 driver (or any support driver, ORM or query builder) // with the Hyperdrive credentials. These credentials are only accessible from your Worker. const connection = await createConnection({ host: env.HYPERDRIVE.host, user: env.HYPERDRIVE.user, password: env.HYPERDRIVE.password, database: env.HYPERDRIVE.database, port: env.HYPERDRIVE.port,
// The following line is needed for mysql2 compatibility with Workers // mysql2 uses eval() to optimize result parsing for rows with > 100 columns // Configure mysql2 to use static parsing instead of eval() parsing with disableEval disableEval: true, });
try { // Sample query const [results, fields] = await connection.query("SHOW tables;");
// Clean up the client after the response is returned, before the Worker is killed ctx.waitUntil(connection.end());
// Return result rows as JSON return new Response(JSON.stringify({ results, fields }), { headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*", }, }); } catch (e) { console.error(e); return Response.json( { error: e instanceof Error ? e.message : e }, { status: 500 }, ); } },} satisfies ExportedHandler<Env>;
Run the following command to deploy your Worker:
npx wrangler deploy
Your application is now live and accessible at <YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev
.
To build more with databases and Workers, refer to Tutorials and explore the Databases documentation.
If you have any questions, need assistance, or would like to share your project, join the Cloudflare Developer community on Discord ↗ to connect with fellow developers and the Cloudflare team.
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