July 29, 2022

Database access on the Edge with Next.js, Vercel & Prisma Accelerate

The Edge enables application deployment across the globe. This article explores what Edge environments are, the challenges that arise when working in Edge environments and how to access databases on the Edge using Prisma Accelerate.

Database access on the Edge with Next.js, Vercel & Prisma Accelerate

What is the Edge?

Traditionally, applications would be deployed to a single region or data center, in either a virtual machine, Platform as a Service (PaaS) like Heroku, or Functions as a Service (FaaS) like AWS Lambda. While this deployment pattern worked fine, the problem this created was that a user located on the other side of the globe would experience slightly longer response times.

We — developers — attempted to fix this with the JAMstack architecture, where static assets, such as HTML, CSS, JavaScript, and images, would be distributed across the globe in a Content Delivery Network (CDN). This improved loading times — the Time to First Byte (TTFB) — of web applications, but if the application required dynamic data, e.g., from an API or database, the application needed to make another request for the data. This also worked fine. However, the side effect was that we also distributed loading spinners across the web.

We took this a step further and introduced Edge computing such as Vercel's Edge Network. The Edge is a form of serverless compute that allows running server-side code geographically close to its end users.

[Source] Cloudflare workers

Edge computing works similarly to serverless functions, without the cold starts because they have a smaller runtime. This is great because web apps would perform better, but it comes at a cost: A smaller runtime on the Edge means that you don't have the exact same capabilities as you would have in regular Node.js runtime used in serverless functions.

Check out this introduction to Edge computing by Fireship to learn more:

Edge functions can easily exhaust database connections

Edge functions are stateless, meaning they lack persistent state between requests. This architecture clashes with the stateful nature of traditional relational databases, where each request requires a new database connection.

With every request to the application, a new database connection is established, adding substantial overhead to queries and potentially hindering application performance as it scales. Moreover, during traffic spikes, the database is at risk of running out of database connections, leading to downtimes.

You can learn more about the challenges of database access in Edge environments, which is similar to serverless environments, in this article.

Database access on the Edge with Prisma Accelerate

Prisma Accelerate offers a connection pooler for your database, that reuses database connections and allows you to interact with your database over HTTP.

The connection pool of Accelerate ensures optimal performance by efficiently reusing database connections for serverless and edge applications (i.e. applications using Vercel Edge Functions or Cloudflare Workers).

In addition to providing connection pooling by default, Prisma Accelerate also offers a global edge cache. You can drastically improve the performance of your applications by opting-in and caching your query results in-line with your Prisma queries. You can learn more about caching with Accelerate here.

Do single-region databases and the Edge fit together?

Edge computing is a fairly young, yet very promising technology that has the potential to drastically speed up applications in the future. The ecosystem around the Edge is still evolving and best practices for globally distributed applications are yet to be figured out.

At Prisma, we are excited about the developments in the Edge ecosystem and want to help move it forward! However, connecting to a single-region database as shown in this article is probably not the best idea for real-world applications today.

To reduce large roundtrips from edge functions to a single-region database, you can use a global cache, which allows you to store your data closer to your edge apps. Prisma Accelerate offers a global cache, which you can easily opt-in to drastically improve the performance of your edge apps. As a best practice, we still recommend to generally deploy your database as closely as possible to your API server to minimize latency in response times.

While the architecture shown in this article might not cater to real-world use cases yet, we are excited about the possibilities that are opening up in this space and want to make sure Prisma can help solve the problems related to database access on the Edge in the future!

Demo: Database access on the Edge

Let's now take a look how to access a database from Vercel's Edge functions using Prisma Accelerate.

You can find the live demo of the application here and the completed project on GitHub.

The demo application that is used here is a random quote generator built with Next.js and styled with TailwindCSS. The application will take advantage of Next.js' Edge server rendering and Edge API routes to fetch data from a remote PostgreSQL database on every page refresh.

The final state of application you will be working on will resemble this:

The application contains a single model called Quote with the following fields:

Prerequisites

To successfully follow along, you will need:

Clone application

Navigate to your directory of choice and run the following command to set up a new Next.js project:

Navigate into the directory:

The page and API Route are also configured to use Vercel’s Edge Runtime with the following configuration in both files:

Set up the database

You can use a free PostgreSQL database hosted on Supabase or Neon.

Once you’ve set up the database, update the .env file at the root of your project with the database’s connection string:

With the DATABASE_URL environment variable set, apply the existing Prisma schema to your database schema using the prisma migrate dev command. The prisma migrate dev command will apply any pending migration in the /prisma/migrations folder against your database.

Next, populate the database with sample data. The project contains a seed script in the ./prisma/seed.ts file and sample data in ./prisma/data.json. The sample data includes 178 quotes.

You should see the following output:

Set up Prisma Accelerate

Navigate to GitHub and create a private repository:

Next, initialize your repository and push your changes to GitHub:

Note: Replace the <username> placeholder value with your GitHub username before pasting the value on your terminal.

Once you’ve set up your repository, navigate to the Platform Console and sign up for a free account if you don’t have one yet.

After signing up:

  1. Create a new project by clicking the New project button

  2. Fill out your Project’s name and the click the Create Project button

  3. Enable Accelerate by clicking the Enable Accelerate button

  4. Add your database connection string to the Database connection string field and select a region close to your database from the Region drop down

  5. Generate an Accelerate connection string by clicking the Generate API key button

  6. Copy the generated Accelerate connection string

Accelerate has been successfully setup 🎉!

Update your application code

Back in your project, rename the existing DATABASE_URL to MIGRATE_DATABASE_URL and paste the Prisma Accelerate URL into your .env file as the new DATABASE_URL:

The MIGRATE_DATABASE_URL variable will be used to apply any pending migrations during the build process. The package.json file uses the vercel-build hook script to run prisma migrate deploy && next build

Then install the Prisma Accelerate client extension:

Next, generate Prisma Client that will connect through Prisma Accelerate using HTTP:

Then, navigate to lib/prisma and update Prisma Client’s import from @prisma/client to @prisma/client/edge to be make it compatible with edge environments:

Test the application locally

Now that setup is done, you can start up your application locally:

Navigate to http://localhost:3000, and this is what it might look like at the moment.

The quote you will see might be different because the quote is selected randomly. You can hit Another one 🔄 to refresh the page with a new quote.

You can also navigate to http://localhost:3000/api/quote to get a random quote in JSON format.

Deploy the application

Commit the existing changes to version control and push them to GitHub.

Navigate to Vercel and import your GitHub repository.

Give your project a name and open up the Environment Variables toggle and fill out the following environment variables:

  • MIGRATE_DATABASE_URL: the database’s connection string
  • DATABASE_URL: the Prisma Accelerate connection string
  • PRISMA_GENERATE_NO_ENGINE: true

The PRISMA_GENERATE_NO_ENGINE can be set to a truthy value to generate a Prisma Client without an included query engine in order to reduce deployed application size when paired with Prisma Accelerate.

Finally, click Deploy to kick off the build:

Congratulations

Once the build is successful, you should see the following:

Click the Visit button to view the deployed version of the application.

Back on the Vercel dashboard in the Overview tab, click View Function Logs. Next, select the “index” function. You will see that your application’s runtime is Edge and the Region is Global.

Refresh the page in your application, and back on Vercel, you will see the request’s status logged.

Congratulations! 🎉 

Conclusion

The Edge enables instant application deployment across the globe, changing how developers think about application development and deployment.

Prisma Accelerate is one tool that enables developers to build and ship web apps requiring database access on the Edge.

The Edge is still in its early stages, with a few drawbacks. However, it's exciting to see how building web apps on the Edge will look.

Don’t miss the next post!

Sign up for the Prisma Newsletter