캐싱 전략, 서버 비용을 절반으로 줄이는 법

요약

사용자가 두 배로 늘어도 서버 비용을 거의 그대로 유지하는 방법이 있습니다. 캐싱은 자주 요청되는 데이터를 원본 저장소보다 가까운 곳에 미리 두는 기법입니다. 페이지 로딩 속도와 인프라 비용을 동시에 잡는 가장 확실한 수단입니다.

서버 비용 청구서를 보고 놀란 적이 있으신가요. 사용자가 늘면 서버 비용이 정비례로 증가하는 것은 당연한 것 같지만, 실제로는 그렇지 않습니다. 캐싱 전략을 제대로 세우면 사용자가 두 배로 늘어도 서버 비용은 거의 그대로 유지할 수 있습니다. 캐싱은 성능 최적화의 첫 번째 원칙이자 비용 절감의 가장 확실한 방법입니다.

캐싱이란 무엇인가

캐싱은 자주 요청되는 데이터를 원본 저장소보다 가까운 곳에 미리 저장해 두는 기법입니다. 매번 데이터베이스까지 가서 데이터를 꺼내는 대신, 이미 꺼내둔 데이터를 바로 전달합니다. 캐싱 없이 운영하면 어떤 일이 벌어질까요. 인기 상품 목록 페이지에 1,000명이 동시에 접속하면 동일한 데이터베이스 쿼리가 1,000번 실행됩니다.

결과는 매번 같은데 데이터베이스는 1,000번 같은 작업을 반복합니다. CPU가 치솟고, 응답시간이 느려지고, 최악의 경우 서버가 다운됩니다. 캐싱을 적용하면 첫 번째 요청의 결과를 메모리에 저장해 두고 나머지 999명에게는 저장된 결과를 즉시 전달합니다.

데이터베이스는 한 번만 일하면 됩니다.

캐싱의 4가지 계층

첫 번째는 브라우저 캐시입니다. HTTP 헤더의 Cache-Control, ETag, Last-Modified를 적절히 설정하면 브라우저가 이미지, CSS, JavaScript 파일을 사용자의 로컬 디바이스에 저장합니다.

같은 페이지를 재방문할 때 서버에 요청조차 하지 않으므로 트래픽이 제로가 됩니다. 두 번째는 CDN 캐시입니다. 정적 파일을 전 세계 엣지 서버에 분산 저장하여 사용자에게 물리적으로 가장 가까운 서버에서 전달합니다.

한국 사용자가 미국 서버에 있는 이미지를 요청하면 200ms가 걸리지만, 한국 CDN 엣지에서 전달하면 20ms로 줄어듭니다. 세 번째는 애플리케이션 캐시입니다. Redis나 Memcached 같은 인메모리 저장소를 사용합니다.

데이터베이스 쿼리 결과, API 응답, 세션 정보를 RAM에 저장하면 디스크 기반 DB보다 약 100배 빠르게 데이터를 제공할 수 있습니다. 네 번째는 데이터베이스 쿼리 캐시입니다. PostgreSQL 같은 데이터베이스는 자주 실행되는 동일 쿼리의 실행 계획과 결과를 내부적으로 캐싱합니다.

무엇을 캐싱하고 무엇을 하지 말아야 하는가

캐싱에 적합한 데이터는 자주 읽히고 잘 바뀌지 않는 데이터입니다. 상품 목록, 카테고리 정보, 사용자 세션, 사이트 설정값, 렌더링된 HTML 페이지, 검색 결과 등이 대표적입니다. 반면 절대 캐싱하면 안 되는 데이터가 있습니다.

결제 금액이 오래된 캐시 때문에 잘못 표시되면 금전적 분쟁이 발생합니다. 실시간 재고 수량이 캐시에 5개로 남아 있는데 실제로는 0이면 주문은 들어오는데 배송을 못 하는 상황이 벌어집니다. 사용자 개인 민감정보도 캐싱하면 다른 사용자에게 노출될 위험이 있습니다.

캐시 무효화라는 난제

컴퓨터 과학에서 가장 어려운 두 가지 문제가 있다는 유명한 농담이 있습니다. 캐시 무효화와 이름 짓기입니다. 캐시에 저장된 데이터가 원본과 달라지면 사용자는 오래된 정보를 보게 됩니다. 상품 가격을 변경했는데 캐시 때문에 고객은 이전 가격을 계속 보고 있다면 문제가 됩니다.

해결 방법은 두 가지를 병행하는 것입니다. TTL(Time-To-Live)을 설정하여 일정 시간이 지나면 캐시가 자동으로 만료되게 하는 방법, 그리고 데이터 변경 이벤트가 발생하면 관련 캐시를 명시적으로 즉시 삭제하는 방법입니다.

자주 바뀌는 데이터는 TTL을 짧게, 거의 안 바뀌는 데이터는 길게 설정하는 것이 기본 전략입니다.

프로덕트 메이커의 캐싱 적용 사례

프로덕트 메이커는 GCP, AWS, Cloudflare 등 여러 인프라 위에서 서비스를 운영해 왔고, 그 경험을 바탕으로 캐시를 4계층 모두에서 적극 활용합니다. 어느 한 솔루션에 묶이지 않고, 트래픽 패턴·운영 비용·기존 스택과의 정합성에 맞춰 가장 적합한 조합을 선택합니다.

정적 에셋은 Cloudflare, CloudFront, Cloud CDN 같은 CDN으로 글로벌 엣지에 분산해 사용자와 가장 가까운 곳에서 응답하게 만들고, HTTP 캐시 헤더를 정확히 설정해 브라우저 레벨에서부터 불필요한 서버 요청을 차단합니다. 인프라 비용의 상당 부분이 트래픽 비용에서 발생하기 때문에, 이 두 가지만 제대로 잡아도 청구서가 눈에 띄게 가벼워집니다.

애플리케이션 계층에서는 백엔드 스택에 맞춰 Redis, Memcached, 매니지드 캐시(ElastiCache, Memorystore) 등을 상황에 맞게 도입합니다. 세션, 자주 조회되는 데이터, 외부 API 응답을 인메모리에 올리면 RAM 속도로 응답이 나갑니다.

실제 한 이커머스 프로젝트에서 캐싱 전략을 재설계한 결과, 서버 평균 응답 시간이 대폭 단축되었습니다. 코드 리팩토링 없이 데이터 접근 경로와 캐시 정책만 손본 결과였습니다. 캐싱은 가장 적은 노력으로 가장 큰 성능 향상과 비용 절감을 동시에 달성하는 수단입니다.

다른 포스팅

캐싱 전략, 서버 비용을 절반으로 줄이는 법

서버 비용 청구서를 보고 놀란 적이 있으신가요. 사용자가 늘면 서버 비용이 정비례로 증가하는 것은 당연한 것 같지만, 실제로는 그렇지 않습니다. 캐싱 전략을 제대로 세우면 사용자가 두 배로 늘어도 서버 비용은 거의 그대로 유지할 수 있습니다. 캐싱은 성능 최적화의 첫 번째 원칙이자 비용 절감의 가장 확실한 방법입니다.

캐싱이란 무엇인가

캐싱은 자주 요청되는 데이터를 원본 저장소보다 가까운 곳에 미리 저장해 두는 기법입니다. 매번 데이터베이스까지 가서 데이터를 꺼내는 대신, 이미 꺼내둔 데이터를 바로 전달합니다. 캐싱 없이 운영하면 어떤 일이 벌어질까요. 인기 상품 목록 페이지에 1,000명이 동시에 접속하면 동일한 데이터베이스 쿼리가 1,000번 실행됩니다.

결과는 매번 같은데 데이터베이스는 1,000번 같은 작업을 반복합니다. CPU가 치솟고, 응답시간이 느려지고, 최악의 경우 서버가 다운됩니다. 캐싱을 적용하면 첫 번째 요청의 결과를 메모리에 저장해 두고 나머지 999명에게는 저장된 결과를 즉시 전달합니다.

데이터베이스는 한 번만 일하면 됩니다.

캐싱의 4가지 계층

첫 번째는 브라우저 캐시입니다. HTTP 헤더의 Cache-Control, ETag, Last-Modified를 적절히 설정하면 브라우저가 이미지, CSS, JavaScript 파일을 사용자의 로컬 디바이스에 저장합니다.

같은 페이지를 재방문할 때 서버에 요청조차 하지 않으므로 트래픽이 제로가 됩니다. 두 번째는 CDN 캐시입니다. 정적 파일을 전 세계 엣지 서버에 분산 저장하여 사용자에게 물리적으로 가장 가까운 서버에서 전달합니다.

한국 사용자가 미국 서버에 있는 이미지를 요청하면 200ms가 걸리지만, 한국 CDN 엣지에서 전달하면 20ms로 줄어듭니다. 세 번째는 애플리케이션 캐시입니다. Redis나 Memcached 같은 인메모리 저장소를 사용합니다.

데이터베이스 쿼리 결과, API 응답, 세션 정보를 RAM에 저장하면 디스크 기반 DB보다 약 100배 빠르게 데이터를 제공할 수 있습니다. 네 번째는 데이터베이스 쿼리 캐시입니다. PostgreSQL 같은 데이터베이스는 자주 실행되는 동일 쿼리의 실행 계획과 결과를 내부적으로 캐싱합니다.

무엇을 캐싱하고 무엇을 하지 말아야 하는가

캐싱에 적합한 데이터는 자주 읽히고 잘 바뀌지 않는 데이터입니다. 상품 목록, 카테고리 정보, 사용자 세션, 사이트 설정값, 렌더링된 HTML 페이지, 검색 결과 등이 대표적입니다. 반면 절대 캐싱하면 안 되는 데이터가 있습니다.

결제 금액이 오래된 캐시 때문에 잘못 표시되면 금전적 분쟁이 발생합니다. 실시간 재고 수량이 캐시에 5개로 남아 있는데 실제로는 0이면 주문은 들어오는데 배송을 못 하는 상황이 벌어집니다. 사용자 개인 민감정보도 캐싱하면 다른 사용자에게 노출될 위험이 있습니다.

캐시 무효화라는 난제

컴퓨터 과학에서 가장 어려운 두 가지 문제가 있다는 유명한 농담이 있습니다. 캐시 무효화와 이름 짓기입니다. 캐시에 저장된 데이터가 원본과 달라지면 사용자는 오래된 정보를 보게 됩니다. 상품 가격을 변경했는데 캐시 때문에 고객은 이전 가격을 계속 보고 있다면 문제가 됩니다.

해결 방법은 두 가지를 병행하는 것입니다. TTL(Time-To-Live)을 설정하여 일정 시간이 지나면 캐시가 자동으로 만료되게 하는 방법, 그리고 데이터 변경 이벤트가 발생하면 관련 캐시를 명시적으로 즉시 삭제하는 방법입니다.

자주 바뀌는 데이터는 TTL을 짧게, 거의 안 바뀌는 데이터는 길게 설정하는 것이 기본 전략입니다.

프로덕트 메이커의 캐싱 적용 사례

프로덕트 메이커는 GCP, AWS, Cloudflare 등 여러 인프라 위에서 서비스를 운영해 왔고, 그 경험을 바탕으로 캐시를 4계층 모두에서 적극 활용합니다. 어느 한 솔루션에 묶이지 않고, 트래픽 패턴·운영 비용·기존 스택과의 정합성에 맞춰 가장 적합한 조합을 선택합니다.

정적 에셋은 Cloudflare, CloudFront, Cloud CDN 같은 CDN으로 글로벌 엣지에 분산해 사용자와 가장 가까운 곳에서 응답하게 만들고, HTTP 캐시 헤더를 정확히 설정해 브라우저 레벨에서부터 불필요한 서버 요청을 차단합니다. 인프라 비용의 상당 부분이 트래픽 비용에서 발생하기 때문에, 이 두 가지만 제대로 잡아도 청구서가 눈에 띄게 가벼워집니다.

애플리케이션 계층에서는 백엔드 스택에 맞춰 Redis, Memcached, 매니지드 캐시(ElastiCache, Memorystore) 등을 상황에 맞게 도입합니다. 세션, 자주 조회되는 데이터, 외부 API 응답을 인메모리에 올리면 RAM 속도로 응답이 나갑니다.

실제 한 이커머스 프로젝트에서 캐싱 전략을 재설계한 결과, 서버 평균 응답 시간이 대폭 단축되었습니다. 코드 리팩토링 없이 데이터 접근 경로와 캐시 정책만 손본 결과였습니다. 캐싱은 가장 적은 노력으로 가장 큰 성능 향상과 비용 절감을 동시에 달성하는 수단입니다.

다른 포스팅