https://blog.cloudflare.com/workers-tcp-socket-api-connect-databases/ Get Started Free | Contact Sales: +1 (888) 274-3482 The Cloudflare Blog The Cloudflare Blog Subscribe to receive notifications of new posts: [ ] Subscribe Subscription confirmed. Thank you for subscribing! Product News Speed & Reliability Security Serverless Zero Trust Developers Deep Dive Life @Cloudflare [magnifier] [hamburger] Product News Speed & Reliability Security Serverless Zero Trust Developers Deep Dive Life @Cloudflare Announcing connect() -- a new API for creating TCP sockets from Cloudflare Workers Loading... May 16, 2023 2:00PM * Brendan Irvine-Broque Brendan Irvine-Broque * Matt Silverlock Matt Silverlock Announcing connect() -- a new API for creating TCP sockets from Cloudflare Workers Today, we are excited to announce a new API in Cloudflare Workers for creating outbound TCP sockets, making it possible to connect directly to any TCP-based service from Workers. Standard protocols including SSH, MQTT, SMTP, FTP, and IRC are all built on top of TCP. Most importantly, nearly all applications need to connect to databases, and most databases speak TCP. And while Cloudflare D1 works seamlessly on Workers, and some hosted database providers allow connections over HTTP or WebSockets, the vast majority of databases, both relational (SQL) and document-oriented (NoSQL), require clients to connect by opening a direct TCP "socket", an ongoing two-way connection that is used to send queries and receive data. Now, Workers provides an API for this, the first of many steps to come in allowing you to use any database or infrastructure you choose when building full-stack applications on Workers. Database drivers, the client code used to connect to databases and execute queries, are already using this new API. pg, the most widely used JavaScript database driver for PostgreSQL, works on Cloudflare Workers today, with more database drivers to come. The TCP Socket API is available today to everyone. Get started by reading the TCP Socket API docs, or connect directly to any PostgreSQL database from your Worker by following this guide. First -- what is a TCP Socket? TCP (Transmission Control Protocol) is a foundational networking protocol of the Internet. It is the underlying protocol that is used to make HTTP requests (prior to HTTP/3, which uses QUIC), to send email over SMTP, to query databases using database-specific protocols like MySQL, and many other application-layer protocols. A TCP socket is a programming interface that represents a two-way communication connection between two applications that have both agreed to "speak" over TCP. One application (ex: a Cloudflare Worker) initiates an outbound TCP connection to another (ex: a database server) that is listening for inbound TCP connections. Connections are established by negotiating a three-way handshake, and after the handshake is complete, data can be sent bi-directionally. [image1-30] A socket is the programming interface for a single TCP connection -- it has both a readable and writable "stream" of data, allowing applications to read and write data on an ongoing basis, as long as the connection remains open. connect() -- A simpler socket API With Workers, we aim to support standard APIs that are supported across browsers and non-browser environments wherever possible, so that as many NPM packages as possible work on Workers without changes, and package authors don't have to write runtime-specific code. But for TCP sockets, we faced a challenge -- there was no clear shared standard across runtimes. Node.js provides the net and tls APIs, but Deno implements a different API -- Deno.connect. And web browsers do not provide a raw TCP socket API, though a WICG proposal does exist, and it is different from both Node.js and Deno. We also considered how a TCP socket API could be designed to maximize performance and ergonomics in a serverless environment. Most networking APIs were designed well before serverless emerged, with the assumption that the developer's application is also the server, responsible for directly handling configuring TLS options and credentials. With this backdrop, we reached out to the community, with a focus on maintainers of database drivers, ORMs and other libraries that create outbound TCP connections. Using this feedback, we've tried to incorporate the best elements of existing APIs and proposals, and intend to contribute back to future standards, as part of the Web-interoperable Runtimes Community Group (WinterCG). The API we landed on is a simple function, connect(), imported from the new cloudflare:sockets module, that returns an instance of a Socket. Here's a simple example showing it used to connect to a Gopher server. Gopher was one of the Internet's early protocols that relied on TCP/IP, and still works today: import { connect } from 'cloudflare:sockets'; export default { async fetch(req: Request) { const gopherAddr = "gopher.floodgap.com:70"; const url = new URL(req.url); try { const socket = connect(gopherAddr); const writer = socket.writable.getWriter() const encoder = new TextEncoder(); const encoded = encoder.encode(url.pathname + "\r\n"); await writer.write(encoded); return new Response(socket.readable, { headers: { "Content-Type": "text/plain" } }); } catch (error) { return new Response("Socket connection failed: " + error, { status: 500 }); } } }; We think this API design has many benefits that can be realized not just on Cloudflare, but in any serverless environment that adopts this design: connect(address: SocketAddress | string, options?: SocketOptions): Socket declare interface Socket { get readable(): ReadableStream; get writable(): WritableStream; get closed(): Promise; close(): Promise; startTls(): Socket; } declare interface SocketOptions { secureTransport?: string; allowHalfOpen: boolean; } declare interface SocketAddress { hostname: string; port: number; } Opportunistic TLS (StartTLS), without separate APIs Opportunistic TLS, a pattern of creating an initial insecure connection, and then upgrading it to a secure one that uses TLS, remains common, particularly with database drivers. In Node.js, you must use the net API to create the initial connection, and then use the tls API to create a new, upgraded connection. In Deno, you pass the original socket to Deno.startTls(), which creates a new, upgraded connection. Drawing on a previous W3C proposal for a TCP Socket API, we've simplified this by providing one API, that allows TLS to be enabled, allowed, or used when creating a socket, and exposes a simple method, startTls(), for upgrading a socket to use TLS. // Create a new socket without TLS. secureTransport defaults to "off" if not specified. const socket = connect("address:port", { secureTransport: "off" }) // Create a new socket, then upgrade it to use TLS. // Once startTls() is called, only the newly created socket can be used. const socket = connect("address:port", { secureTransport: "starttls" }) const secureSocket = socket.startTls(); // Create a new socket with TLS const socket = connect("address:port", { secureTransport: "use" }) TLS configuration -- a concern of host infrastructure, not application code Existing APIs for creating TCP sockets treat TLS as a library that you interact with in your application code. The tls.createSecureContext() API from Node.js has a plethora of advanced configuration options that are mostly environment specific. If you use custom certificates when connecting to a particular service, you likely use a different set of credentials and options in production, staging and development. Managing direct file paths to credentials across environments and swapping out .env files in production build steps are common pain points. Host infrastructure is best positioned to manage this on your behalf, and similar to Workers support for making subrequests using mTLS, TLS configuration and credentials for the socket API will be managed via Wrangler, and a connect() function provided via a capability binding. Currently, custom TLS credentials and configuration are not supported, but are coming soon. Start writing data immediately, before the TLS handshake finishes Because the connect() API synchronously returns a new socket, one can start writing to the socket immediately, without waiting for the TCP handshake to first complete. This means that once the handshake completes, data is already available to send immediately, and host platforms can make use of pipelining to optimize performance. connect() API + DB drivers = Connect directly to databases Many serverless databases already work on Workers, allowing clients to connect over HTTP or over WebSockets. But most databases don't "speak" HTTP, including databases hosted on most cloud providers. Databases each have their own "wire protocol", and open-source database "drivers" that speak this protocol, sending and receiving data over a TCP socket. Developers rely on these drivers in their own code, as do database ORMs. Our goal is to make sure that you can use the same drivers and ORMs you might use in other runtimes and on other platforms on Workers. Try it now -- connect to PostgreSQL from Workers We've worked with the maintainers of pg, one of the most popular database drivers in the JavaScript ecosystem, used by ORMs including Sequelize and knex.js, to add support for connect(). You can try this right now. First, create a new Worker and install pg: wrangler init npm install --save pg As of this writing, you'll need to enable the node_compat option in wrangler.toml: wrangler.toml name = "my-worker" main = "src/index.ts" compatibility_date = "2023-05-15" node_compat = true In just 20 lines of TypeScript, you can create a connection to a Postgres database, execute a query, return results in the response, and close the connection: index.ts import { Client } from "pg"; export interface Env { DB: string; } export default { async fetch( request: Request, env: Env, ctx: ExecutionContext ): Promise { const client = new Client(env.DB); await client.connect(); const result = await client.query({ text: "SELECT * from customers", }); console.log(JSON.stringify(result.rows)); const resp = Response.json(result.rows); // Close the database connection, but don't block returning the response ctx.waitUntil(client.end()); return resp; }, }; To test this in local development, use the --experimental-local flag (instead of -local), which uses the open-source Workers runtime, ensuring that what you see locally mirrors behavior in production: wrangler dev --experimental-local What's next for connecting to databases from Workers? This is only the beginning. We're aiming for the two popular MySQL drivers, mysql and mysql2, to work on Workers soon, with more to follow. If you work on a database driver or ORM, we'd love to help make your library work on Workers. If you've worked more closely with database scaling and performance, you might have noticed that in the example above, a new connection is created for every request. This is one of the biggest current challenges of connecting to databases from serverless functions, across all platforms. With typical client connection pooling, you maintain a local pool of database connections that remain open. This approach of storing a reference to a connection or connection pool in global scope will not work, and is a poor fit for serverless. Managing individual pools of client connections on a per-isolate basis creates other headaches -- when and how should connections be terminated? How can you limit the total number of concurrent connections across many isolates and locations? Instead, we're already working on simpler approaches to connection pooling for the most popular databases. We see a path to a future where you don't have to think about or manage client connection pooling on your own. We're also working on a brand new approach to making your database reads lightning fast. What's next for sockets on Workers? Supporting outbound TCP connections is only one half of the story -- we plan to support inbound TCP and UDP connections, as well as new emerging application protocols based on QUIC, so that you can build applications beyond HTTP with Socket Workers. Earlier today we also announced Smart Placement, which improves performance by placing any Worker that makes multiple HTTP requests to an origin run as close as possible to reduce round-trip time. We're working on making this work with Workers that open TCP connections, so that if your Worker connects to a database in Virginia and makes many queries over a TCP connection, each query is lightning fast and comes from the nearest location on Cloudflare's global network. We also plan to support custom certificates and other TLS configuration options in the coming months -- tell us what is a must-have in order to connect to the services you need to connect to from Workers. Get started, and share your feedback The TCP Socket API is available today to everyone. Get started by reading the TCP Socket API docs, or connect directly to any PostgreSQL database from your Worker by following this guide. We want to hear your feedback, what you'd like to see next, and more about what you're building. Join the Cloudflare Developers Discord. Watch on Cloudflare TV We protect entire corporate networks, help customers build Internet-scale applications efficiently, accelerate any website or Internet application, ward off DDoS attacks, keep hackers at bay, and can help you on your journey to Zero Trust. Visit 1.1.1.1 from any device to get started with our free app that makes your Internet faster and safer. To learn more about our mission to help build a better Internet, start here. If you're looking for a new career direction, check out our open positions. Discuss on Twitter Discuss on Hacker News Discuss on Reddit Developer Week Cloudflare Workers TCP sockets Database Follow on Twitter Brendan Irvine-Broque |@irvinebroque Matt Silverlock |@elithrar Cloudflare |Cloudflare Related Posts January 07, 2022 3:57PM Cloudflare Innovation Weeks 2021 As we start planning our 2022 Innovation Weeks, we are reflecting back on the highlights from each of these weeks... By * Reagan Russell * , John Graham-Cumming * , Val Vesa Birthday Week , CIO Week , Developer Week , Full Stack Week , Impact Week May 19, 2023 2:00PM Cloudflare Queues: messages at your speed with consumer concurrency and explicit acknowledgement Queues is faster than ever before! Now queues will automatically scale up your consumers, clearing out backlogs in a flash. Explicit Acknowledgement allows developers to acknowledge or retry individual messages in a batch, preventing work from being repeated.... By * Charles Burnett * , Josh Wheeler Developer Week , Developers , Cloudflare Workers , Queues , Beta November 18, 2022 9:13PM ICYMI: Developer Week 2022 announcements This week we made over 30 announcements, in case you missed any here's a quick round-up.... By * Dawn Parzych Developer Week , Developers , Serverless , Product News , Supercloud April 20, 2021 2:00PM Start building your own private network on Cloudflare today Starting today, your team can build a private network on Cloudflare's network.... By * Sam Rhea Developer Week , Developers , Cloudflare Access , Zero Trust , VPN * Sales * Enterprise Sales * Become a Partner Contact Sales: +1 (888) 99 FLARE +1 650 319 8930 * Getting Started * Pricing * Case Studies * White Papers * Webinars * Learning Center * Community * Community Hub * Blog * Project Galileo * Athenian Project * Cloudflare TV * Developers * Developer Hub * Technical Resources * Cloudflare Workers * Integrations * Support * Support * Cloudflare Status * Compliance * GDPR * Company * About Cloudflare * Our Team * Press * Analysts * Careers * Logo * Network Map [facebook] [twitter] [linkedin] [youtube] [instagram] (c) 2023 Cloudflare, Inc. | Privacy Policy | Terms of Use | Cookie Settings | Trust & Safety | Trademark