한 줄로
맥미니 메모리가 32GB 중 25.5GB 차 있었다. 범인은 무거운 앱이 아니라
세션마다 하나씩 뜨는 MCP 서버였다. 세션 21개 × MCP 3종.
전역 등록에서 셋을 빼고 서버를 재시작하니 node+claude 가
15.4GB 에서 5.7GB 로 떨어졌다. 그중 MCP 몫이 약 7GB 다.
문제: 메모리가 80% 인데 범인이 안 보였다
메뉴바의 RunCat 이 80% 를 가리키고 있었다. 25.5 / 32GB.
먼저 확인한 건 이 숫자가 맞느냐였다. 맞았다. 다만 macOS 기준 메모리 압박
(memory pressure)은 49% 로 여유 였다. 압박은 “압축·스왑까지 동원해 쥐어짜는
정도”를 말하고, 사용량과 다른 값이다. 그래서 급한 불은 아니었다.
급하진 않은데 범인은 알아야 했다. 프로세스 목록을 봤더니
약 15GB 가 Claude 세션 21개와 거기 딸린 것들이었다.
세션마다 서버가 하나씩 뜬다
MCP(Model Context Protocol)는 Claude 에 도구를 붙이는 규격이다. 붙이는 방법은
두 갈래인데, 메모리 관점에서는 이 둘이 완전히 다르다.
| 로컬(stdio) | 원격(HTTP) | |
|---|---|---|
| 뜨는 것 | 세션마다 내 컴퓨터에 프로세스 하나 | 없음 (남의 서버로 요청만) |
| 세션 21개면 | 21개 | 0개 |
| 예 |
npx 로 도는 것들 |
https://... 로 등록한 것들 |
문제는 로컬 쪽이다. 세션을 하나 켤 때마다 등록된 로컬 MCP 수만큼 프로세스가
같이 뜬다. 세션 21개에 로컬 MCP 3종이면 63개다.
내가 등록해 둔 셋은 이랬다.
-
chrome-devtools— 브라우저 자동화. 세션 21개 기준 약 4.4GB -
github— GitHub API -
sequential-thinking— 단계적 추론 보조. 둘이 합쳐 약 3GB
합쳐서 약 7GB. 대부분의 세션에서 한 번도 쓰이지 않았다.
쓰지도 않는데 왜 떠 있었나
등록을 전역(user 스코프) 으로 해뒀기 때문이다. 전역에 걸면 모든 세션에
붙는다. 블로그 글을 쓰는 세션에도 chrome-devtools 가 뜬다.
처음 붙일 때는 이게 편했다. 어느 프로젝트에서든 바로 쓰니까. 비용이 보이지
않았던 건 세션을 한두 개 띄울 때는 티가 안 나기 때문이다. 21개가 되고서야
보였다.
셋을 각각 이렇게 정리했다.
-
chrome-devtools→ 전역에서 빼고, 필요한 프로젝트에서만 건다.
브라우저 작업은 이미 다른 도구(ego)로 옮겨둔 상태라 평소엔 쓸 일이 없었다.
성능 트레이스나 Lighthouse 처럼 그 도구로 안 되는 일이 생기면 그때 프로젝트
스코프로 붙인다. -
github→ 폐기.ghCLI 가 하는 일과 겹쳤다. 덤으로 이건 토큰을
~/.claude.json에 평문으로 두고 있었다. -
sequential-thinking→ 폐기. 거의 쓰이지 않았다.
뺐는데 안 빠졌다
설정에서 지웠다. 그런데 메모리가 그대로였다.
이미 떠 있는 세션은 옛 설정을 그대로 물고 있다. MCP 는 세션이 시작할 때
붙으므로, 설정을 바꿔도 그 세션이 다시 시작해야 반영된다. 이건 MCP 만의
얘기가 아니라 “설정을 고쳤는데 안 먹을 때 프로세스 시작 시각부터 본다” 는
일반 규칙의 한 사례다.
세션 하나를 되살리는 방법은 이렇다.
# 세션 안에서 /exit (또는 Ctrl+D 두 번) 로 끄고
claude --resume <세션ID>
터미널 멀티플렉서에서 detach 했다가 다시 붙는 것만으로는 안 빠진다.
그건 화면만 떼었다 붙이는 것이고 프로세스는 계속 살아 있다.
세션이 21개였다. 하나씩 하는 대신 멀티플렉서 서버를 한 번 재시작했다.
| 항목 | 전 | 5분 후 |
|---|---|---|
| node+claude | 15.4GB (node 186개) | 5.7GB (51개) |
| compressor | 8.4GB | 3.5GB |
| 스왑 | 3.14GB | 3.04GB |
21개가 모두 같은 세션 ID로 되살아났다. compressor(메모리가 모자랄 때
압축을 맡는 프로세스)가 8.4GB 에서 3.5GB 로 떨어진 게 눈에 띈다. 압축할
대상이 줄었다는 뜻이다.
⚠️ 10GB 전부가 MCP 몫은 아니다. 재시작은 Claude 세션 자체도 같이
되살리므로 그쪽에서 줄어든 양이 섞여 있다. MCP 로 특정할 수 있는 건 앞서
잰 약 7GB 다.
재시작하면서 밟은 함정
Claude 세션 안에서 멀티플렉서 서버를 다시 띄우면 안 된다.
새 서버가 그 세션의 환경변수(CLAUDE_CODE_CHILD_SESSION)를 물려받는다.
그러면 복원된 모든 판에서 Transcript saving is off 경고가 뜨고 대화 기록이
저장되지 않는다. 21개 판 전부가 그 상태가 됐다.
Claude 바깥 터미널에서 다시 띄워 해결했다.
herdr server stop && zsh -lc 'nohup herdr server >/tmp/herdr-server.log 2>&1 &'
zsh -lc 로 로그인 셸을 거치는 건 그 세션의 환경을 물려받지 않기 위해서다.
하나 더 있었다. 작업 폴더가 홈인 판은 복원할 때 폴더 신뢰 확인창이 뜬다.
기본 선택이 “No, exit” 라서 Enter 를 누르면 Claude 가 꺼진다.
남겨둔 것
이 확인창을 자동으로 넘기게 만들지 않았다. 폴더를 신뢰할지 묻는 창은
그러라고 있는 것이다. 대신 새 세션을 홈이 아니라 이미 신뢰된 하위 폴더에서
시작하기로 했다. 창 자체가 안 뜨게 하는 쪽이다.
chrome-devtools 를 완전히 지우지는 않았다. 성능 트레이스·Lighthouse·
비로그인 상태 재현은 ego 로 대체되지 않는다. 필요한 프로젝트에서만 프로젝트
스코프로 건다.
남는 교훈
“붙여두면 편하다” 와 “붙여둬도 공짜다” 는 다른 말이다.
MCP 를 처음 붙일 때 나는 도구 개수와 기능만 봤다. 각각이 세션마다 프로세스
하나라는 건 세지 않았다. 세션이 한두 개일 때는 그 비용이 보이지 않는다.
그래서 지금은 등록 전에 이걸 먼저 묻는다.
- 로컬인가 원격인가 — 원격(HTTP)은 내 메모리를 안 먹는다. 같은 기능이면 이쪽.
- 모든 세션에 필요한가 — 아니면 전역이 아니라 프로젝트 스코프로 건다.
-
이미 있는 CLI 와 겹치나 —
githubMCP 는gh와 겹쳤다.
세 번째가 가장 자주 걸린다. 터미널에서 한 줄이면 되는 일에 상주 프로세스를
붙이고 있던 셈이다.