September 28, 2023

SQLite on the Edge: Prisma Support for Turso is in Early Access

Turso is an edge-hosted, distributed database that's based on libSQL, an open-source and open-contribution fork of SQLite, enabling you to bring data closer to your application and minimize query latency.

We’re excited to share that Prisma ORM is adding Early Access support for Turso. Let’s dive in!

SQLite on the Edge: Prisma Support for Turso is in Early Access

What is Turso, and how is it different from SQLite?

SQLite is a self-contained, file-based open-source database known for its portability, reliability, and performance, even in environments with low memory. It’s also the perfect fit for small web applications because of its speed.

However, scaling SQLite introduces challenges:

  • Manual backups
  • Lack of out-of-the-box replication
  • Difficulties persisting data in serverless environments
  • Hosting difficulties in multi-server setups

Some of these challenges can be solved by tools such as LiteFS, which provides replication and database backups for SQLite.

On the other hand, Turso solved the above challenges by creating libSQL — a fork of SQLite that adds features that SQLite does not support yet. libSQL allows you to distribute and replicate SQLite, connect over HTTP, perform async operations, and embed SQLite as part of other programs as a primary database or replica of the primary database.

Prisma + Turso = 🚀

While Prisma has supported SQLite from its first release in 2019, libSQL differs from SQLite. For example, libSQL uses HTTP to connect to the database and uses a remote file over a local one, making Prisma and Turso incompatible until now.

Today, we’re excited to announce that Prisma support for Turso is now available in Early Access!

Get started with Prisma and Turso

To start using Turso in your project, you must first enable the driverAdapters Preview feature flag. This will allow you to query your database using Turso’s driver adapter.

The driverAdapters feature flag is part of the driver adapter initiative we're working on to enable you use other database drivers to connect to your database. Example driver adapters include PlanetScale, Neon, and libSQL. We’ll share more details soon! If you have not yet, fill out this survey, and leave us your email address for updates.

Prerequisites

You will need to have the following tools installed:

You can set up a project using try-prisma if you don’t have an existing project using SQLite. Navigate to your working directory and copy the command below to set up the project:

Navigate to the project and open it on your preferred code editor:

Create a database on Turso

First, create a database on Turso that your application will use. This step is necessary for creating the credentials required to configure Turso’s database client.

  1. To create a database, run the following command on your terminal:

    Turso will also create a database in the region closest to your location.

  2. Create an authentication token that will allow you to connect to the database:

  3. Next, reveal the connection string details to connect to your database:

    Take note of the authentication token and connection string which will be used to connect to your database in the next step.

Connect to Turso using Prisma

To get started using Turso:

  1. Enable the driverAdapters Preview feature flag in your Prisma schema:

  2. Create or update your .env file with the environment variables with the values from the “Create a database on Turso” step:

  3. Create the initial migration:

  4. Apply the migration to your Turso database:

  5. Install the latest version of Prisma Client:

  6. Install the libSQL database client and the driver adapter for Prisma Client:

  7. Update your Prisma Client instance with the following snippet:

And that’s it!

You can now start querying your Turso database using Prisma Client.

If you cloned the typescript/script example, you can run npm run dev to insert and query data to confirm your changes were successful.

Where to go from here

The setup above uses a single remote database. You can take it a step further by setting up database replicas. Turso automatically picks the closest replica to your app for read queries when you create replicas. No additional logic is required to define how the routing of the read queries should be handled. Write queries will be forwarded to the primary database.

Try it out and share your feedback! We encourage you to create an issue if you find something missing or run into a bug.


Beyond remote SQLite: embedded replicas

While Turso allows you to replicate SQLite globally, what if you could eliminate the extra network hop from your app to the remote replica? What if… you could move the database inside your application?

With Turso's newly announced embedded replicas, you can have a-copy of your primary, remote database inside your application, similar to how an embedded/local SQLite database works. You can try this out in your application using Prisma’s new support for Turso.

A meme gif of a person having their mind blown.

How do embedded replicas work?

When your app initially establishes a connection to your database, the remote primary database will fulfill the query:

Then Turso will (1) create an embedded replica inside your application and (2)-copy data from your primary database to the replica so it is locally available:

The embedded replica will fulfill subsequent read queries. The libSQL client provides a sync() method which you can invoke to ensure the embedded replica's data remains fresh.

With embedded replicas, this setup guarantees your app is fast because the data will be readily available locally.

Like a read replica setup you may be familiar with, write operations are forwarded to the primary remote database and executed before being propagated to all embedded replicas.

  1. Write operations propagation are forwarded to the database.
  2. Database responds to the server with the updates from 1.
  3. Write operations are propagated to the database replica.

Impact of embedded replicas on your queries

To demonstrate the speed of embedded replicas, we created two example apps using the same primary database - and one variant uses an embedded replica.

For this sample test, the following query will be used:

Below are screenshots of the timings for the same query on application startup:

Without an embedded replica:

Time: 154.390 ms

With an embedded replica:

Time: 7.883 ms

The query response significantly drops from 154.390 ms to 7.883 ms.

If you would like to try it out yourself, you can find the two example apps up on GitHub:

What can you use an embedded replica for?

Embedded replicas are a relatively new feature of Turso, but some of the use cases you could use them for include:

  • Improving read performance of your APIs: Embedded replicas can eliminate the network cost of connecting to a remote database server with an embedded database with Prisma Client.
  • Replacement for your caching service: Embedded replicas can be paired with a Prisma Client extension for query responses, making your app faster because the data is always kept fresh.

It will be interesting to see what other use cases you will come up with for this new approach to database replicas.

Try it out yourself!

We can't wait to see what you build with Turso and Prisma. We encourage you to try it out and let us know your thoughts.

We’re also working on supporting other serverless database drivers and edge function deployments. Take this short survey and leave us your email address for updates.

Be sure to share with us what you build on Twitter or Discord. 🙌

Don’t miss the next post!

Sign up for the Prisma Newsletter