Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Connection pooling for serverless in Next.js
📖 Scenario: You are building a Next.js API route that connects to a PostgreSQL database. Since serverless functions start fresh on each request, you want to reuse database connections efficiently to avoid opening too many connections.This technique is called connection pooling and helps your app stay fast and stable.
🎯 Goal: Create a Next.js API route that uses a connection pool to query the database. You will set up the pool, configure it, write the query logic, and export the handler.
📋 What You'll Learn
Use the pg package to create a connection pool
Configure the pool with a max of 5 connections
Write an async function to query the database for all users
Export a Next.js API route handler that returns the users as JSON
💡 Why This Matters
🌍 Real World
Serverless functions like Next.js API routes start fresh on each request. Without connection pooling, each request opens a new database connection, which can overload the database. Connection pooling reuses connections, improving performance and stability.
💼 Career
Understanding connection pooling is important for backend and full-stack developers working with serverless platforms and databases. It helps build scalable, efficient APIs.
Progress0 / 4 steps
1
Set up the connection pool
Import Pool from pg and create a connection pool called pool with max set to 5.
NextJS
Hint
Use new Pool({ max: 5 }) to create the pool.
2
Configure the database connection string
Add a connectionString property to the pool configuration with the value process.env.DATABASE_URL.
NextJS
Hint
Use connectionString: process.env.DATABASE_URL inside the pool config.
3
Write the query function
Create an async function called getUsers that uses pool.query to select all rows from the users table and returns result.rows.
NextJS
Hint
Use await pool.query('SELECT * FROM users') and return result.rows.
4
Export the API route handler
Export an async default function called handler that calls getUsers, then returns a JSON response with status 200 and the users array.
NextJS
Hint
Use export default async function handler(req, res) and respond with res.status(200).json({ users }).
Practice
(1/5)
1. What is the main benefit of using connection pooling in a Next.js serverless app?
easy
A. It automatically scales the number of serverless functions.
B. It reuses database connections to improve speed and avoid connection limits.
C. It caches API responses for faster loading.
D. It encrypts database connections for security.
Solution
Step 1: Understand connection pooling purpose
Connection pooling allows reusing existing database connections instead of opening new ones each time.
Step 2: Identify benefits in serverless context
This reuse improves speed and prevents hitting database connection limits common in serverless environments.
Final Answer:
It reuses database connections to improve speed and avoid connection limits. -> Option B
Quick Check:
Connection pooling = reuse connections [OK]
Hint: Pooling means reusing connections to avoid limits [OK]
Common Mistakes:
Confusing pooling with caching data
Thinking pooling scales serverless functions
Assuming pooling encrypts connections
2. Which code snippet correctly creates a MySQL connection pool using mysql2/promise in Next.js?
easy
A. const pool = mysql2.createPool({ host: 'localhost', user: 'root', database: 'test' }).promise();
B. const pool = mysql2.promise.createPool({ host: 'localhost', user: 'root', database: 'test' });
C. const pool = mysql.createPool({ host: 'localhost', user: 'root', database: 'test' });
D. const pool = mysql2/promise.createPool({ host: 'localhost', user: 'root', database: 'test' });
Solution
Step 1: Recall mysql2/promise usage
When importing mysql from 'mysql2/promise', mysql.createPool() directly creates a promise-based pool.
Step 2: Match correct syntax
const pool = mysql.createPool({ host: 'localhost', user: 'root', database: 'test' }); correctly uses the mysql2/promise import.
Final Answer:
const pool = mysql.createPool({ host: 'localhost', user: 'root', database: 'test' }); -> Option C
Hint: mysql from 'mysql2/promise'; mysql.createPool() [OK]
Common Mistakes:
Trying to call createPool directly on mysql2/promise import
Missing .promise() for async support
Using wrong import or syntax
3. Given this Next.js API handler using a PostgreSQL pool, what will be the output if the database connection fails?
import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export default async function handler(req, res) {
try {
const client = await pool.connect();
const result = await client.query('SELECT NOW()');
client.release();
res.status(200).json({ time: result.rows[0].now });
} catch (error) {
res.status(500).json({ error: 'Database connection failed' });
}
}
medium
A. Returns JSON with error message 'Database connection failed'.
B. Returns empty JSON object {}.
C. Throws an unhandled exception crashing the server.
D. Returns JSON with current time from database.
Solution
Step 1: Analyze try-catch behavior
If pool.connect() fails, the code jumps to the catch block.
Step 2: Check catch block response
The catch block sends a 500 status with JSON error message 'Database connection failed'.
Final Answer:
Returns JSON with error message 'Database connection failed'. -> Option A
Quick Check:
Error caught = JSON error response [OK]
Hint: Errors in try send JSON error response [OK]
Common Mistakes:
Assuming unhandled exception crashes server
Expecting successful time JSON on failure
Thinking empty JSON is returned
4. Identify the bug in this Next.js serverless function using MySQL connection pooling:
import mysql from 'mysql2/promise';
const pool = mysql.createPool({ host: 'localhost', user: 'root', database: 'test' });
export default async function handler(req, res) {
const connection = await pool.getConnection();
const [rows] = await connection.query('SELECT * FROM users');
res.status(200).json(rows);
}
medium
A. Missing connection.release() after query.
B. Using getConnection() instead of connect().
C. Pool should be created inside the handler.
D. Query syntax is incorrect.
Solution
Step 1: Check connection usage
The code gets a connection from the pool but never releases it back.
Step 2: Understand pooling best practice
Connections must be released with connection.release() to avoid leaks and exhaustion.
Final Answer:
Missing connection.release() after query. -> Option A
Quick Check:
Always release pooled connections [OK]
Hint: Always release connections after use [OK]
Common Mistakes:
Forgetting to release connections
Thinking getConnection() is invalid
Creating pool inside handler causing overhead
5. You want to optimize a Next.js serverless app connecting to PostgreSQL with connection pooling. Which approach best prevents exhausting database connections during high traffic?
hard
A. Close the pool after each query to free resources.
B. Create a new pool inside each API handler call.
C. Use a new client connection for every query without pooling.
D. Create a single global pool instance reused across requests.