캐싱

Caching

방법

한 번 만든 결과를 따로 저장해 두었다가 같은 요청이 다시 오면 처음부터 만들지 않고 저장해 둔 것을 내주는 기법입니다.

등장 배경

서버는 요청을 받을 때마다 같은 일을 처음부터 다시 했습니다. 팀 문서 목록을 여는 요청이 들어오면 데이터베이스에서 문서 200건을 꺼내고, 각 문서에 누가 접근할 수 있는지 권한을 확인하고, 수정 시각 순으로 정렬해 화면에 실을 형태로 만듭니다. 1초 뒤에 옆자리 동료가 같은 목록을 열면 그 1초 사이에 바뀐 것이 하나도 없는데도 서버는 똑같은 과정을 처음부터 되풀이했습니다.

한 사람이 쓸 때는 이 낭비가 보이지 않습니다. 문제는 같은 화면을 동시에 여는 사람이 늘어날 때 드러납니다. 월요일 오전 9시에 전 직원이 출근해 문서 목록을 여는 순간 서버는 초당 수백 번 같은 계산을 하고, 평소 0.2초에 끝나던 응답이 3초로 늘어집니다.

그래서 나오는 대화가 "서버를 늘립시다" 입니다. 서버를 두 배로 늘리면 실제로 느려지는 시점이 뒤로 밀리기는 합니다. 다만 늘어난 서버도 같은 계산을 되풀이하므로 비용만 두 배가 되고 낭비의 비율은 그대로입니다. 캐싱은 반대쪽에서 접근합니다. 계산을 더 빨리 하거나 더 많이 하는 대신, 이미 한 계산의 결과를 들고 있다가 그대로 내주어 계산 자체를 건너뜁니다.

사용 절차

저장할 대상을 고르고, 둘 자리를 정하고, 언제 버릴지를 정하는 순서로 적용합니다. 이 세 가지가 정해지지 않은 캐싱은 틀린 화면을 빠르게 보여 주는 장치가 됩니다.

  1. 무엇을 저장할지 고릅니다. 만드는 데 오래 걸리면서 자주 요청되고 자주 바뀌지는 않는 것이 후보입니다. 문서 목록은 하루에 수천 번 요청되고 수정은 몇 번뿐이라 잘 맞습니다. 반대로 지금 누가 이 문서를 보고 있는지는 초 단위로 바뀌므로 후보가 아닙니다.
  2. 어디에 둘지 정합니다. 사용자의 브라우저에 두면 그 사람의 두 번째 방문만 빨라지고, 서버 쪽 메모리에 두면 모든 사용자가 함께 덕을 봅니다. 사용자와 가까운 지역 거점에 두는 방식이 CDN입니다. 서울 사용자가 미국 서버까지 다녀오지 않아도 되므로, 요청을 보낸 뒤 첫 바이트가 도착하기까지 걸린 시간인 TTFB가 눈에 띄게 줄어듭니다.
  3. 얼마나 오래 들고 있을지 정합니다. 보통 유효 기간을 초 단위로 적어 둡니다. 로고 이미지처럼 바뀌지 않는 파일에는 1년을 주고, 문서 목록처럼 수정될 수 있는 응답에는 30초나 5분을 줍니다. 짧게 잡으면 효과가 줄고 길게 잡으면 낡은 내용을 보여 줄 위험이 커집니다.
  4. 원본이 바뀌었을 때 저장해 둔 것을 어떻게 버릴지 정합니다. 기간이 지나기를 기다리는 방법과 바뀌는 순간 지우는 방법이 있습니다. 문서를 수정하는 코드에서 그 팀의 목록 캐시를 함께 지우도록 해 두면 수정이 곧바로 반영됩니다. 지워야 할 자리를 빠뜨리면 그 화면만 며칠씩 옛 내용을 보여 줍니다.
  5. 실제로 맞고 있는지 확인합니다. 전체 요청 중 저장해 둔 것으로 답한 비율을 봅니다. 이 비율이 90퍼센트면 서버가 하던 계산의 열에 아홉이 사라진 것이고, 20퍼센트면 유효 기간이 너무 짧거나 저장할 대상을 잘못 고른 것입니다.

적합한 상황과 한계

읽는 횟수가 쓰는 횟수보다 훨씬 많고, 같은 요청에 같은 답을 내줘도 되는 자리에 잘 맞습니다. 공개된 도움말 문서는 하루에 5만 번 읽히고 수정은 한 달에 두세 번이라 거의 모든 요청을 저장해 둔 것으로 처리할 수 있습니다.

반대로 사람마다 다른 내용이 나가는 화면에는 쓰기 어렵습니다. 내 알림 목록이나 내 결제 내역이 그렇습니다. 굳이 저장한다면 사용자별로 따로 저장해야 하는데, 그러면 저장 공간은 사용자 수만큼 늘고 각 사용자는 자기 것을 한 번씩만 쓰므로 재사용이 거의 일어나지 않습니다.

한계는 세 가지입니다. 첫째는 낡은 내용입니다. 원본이 바뀌었는데 저장해 둔 것이 그대로 남아 있으면 사용자는 없는 문서가 목록에 떠 있는 화면을 봅니다. 둘째는 버릴 자리를 찾기 어렵다는 점입니다. 저장해 둔 것이 서너 군데에 흩어져 있으면 무엇을 지워야 반영되는지 추적하는 일이 기능 하나 만드는 일보다 오래 걸립니다. 셋째는 저장해 둔 것이 한꺼번에 사라질 때입니다. 유효 기간을 전부 같게 잡아 두면 그 시각에 모든 요청이 동시에 원본으로 몰려가, 캐싱이 없을 때보다 오히려 서버가 크게 흔들립니다. 그래서 유효 기간에 몇 초씩 무작위로 차이를 두거나, 만료 직전에 미리 새로 만들어 두는 식으로 피합니다.

실무 용례

"이거 캐싱 걸려 있어서 수정해도 5분은 옛날 화면 보일 거예요."

지금 화면이 틀린 게 아니라 유효 기간이 지나기를 기다리는 중이라는 뜻입니다.

"목록 API 에 캐시 한번 씌워 보죠. 응답 시간 절반은 줄 것 같은데요."

같은 요청이 반복되고 있으니 계산을 건너뛰어 보자는 제안입니다.

"캐시 지우는 걸 빠뜨렸네요. 문서 삭제할 때 목록도 같이 날려야 합니다."

원본이 바뀌었는데 저장해 둔 것을 지우는 코드가 없어서 생긴 사고를 짚는 말입니다.

페이지덱에서 실제로 있었던 일입니다. 태오가 문서 목록 응답에 5분짜리 캐싱을 걸었고 평균 응답 시간이 1.4초에서 0.3초로 내려갔습니다. 그런데 이틀 뒤 고객 문의가 들어왔습니다. 문서를 삭제했는데 목록에 계속 보인다는 내용이었습니다. 삭제하는 코드가 문서 자체는 지우면서 그 팀의 목록 캐시는 건드리지 않고 있었습니다.

태오는 삭제·수정·생성 세 곳 모두에서 해당 팀의 목록 캐시를 함께 지우도록 고쳤습니다. 캐싱에서 어려운 쪽은 저장하는 일이 아니라 버리는 일입니다.

흔한 오해

캐싱을 느린 코드의 해결책으로 보는 경우가 많습니다. 걸기만 하면 응답 시간이 눈에 띄게 줄어드니 그렇게 보입니다. 하지만 저장해 둔 것으로 답하지 못하는 요청은 여전히 원래 속도로 돌아갑니다. 3초 걸리던 조회에 캐싱을 씌우면 평균은 0.4초로 보이지만, 처음 들어온 사용자와 유효 기간이 막 지난 직후에 들어온 사용자는 그대로 3초를 기다립니다. 느린 조회 자체를 고치지 않으면 그 3초는 평균 뒤에 숨어 있다가 트래픽이 몰리는 날 한꺼번에 드러납니다.

많이 저장할수록 빨라진다는 것도 흔한 오해입니다. 저장해 둔 것이 늘면 그만큼 지워야 할 자리도 늘고, 어느 화면이 어떤 저장본을 보고 있는지 아는 사람이 줄어듭니다. 그러다 보면 데이터가 틀린 것 같은데 어디를 지워야 할지 모르는 상태가 옵니다. 저장할 대상을 좁게 고르고 지우는 규칙을 함께 적어 두는 편이 결과적으로 더 빠릅니다.

자주 헷갈리는 용어

용어무엇을 하는가캐싱과의 차이
CDN자원을 사용자와 가까운 지역 거점에서 내려 줍니다저장 자리를 어디에 두느냐에 대한 답이라 캐싱의 반대말이 아닙니다. CDN 은 캐싱을 지역 단위로 펼쳐 놓은 형태입니다
프리페치곧 필요할 자원을 요청이 오기 전에 미리 받아 둡니다캐싱은 이미 온 요청의 결과를 재사용하고, 프리페치는 아직 오지 않은 요청을 앞당깁니다. 캐싱은 두 번째 요청부터, 프리페치는 첫 요청부터 빨라집니다

같이 보면 좋은 페이지

  • 웹 성능

    캐싱이 어느 지표를 줄이는 기법인지 전체 지형에서 확인합니다

  • 압축

    보내는 횟수를 줄이는 캐싱과 달리 보내는 양을 줄이는 기법입니다

연관 용어

마지막 업데이트 2026-09-16