Next.js를 떠올리면 정적 웹사이트나 React 기반 프론트엔드부터 먼저 생각나실 겁니다. 하지만 그것은 이야기의 절반에 불과합니다. Next.js는 완전한 기능을 갖춘 백엔드 API를 구동할 수도 있으며, 다른 백엔드 서비스처럼 호스팅하고 확장할 수 있습니다.
이전 글에서는 Next.js API를 만들고 Sevalla로 배포하는 과정을 다뤘습니다. 당시 예제는 PostgreSQL 데이터베이스에 데이터를 저장하고 요청을 직접 처리하는 방식이었죠. 잘 동작하지만, 트래픽이 늘어나면 매 요청마다 데이터베이스에 접근하는 API는 점점 느려질 수밖에 없습니다.
바로 이 지점에서 캐싱이 빛을 발합니다. Redis를 캐시 계층으로 추가하면 Next.js API를 훨씬 빠르고 효율적으로 만들 수 있습니다. 이번 글에서는 API에 Redis 캐싱을 적용하고 Sevalla로 배포한 뒤, 실측 가능한 성능 향상까지 확인해 보겠습니다.
목차
- 캐싱이 중요한 이유
- Redis란 무엇인가?
- 프로젝트 세팅하기
- Redis 프로비저닝
- 읽기 시 캐시 갱신
- 쓰기 시 캐시 갱신
- Sevalla 배포하기
- Redis가 Next.js API와 궁합이 좋은 이유
- 마무리
캐싱이 중요한 이유
API가 데이터베이스에 접근할 때마다 시간과 리소스가 소모됩니다. 데이터베이스는 구조화된 데이터를 저장하고 조회하는 데는 탁월하지만, 초당 수천 건의 읽기 요청을 처리해야 하는 상황에서는 속도 면에서 최적화되어 있지 않습니다.
캐싱은 자주 조회되는 데이터를 메모리에 유지함으로써 이 문제를 해결합니다. 매번 데이터베이스에 물어보는 대신, 캐시에 데이터가 있다면 API가 즉시 반환할 수 있는 것이죠. Redis는 성능을 위해 설계된 인메모리 키-값 스토어이기 때문에 이 용도에 완벽하게 어울립니다.
예를 들어 매 요청마다 사용자 목록을 데이터베이스에서 가져온다면 쿼리 실행과 결과 반환에 약 200ms가 걸릴 수 있습니다. Redis 캐싱을 적용하면 첫 번째 요청에서 결과가 메모리에 저장되고, 이후 요청들은 10ms 이내에 동일한 데이터를 받게 됩니다. 무려 한 자릿수 차이의 개선입니다.
Redis란 무엇인가?
Redis는 초고속 데이터베이스처럼 동작하는 인메모리 데이터 스토어입니다. 디스크에 읽고 쓰는 대신 메모리에 데이터를 보관하기 때문에 놀라울 정도로 빠르죠. 그래서 장기 저장보다 속도가 중요한 캐시 용도로 널리 사용됩니다.
Redis는 매우 낮은 지연 시간으로 높은 처리량을 감당하도록 설계되었으며, 마이크로초 단위로 응답할 수 있습니다. 덕분에 API 응답 캐싱, 세션 데이터 저장은 물론, 채팅 시스템이나 리더보드 같은 실시간 애플리케이션까지 폭넓게 활용됩니다.
전통적인 데이터베이스와 달리 Redis는 단순함과 속도에 집중합니다. 데이터를 키-값 쌍으로 저장하기 때문에 복잡한 쿼리 없이도 값을 빠르게 조회하거나 갱신할 수 있습니다. 게다가 리스트, 셋, 해시 같은 고급 자료형을 지원하기 때문에 단순한 키-값 스토어보다 훨씬 유연합니다.
Next.js로 만든 API와 결합하면 Redis는 메인 데이터베이스의 부하를 줄이고 클라이언트에 번개같이 빠른 응답을 전달하는 데 큰 역할을 합니다.
프로젝트 세팅하기
먼저 저장소를 클론합니다:
git clone git@github.com:manishmshiva/nextjs-api-pgsql.git next-api디렉터리로 이동한 후 npm install로 패키지를 설치합니다.
cd next-api
npm i.env 파일을 만들고 Sevalla에서 발급받은 데이터베이스 URL을 환경 변수로 추가합니다.
cat .env.env 파일은 다음과 같은 형태여야 합니다:
PGSQL_URL=postgres://<username>:<password>-@asia-east1-001.proxy.kinsta.app:30503/<db_name>이제 애플리케이션을 실행해서 몇 가지 API 요청을 보내며 정상 동작 여부를 확인해 보겠습니다.
앱 시작:
npm run dev데이터베이스 연결을 확인하세요. 브라우저에서 localhost:3000에 접속하면 아래 JSON이 반환됩니다:

새 사용자를 생성해 보겠습니다. Postman으로 DB에 새 항목을 추가하려면 다음 JSON과 함께 POST 요청을 보냅니다:
{"id":"d9553bb7-2c72-4d92-876b-9c3b40a8c62c","name":"Larry","email":"larry@example.com","age":"25"}
브라우저에서 localhost:3000/users에 접속해 레코드가 생성되었는지 확인합니다.

좋습니다. 이제 이 API들에 Redis 캐싱을 적용해 보겠습니다.
Redis 프로비저닝
Sevalla 대시보드로 이동해 “Databases”를 클릭합니다. 목록에서 “Redis”를 선택하고 나머지 옵션은 기본값으로 두면 됩니다.

데이터베이스 생성이 완료되면 “external connection” 옵션을 켜고 공개 접근 가능한 URL을 복사합니다.

.env 파일에는 다음과 같이 작성합니다:
REDIS_URL=redis://default:<password>@<host>:<port>이제 Node.js용 Redis 클라이언트를 설치합니다:
npm install ioredis이제 Redis에 연결해서 users API의 캐시 계층으로 활용할 수 있습니다. 캐싱 구현 방법을 살펴보겠습니다.
읽기 시 캐시 갱신
다음은 Redis를 활용하도록 수정한 users/route.ts입니다:
import { NextResponse } from "next/server";
import { Client } from "pg";
import Redis from "ioredis";
const redis = new Redis(process.env.REDIS_URL!);
async function readUsers() {
const client = new Client({
connectionString: process.env.PGSQL_URL,
});
await client.connect();
try {
const result = await client.query("SELECT id, name, email, age FROM users");
return result.rows;
} finally {
await client.end();
}
}
export async function GET() {
try {
// Check cache first
const cached = await redis.get("users");
if (cached) {
return NextResponse.json(JSON.parse(cached));
}
// Fallback to database if not cached
const users = await readUsers();
// Store result in cache with 60s TTL
await redis.set("users", JSON.stringify(users), "EX", 60);
return NextResponse.json(users);
} catch (err) {
return NextResponse.json({ error: "Failed to fetch users" }, { status: 500 });
}
}이제 /users를 호출하면 다음 순서로 동작합니다:
- API가 먼저 Redis를 확인합니다.
- 데이터가 존재하면 즉시 반환합니다.
- 없다면 PostgreSQL을 조회하고, 그 결과를 Redis에 저장한 뒤 반환합니다.
덕분에 반복 요청이 매우 빨라집니다. 캐시 만료 시간(EX 60)은 데이터 신선도 요구 수준에 맞게 조절하면 됩니다.
Redis 캐싱 없이 /users를 열 번 호출하면 열 번의 데이터베이스 쿼리가 발생합니다. 각 쿼리는 데이터베이스 크기와 네트워크 지연에 따라 대략 150~200ms 정도 걸릴 수 있습니다.
Redis를 적용하면 첫 번째 요청은 캐시를 채우는 과정 때문에 여전히 ~200ms 정도 걸리지만, 이후 모든 요청은 거의 즉각적이라 보통 10ms 미만입니다. 무려 20배의 성능 개선입니다.
초당 수백, 수천 건의 요청을 처리해야 하는 API라면 이 속도 향상이 큰 의미를 가집니다. 캐싱은 지연 시간을 줄여줄 뿐만 아니라 데이터베이스 부하도 함께 덜어줍니다.
쓰기 시 캐시 갱신
현재는 GET 요청만 캐시를 사용합니다. 그런데 새 사용자가 추가되면 어떻게 될까요? 캐시는 여전히 오래된 데이터를 반환할 것입니다.
해결책은 쓰기 작업이 발생할 때마다 캐시를 갱신하거나 삭제하는 것입니다. POST 핸들러를 수정해 보겠습니다:
export async function POST(req: Request) {
try {
const body = await req.json();
const client = new Client({
connectionString: process.env.PGSQL_URL,
});
await client.connect();
const query = `
INSERT INTO users (id, name, email, age)
VALUES ($1, $2, $3, $4)
RETURNING *;
`;
const result = await client.query(query, [
body.id,
body.name,
body.email,
body.age,
]);
await client.end();
// Invalidate cache so next GET fetches fresh data
await redis.del("users");
return NextResponse.json(result.rows[0]);
} catch (err) {
return NextResponse.json({ error: "Failed to add user" }, { status: 500 });
}
}이제 새 사용자가 생성될 때마다 users 캐시가 삭제됩니다. 다음 GET 요청은 데이터베이스에서 최신 데이터를 가져와 캐시를 새로 고친 후, 이후 요청들을 계속 캐시된 데이터로 서빙합니다.
Sevalla 배포하기
코드를 GitHub에 푸시하거나 제 저장소를 포크하세요. 그런 다음 Sevalla에서 새 앱을 생성합니다.

드롭다운에서 저장소를 선택하고 “Automatic deployment on commit” 옵션에 체크합니다. 이렇게 하면 코드를 푸시할 때마다 자동으로 배포됩니다. 리소스 섹션에서는 “Hobby”를 선택합니다.

“Create and deploy”가 아니라 “Create”를 클릭하세요. 아직 PostgreSQL URL과 Redis URL을 환경 변수로 등록하지 않았기 때문에 바로 배포하면 앱이 크래시됩니다.
“Environment variables” 섹션으로 이동해 키 이름 “PGSQL_URL”을 입력하고 값 필드에 URL을 넣습니다. “REDIS_URL” 키에도 동일하게 Redis URL을 추가합니다.

이제 “Overview” 섹션으로 돌아가 “Deploy now”를 클릭합니다.

배포가 완료되면 “Visit app”을 클릭해 API의 라이브 URL을 확인하세요. Postman에서 localhost:3000을 새 URL로 교체하면 배포된 API를 테스트할 수 있습니다.
Redis가 Next.js API와 궁합이 좋은 이유
Redis는 가볍고 매우 빠르며 API 응답 캐싱에 완벽합니다. Next.js 환경에서 특히 잘 어울리는 이유는 다음과 같습니다:
- API 라우트가 서버 사이드에서 실행되므로 Redis에 직접 질의할 수 있습니다.
- 데이터베이스 호출 주변에 캐싱 로직을 간단하게 추가할 수 있습니다.
- Redis는 캐싱 외에도 속도 제한, 세션 저장, pub/sub 같은 패턴에도 폭넓게 활용됩니다.
Sevalla 위에서 Next.js, PostgreSQL, Redis를 조합하면 빠르고 확장 가능하며 배포가 쉬운 스택을 완성할 수 있습니다.
마무리
캐싱은 단순한 최적화 기법이 아니라 실무 API에 반드시 필요한 요소입니다. Next.js는 견고한 백엔드 API를 쉽게 배포할 수 있게 도와주고, 여기에 Redis를 더하면 그 API들이 스케일을 거뜬히 감당할 수 있게 됩니다.
Sevalla는 관리형 PostgreSQL, Redis, 앱 호스팅을 한곳에서 제공하며 이 모든 것을 하나로 묶어줍니다. 환경 변수 몇 개와 GitHub 저장소만 있으면 로컬 개발 환경에서 프로덕션 준비가 된 캐시 적용 API까지 몇 분 만에 도달할 수 있습니다.
이 글이 도움이 되셨기를 바랍니다. AI 관련 실습 튜토리얼을 더 원하신다면 제 무료 AI 뉴스레터 TuringTalks.ai를 구독해 주세요. Linkedin에서도 저를 찾아볼 수 있습니다.
freeCodeCamp의 오픈소스 커리큘럼은 4만 명 이상의 사람들이 개발자로 취업하는 데 도움을 준 무료 코딩 학습 플랫폼입니다. 지금 바로 시작해 보세요.