# SQLite on the Edge: Prisma Support for Turso is in Early Access URL: https://www.prisma.io/blog/prisma-turso-ea-support-rXGd_Tmy3UXX Published: 2023-09-28 Authors: Alex Ruheni Tags: orm, announcement Description: Prisma support for Turso is now in Early Access, enabling you to bring SQLite closer to your users. Try it out! [Turso](https://turso.tech/) is an edge-hosted, distributed database that's based on [libSQL](https://turso.tech/libsql), an open-source and open-contribution fork of [SQLite](https://sqlite.org/), 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! ## What is Turso, and how is it different from SQLite? [#what-is-turso-and-how-is-it-different-from-sqlite] [SQLite](https://www.sqlite.org/index.html) 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](https://fly.io/blog/introducing-litefs/), which provides replication and database backups for SQLite. On the other hand, Turso solved the above challenges by creating [libSQL](https://turso.tech/libsql-manifesto) — 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 = 🚀 [#prisma--turso--] While Prisma has supported SQLite from its [first release in 2019](https://www.prisma.io/blog/announcing-prisma-2-zq1s745db8i5), 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! ```tsx import { PrismaClient } from '@prisma/client' import { PrismaLibSQL } from '@prisma/adapter-libsql' import { createClient } from '@libsql/client' // Create a new instance of the libSQL database client const libsql = createClient({ // @ts-expect-error url: process.env.TURSO_DATABASE_URL, authToken: process.env.TURSO_AUTH_TOKEN }) // Create a Prisma "adapter" for libSQL const adapter = new PrismaLibSQL(libsql) // Pass the adapter option to the Prisma Client instance const prisma = new PrismaClient({ adapter }) export default prisma ``` ## Get started with Prisma and Turso [#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](https://github.com/planetscale/database-js), [Neon](https://github.com/neondatabase/serverless), and libSQL. We’ll share more details soon! If you have not yet, fill out [this survey](https://pris.ly/survey/driver-adapters-turso-blog), and leave us your email address for updates. ### Prerequisites [#prerequisites] You will need to have the following tools installed: * [Node.js](https://nodejs.org/en/download) version 16.13 or later * [Turso CLI](https://docs.turso.tech/reference/turso-cli) You can set up a project using [`try-prisma`](https://github.com/prisma/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: ```shell npx try-prisma@latest --template typescript/script --path . --name turso-prisma --install npm ``` Navigate to the project and open it on your preferred code editor: ```shell cd turso-prisma ``` ### Create a database on Turso [#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: ```shell turso db create turso-prisma ``` 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: ```shell turso db tokens create turso-prisma ``` 3. Next, reveal the connection string details to connect to your database: ```shell turso db show turso-prisma ``` 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 [#connect-to-turso-using-prisma] To get started using Turso: 1. Enable the `driverAdapters` Preview feature flag in your Prisma schema: ```diff generator client { provider = "prisma-client-js" + previewFeatures = ["driverAdapters"] } datasource db { provider = "sqlite" url = "file:./dev.db" } ``` 2. Create or update your `.env` file with the environment variables with the values from the “Create a database on Turso” step: ```shell TURSO_AUTH_TOKEN="eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..." TURSO_DATABASE_URL="libsql://turso-prisma-random-user.turso.io" ``` 3. Create the initial migration: ```shell npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script > migration.sql ``` 4. Apply the migration to your Turso database: ```shell turso db shell turso-prisma < migration.sql ``` 5. Install the latest version of Prisma Client: ```shell npm install @prisma/client@7.9.1 ``` 6. Install the libSQL database client and the driver adapter for Prisma Client: ```shell npm install @prisma/adapter-libsql npm install @libsql/client ``` 7. Update your Prisma Client instance with the following snippet: ```tsx import { PrismaClient } from '@prisma/client' // 1. Import libSQL and the Prisma libSQL driver adapter import { PrismaLibSQL } from '@prisma/adapter-libsql' import { createClient } from '@libsql/client' // 2. Instantiate libSQL const libsql = createClient({ // @ts-expect-error url: process.env.TURSO_DATABASE_URL, authToken: process.env.TURSO_AUTH_TOKEN }) // 3. Instantiate the libSQL driver adapter const adapter = new PrismaLibSQL(libsql) // Pass the adapter option to the Prisma Client instance const prisma = new PrismaClient({ adapter }) ``` 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 [#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](https://docs.turso.tech/tutorials/get-started-turso-cli/step-05-replicate-database-another-location#replicate-a-database-by-adding-a-location-to-its-placement-group). 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](https://github.com/prisma/orm/issues/new/choose) if you find something missing or run into a bug. *** ## Beyond remote SQLite: embedded replicas [#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](https://blog.turso.tech/introducing-embedded-replicas-deploy-turso-anywhere-2085aa0dc242), 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.](https://www.prisma.io/blog/prisma-turso-ea-support-rXGd_Tmy3UXX/imgs/mind-blown.gif) ### How do embedded replicas work? [#how-do-embedded-replicas-work] When your app initially establishes a connection to your database, the remote primary database will fulfill the query: ![](https://www.prisma.io/blog/prisma-turso-ea-support-rXGd_Tmy3UXX/imgs/embedded-replica-remote-read.png) 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: ![](https://www.prisma.io/blog/prisma-turso-ea-support-rXGd_Tmy3UXX/imgs/embedded-replica-create-copy.png) The embedded replica will fulfill subsequent read queries. The libSQL client provides a [`sync()`](https://docs.turso.tech/libsql/client-access/javascript-typescript-sdk#client-capability-summary:~\:text=an%20interactive%20transaction-,sync\(\),-Synchronize%20the%20embedded) method which you can invoke to ensure the embedded replica's data remains fresh. ![](https://www.prisma.io/blog/prisma-turso-ea-support-rXGd_Tmy3UXX/imgs/embedded-replica-read.png) 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. ![](https://www.prisma.io/blog/prisma-turso-ea-support-rXGd_Tmy3UXX/imgs/embedded-replica-write-propagation.png) 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 [#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: ```tsx await prisma.post.findMany({ where: { published: true }, select: { id: true, title: true, author: true // relation } }) ``` Below are screenshots of the timings for the same query on application startup: **Without an embedded replica:** Time: 154.390 ms ![](https://www.prisma.io/blog/prisma-turso-ea-support-rXGd_Tmy3UXX/imgs/remote-sqlite-timing.png) **With an embedded replica:** Time: 7.883 ms ![](https://www.prisma.io/blog/prisma-turso-ea-support-rXGd_Tmy3UXX/imgs/embedded-replica-timing.png) 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: * [Without embedded replicas](https://github.com/ruheni/fullstack-prisma-turso) * [With embedded replicas](https://github.com/ruheni/fullstack-prisma-turso-embedded-db) ### What can you use an embedded replica for? [#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](https://www.prisma.io/docs/orm/v7/prisma-client/client-extensions) 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! [#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](https://github.com/prisma/orm/discussions/21345). We’re also working on supporting other serverless database drivers and edge function deployments. Take [this short survey](https://pris.ly/survey/driver-adapters-turso-blog) and leave us your email address for updates. Be sure to share with us what you build on [X/Twitter](https://pris.ly/x) or [Discord](https://pris.ly/discord). 🙌