Cloudflare recently announced they are introducing support for relational database connections through Workers, their serverless application platform. The initial support is for Postgres and MySQL. There are still a number of challenges that the Cloudflare team are working through and there are opportunities for community contributions.
Relational databases offer unique challenges that lead to making serverless connections harder. Most databases require long-standing TCP connections between the application server and the database server. Kabir Sikand, Greg McKeon, and Ben Yule share that the Cloudflare "Workers runtime doesn’t currently support TCP connections, so we’ve only been able to support HTTP-based databases or proxies.". They also note that Workers are not fully Node.js compatible meaning they are unable to leverage off-the-shelf client libraries for managing the database connections.
Phil Vuollet summarized the challenges with serverless databases in a recent post:
Connection and networking issues limit the number of application nodes that can use the data. Provisioning and scaling present limitations for the database itself, including costs and time to grow.
The Cloudflare team looked to move past these challenges by leveraging a number of pre-existing tools within the Cloudflare cloud ecosystem. First they used cloudflared to create an HTTP tunnel between the Cloudflare cloud and the data center hosting the database. Cloudflared supports proxying HTTP to TCP over WebSockets which helps to solve the need for TCP connections. To make the connection to the database using WebSockets, they created a shim-layer by adapting an existing socket API library.
As part of this beginning solution, Cloudflare has published a tutorial on how to connect to and query a Postgres database using Workers. This tutorial makes use of existing Cloudflare technology, such as cloudflared, and their shimmed version of a driver from Deno. Once the pieces are in place, the database connection can be made using the following client configuration:
const client = new Client({
user: '<DATABASE_USER>',
database: '<DATABASE_NAME>',
// hostname is the full URL to your pre-created Cloudflare Tunnel, see documentation here:
// https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/create-tunnel
hostname: env.TUNNEL_HOST || 'https://dev.example.com',
password: env.DATABASE_PASSWORD, // use a secret to store passwords
port: '<DATABASE_PORT>',
})
await client.connect()
Serverless relational databases are not a novel technology within the Cloud, although they are not yet commonplace. AWS announced v2 of its Aurora Serverless database service at re:Invent in 2020. With the move to v2, AWS adjusted the scaling of Aurora Serverless from doubling the instance size to incrementing by 0.5 Aurora capacity units (ACU). The service is fault-tolerant and available over multiple availability zones within the us-east-1 region. At the time of writing Aurora Serverless v2 is available for Amazon Aurora with MySQL compatibility and is still in preview.
In response to a question on Reddit regarding which relational database should be used with a serverless application, user localhost87 shared that "When we do architectural reviews, one question is always "do you actually need a database"?". The consensus across a number of users within the thread was the same and recommendations were to look to alternate technologies, such as message queues, or S3.
The team at Cloudflare has acknowledged a number of necessary improvements to making this technology more readily available. The main addition is to add support for TCP into the Worker runtime natively. This improvement is to come with Socket Workers, Workers that can be connected to using raw TCP, UDP, or QUIC protocols. While the work is still in flight, James Snell, Systems Engineer at Cloudflare, shares that the connect event would be similar to how fetch events work now:
addEventListener('connect', (event) => {
const enc = new TextEncoder();
const writer = event.socket.writable.getWriter();
writer.write(enc.encode('Hello World'));
writer.close();
});
As Snell notes "there is no standard API for socket connections in JavaScript" and he follows up by stating that Cloudflare has "no interest in developing yet another non-standard, platform-specific API". Therefore they are extending the call to all JavaScript runtime platforms to collaborate on new, standard API for socket connections.
With this initial announcement for relational database connection support through Workers, the Cloudflare team is looking for Cloudflare users to work with them on building out the full solution. Interested individuals are invited to contact the team or join them on their Discord.