오늘 저희는 Data Cache를 Runtime Cache로 통합하여, 개발자들이 프레임워크와 API 전반에 걸쳐 데이터 캐싱을 위한 단일 제품을 사용할 수 있게 합니다. Next.js 캐싱이나 fetch의 불안정한 캐시(unstable_cache)를 사용하더라도 코드를 변경할 필요가 없습니다. Pro 및 Enterprise 프로젝트는 더 큰 스토리지 할당량을 받게 됩니다.
Runtime Cache를 사용하면 별도의 캐싱 서비스를 운영하지 않고도 요청 간에 가져오거나 계산된 데이터를 재사용할 수 있습니다. 지난 한 해 동안, 저희는 트래픽 급증 시 읽기 성능을 개선하고, 스토리지 예산을 늘렸으며, 캐시 사용 현황을 조사하기 더 쉽게 만들었습니다.
Data Cache는 원래 Next.js App Router를 위한 Vercel의 데이터 캐싱 서비스로 출시되었으며, 캐싱 및 fetch를 사용하는 곳에서 활용되었습니다. 전체 HTTP 응답을 저장하는 CDN 캐싱(CDN caching)과 달리, Data Cache는 애플리케이션이 해당 응답을 생성하는 데 사용하는 데이터를 저장합니다. 예를 들어, 제품 페이지는 방문자 개개인에게 개인화된 응답을 렌더링하면서도 캐시된 카탈로그 데이터를 재사용할 수 있습니다.fetch``unstable_cacheCDN caching
저희는 개발자들이 Next.js에 의존하지 않고도 이 서비스에 접근하기를 원했습니다. 작년에 저희는 직접적인 API를 통해 이를 구현했으며, getCache``@vercel/functions와 같은 애플리케이션에서 사용할 수 있습니다. 이 기능을 사용하면 라우팅 미들웨어(Routing Middleware)의 기능 플래그 조회, 빌드 중 CMS 콘텐츠 캐싱, 그리고 SvelteKit 및 Nuxt 앱에서의 데이터 캐싱 등에 활용할 수 있습니다.introduced Runtime CachegetCache``@vercel/functions
프레임워크들도 자체 API를 통해 이 서비스를 노출할 수 있습니다. Vercel에서 Next.js 자체는 함수 및 컴포넌트 출력을 캐싱하기 위해 Runtime Cache API를 사용하여 use cache: remote 기능을 사용합니다.
Runtime Cache의 기반 인프라는 여러 팀이 공유하는 분산형 캐싱 서비스입니다. Go API가 요청을 처리하며, 모든 Vercel 리전의 Redis 클러스터(Redis fleets)에 의해 백업됩니다. 이 서비스는 매시간 4억 4천만 건 이상의 읽기 요청을 처리하고 18 TB 이상의 데이터를 이동시키고 있습니다.
각 리전은 자체 캐시를 가지고 있습니다. 캐시 히트(cache hit)는 코드가 실행되는 리전의 캐시 서비스로 한 번의 왕복(round trip)을 필요로 합니다. Vercel은 단기 자격 증명(short-lived credentials)으로 인증을 처리하므로, API 키를 직접 관리할 필요가 없습니다.
캐시 미스(cache miss)가 발생하면, 앱 또는 프레임워크가 값을 가져오거나 계산하여 해당 리전의 캐시에 기록합니다. 이 서비스는 다른 리전을 검색하여 캐시된 복사본을 확인하지 않습니다.
각 캐시 항목은 태그와 쓰기 시간을 저장합니다. 서비스가 항목을 읽을 때, 동일한 리전에 있는 별도의 태그 스토어(tag store)에서 해당 태그의 무효화 타임스탬프를 확인합니다. 만약 어떤 태그라도 항목이 기록된 이후에 무효화되었다면, 그 항목은 오래된(stale) 상태입니다.
예를 들어, 애플리케이션은 모든 캐시된 제품 데이터에 .catalog와 같은 태그를 지정할 수 있습니다. 카탈로그가 변경되면, 해당 태그를 무효화하는 것은 단일 타임스탬프만 기록하며, 설령 백만 개의 항목이 그 태그를 공유하더라도 마찬가지입니다. 서비스는 개별적으로 이 항목들을 찾아 삭제할 필요가 없습니다.
무효화 작업은 요청을 받는 리전의 태그 스토어를 즉시 업데이트합니다. Vercel의 공유 태그 인프라(shared tag infrastructure)는 (빈칸으로 표시된 컴포넌트)에서도 사용되며, 이 타임스탬프를 글로벌 푸시 파이프라인(global push pipeline)을 통해 분배하여 일반적으로 수백 밀리초 내에 다른 리전에 도달합니다.CDN
앱 또는 프레임워크가 무엇을 캐시할지 결정하고 미스 처리를 담당합니다. 런타임 캐시(Runtime Cache)는 지역별 스토리지, 인증, 그리고 여러 리전으로의 태그 무효화 분배를 처리합니다.
항목이 여전히 최신 상태인지 확인하는 과정은 모든 캐시 히트에 의존성을 추가합니다. 트래픽 급증 시, 태그 스토어 내 느린 샤드(shard)는 캐시된 값이 이미 사용 가능하더라도 읽기 작업을 지연시킬 수 있습니다.
저희는 회로 차단기(circuit breakers)를 추가하여, 읽기 작업이 메모리에 캐시된 태그 타임스탬프를 사용하여 일시적으로 최신 상태를 확인할 수 있게 했습니다. 이를 통해 느린 샤드가 응답할 때까지 기다릴 필요 없이 진행될 수 있습니다. 이 폴백(fallback) 기간 동안, 읽기 작업은 최근 무효화된 데이터를 잠시 최신 데이터로 간주할 수 있습니다.
우리는 8월에 모든 리전에서 브레이커(breakers)를 활성화했습니다. 가장 트래픽이 몰렸던 최대 리전에서도 p99 캐시 서비스 읽기 지연 시간(read latency)은 유사한 트래픽 대비 이전 수준의 약 5분의 1까지 떨어졌습니다. 이 장애 모드에 대한 온콜 알림도 중단되었습니다.
우리는 Pro 프로젝트의 Runtime Cache 스토리지 예산(storage budgets)을 6월에, Enterprise 프로젝트를 10월에 상향 조정하여 애플리케이션이 재사용하는 데이터에 더 많은 공간을 할당했습니다. 이는 새로운 데이터를 위해 캐시된 항목을 제거할 필요성을 줄여줍니다. 자주 항목 제거가 발생하는 Enterprise 프로젝트의 경우, 하루 만에 캐시 미스율(cache miss rates)이 약 절반으로 감소했습니다.
또한 Runtime Cache 뷰에 배포 마커(deployment markers), 재검증 원인(revalidation causes), 쓰기 활용도(write utilization)를 추가했습니다. 이를 통해 출시와 함께하는 캐시 동작의 변화를 비교하고, 항목이 새로고침되는 이유를 확인하며, 캐시에 기록되지만 거의 읽히지 않는 데이터를 식별할 수 있습니다.Observability
우리는 Runtime Cache를 중심으로 캐싱을 간소화하고 있습니다. 이전까지 Next.js 캐싱은 Data Cache와 사용했고, [fetch]는 다른 방식으로 사용했으며, [getCache]는 또 다른 방식을 사용했습니다. 이번 마이그레이션으로 네 가지 API가 모두 Runtime Cache 아래로 통합되어, 여러분과 코딩 에이전트들은 하나의 스토리지 예산 및 사용 도구 세트를 갖게 되었습니다.[fetch``unstable_cache``getCache``'use cache: remote'
캐싱을 사용하거나 [fetch]를 사용하는 경우에도 코드 변경은 전혀 필요하지 않습니다. Pro에서는 각 프로젝트와 환경이 자체 스토리지 할당량을 가지며, 이는 Data Cache의 이전 팀 전체 풀(team-wide pool) 공간보다 8배 더 많습니다. Enterprise 프로젝트는 이전 Data Cache 스토리지보다 10배 많은 용량을 제공받습니다.[fetch``unstable_cache
이전에 청구되지 않던 Data Cache 읽기 및 쓰기는 [Runtime Cache]를 따르게 됩니다. 신규 팀은 Runtime Cache를 자동으로 사용하며, 기존 팀은 마이그레이션 및 결제 세부 정보를 사전에 받게 될 것입니다.Runtime Cache pricing
출시(rollout), 가격 책정(pricing), 그리고 초기 옵트인(early opt-in) 세부 정보를 확인하세요. 마이그레이션하기 전에 캐시 사용량을 검토하고 불필요한 읽기(reads) 및 쓰기(writes)를 줄이려면 다음을 따르세요.changelogoptimization guide
더 읽어보기
런타임 캐시를 구축한 이유
런타임 캐시 작동 방식
출시된 기능
데이터 캐시를 런타임 캐시에 통합하기
트래픽 급증 시 더 빠른 읽기 속도
더 많은 저장 공간 및 적은 제거(eviction) 횟수
캐시 동작에 대한 더 높은 가시성