--- title: Migrate from Vercel Postgres SDK to the Neon serverless driver subtitle: Learn how to smoothly transition your application from using Vercel Postgres SDK to the Neon serverless driver author: dhanush-reddy enableTableOfContents: true createdAt: '2024-10-28T00:00:00.000Z' updatedAt: '2024-10-28T00:00:00.000Z' --- With Vercel Postgres transitioning to Neon's native integration in the [Vercel Marketplace](https://vercel.com/blog/introducing-the-vercel-marketplace), now is the perfect time to migrate from the Vercel Postgres SDK [(@vercel/postgres)](https://vercel.com/docs/storage/vercel-postgres/sdk) to the [Neon serverless driver](https://github.com/neondatabase/serverless). ## Why migrate? Switching to the Neon serverless driver provides several advantages. It offers greater flexibility by allowing the choice between HTTP for single queries or WebSockets for transactions and full [node-postgres](https://node-postgres.com/) compatibility. Additionally, it enhances maintainability by relying on Neon's actively maintained, native database driver. ## Prerequisites To begin, you’ll need: - An existing application using the Vercel Postgres SDK - A [Neon account](/docs/get-started/signing-up) (your Vercel Postgres database will automatically migrate to Neon) ## Migration Steps ### 1. Install the Neon serverless driver Start by installing the Neon serverless driver in your project: ```bash npm install @neondatabase/serverless ``` To ensure proper configuration, set your environment variable to `DATABASE_URL` when referencing the database URL in your code, especially if you're following this guide. ### 2. Update your database connection Replace your Vercel Postgres SDK imports and connection setup with the Neon serverless driver. You have two options: #### Option A: Using HTTP (Recommended for simple queries) ```diff import { sql } from '@vercel/postgres'; // [!code --] import { neon } from '@neondatabase/serverless'; // [!code ++] const sql = neon(process.env.DATABASE_URL!); // [!code ++] ``` #### Option B: Using WebSockets (Recommended for transactions) ```diff import { db } from '@vercel/postgres'; // [!code --] import ws from 'ws'; // [!code ++] import { Pool, neonConfig } from '@neondatabase/serverless'; // [!code ++] const pool = new Pool({ connectionString: process.env.DATABASE_URL }); // [!code ++] neonConfig.webSocketConstructor = ws; // [!code ++] ``` ### 3. Update your queries Here are common query patterns and how to migrate them: #### Simple Queries ```diff # Vercel Postgres SDK const { rows } = await sql`SELECT * FROM users WHERE id = ${userId}`; // [!code --] # Neon HTTP const rows = await sql`SELECT * FROM users WHERE id = ${userId}`; // [!code ++] # Neon WebSockets const { rows } = await pool.query('SELECT * FROM users WHERE id = $1', [userId]); // [!code ++] ``` #### Transactions ```diff import { db } from '@vercel/postgres'; // [!code --] async function transferFunds(fromId: number, toId: number, amount: number) { // [!code --] const client = await db.connect(); // [!code --] try { // [!code --] await client.query('BEGIN'); // [!code --] await client.query('UPDATE accounts SET balance = balance - $1 WHERE id = $2', [ // [!code --] amount, // [!code --] fromId, // [!code --] ]); // [!code --] await client.query('UPDATE accounts SET balance = balance + $1 WHERE id = $2', [amount, toId]); // [!code --] await client.query('COMMIT'); // [!code --] } catch (e) { // [!code --] await client.query('ROLLBACK'); // [!code --] throw e; // [!code --] } finally { // [!code --] client.release(); // [!code --] } // [!code --] } // [!code --] import { Pool } from '@neondatabase/serverless'; // [!code ++] async function transferFunds(fromId: number, toId: number, amount: number) { // [!code ++] const pool = new Pool({ connectionString: process.env.DATABASE_URL }); // [!code ++] try { // [!code ++] await pool.query('BEGIN'); // [!code ++] await pool.query('UPDATE accounts SET balance = balance - $1 WHERE id = $2', [amount, fromId]); // [!code ++] await pool.query('UPDATE accounts SET balance = balance + $1 WHERE id = $2', [amount, toId]); // [!code ++] await pool.query('COMMIT'); // [!code ++] } catch (e) { // [!code ++] await pool.query('ROLLBACK'); // [!code ++] throw e; // [!code ++] } finally { // [!code ++] await pool.end(); // [!code ++] } // [!code ++] } // [!code ++] ``` ## Best practices 1. **Choose the right connection method**: - Use HTTP (`neon()`) for single queries and simple transactions. - Use WebSockets (`Pool`) for complex transactions and session-based operations. 2. **Connection management**: - For HTTP queries, reuse the `sql` query function. - For WebSocket connections in serverless environments, always close connections: ```typescript const pool = new Pool({ connectionString: process.env.DATABASE_URL }); try { // Your queries here } finally { await pool.end(); } ``` 3. **Error Handling**: ```typescript try { const result = await sql`SELECT * FROM users`; return result; } catch (error) { console.error('Database error:', error); throw new Error('Failed to fetch users'); } ``` ## Working with ORMs Neon's serverless driver is compatible with popular ORMs like Prisma and Drizzle ORM. Check out the following guides to learn more: Prisma Drizzle ORM ## Advanced Configuration For most cases, using neon serverless driver is straightforward without needing advanced configuration. However, for custom setups or troubleshooting, here are the key options: - **poolQueryViaFetch**: Setting `poolQueryViaFetch` to true sends `Pool.query()` calls as low-latency `HTTP` fetch requests (currently defaults to false). - **wsProxy**: This option is for connecting via a WebSocket proxy deployed in front of your your own Postgres instance, which allows you to use the Neon serverless driver with a local development environment. For more information about these options, see [Advanced configuration](https://github.com/neondatabase/serverless/blob/main/CONFIG.md#advanced-configuration).