Prompt caching trong Claude Code: vì sao phiên của bạn đột nhiên chậm và tốn token
Claude Code gửi lại toàn bộ lịch sử hội thoại ở mỗi lượt — prompt cache là thứ giúp việc đó không tốn tiền. Bài này liệt kê đủ 8 hành động làm mất cache và các hành động an toàn, theo docs chính thức.
Contents
Mỗi lần bạn gửi một tin nhắn trong Claude Code, nó tạo một API request mới. Model không nhớ gì giữa các request, nên Claude Code gửi lại toàn bộ context: system prompt, CLAUDE.md, mọi tin nhắn và tool result trước đó, cộng thêm tin nhắn mới của bạn. Phần lớn request lần này giống hệt lần trước — và prompt caching là cơ chế giúp API khỏi xử lý lại phần không đổi.
Khi cache hoạt động tốt, bạn không nhận ra nó tồn tại. Khi cache vỡ, bạn nhận ra ngay: lượt kế tiếp chậm hẳn, và nếu trả tiền theo token thì hóa đơn nhảy vọt. Bài này liệt kê chính xác những hành động làm vỡ cache — theo tài liệu chính thức của Claude Code.
1. Cache được tổ chức thế nào
API cache theo prefix match: nó so phần đầu của request với nội dung đã xử lý gần đây. Match là tuyệt đối — một thay đổi ở bất kỳ đâu trong prefix làm tính lại mọi thứ phía sau nó. Không có cache theo từng file hay từng đoạn.
Claude Code sắp xếp request sao cho nội dung ít thay đổi nằm trước:
| Layer | Nội dung | Thay đổi khi |
|---|---|---|
| System prompt | Chỉ thị lõi, tool definitions, output style | Bộ tool thay đổi, hoặc Claude Code được upgrade |
| Project context | CLAUDE.md, auto memory, rules | Phiên mới, hoặc sau /clear / /compact |
| Conversation | Tin nhắn, phản hồi, tool results | Mỗi lượt |
Thay đổi ở layer conversation không đụng đến hai layer trên. Thay đổi ở system prompt thì vỡ tất cả, vì mọi nội dung phía sau giờ nằm sau một prefix khác.
Ngoài ra có hai thứ không nằm trong văn bản prompt nhưng vẫn nằm trong cache key:
- Model — mỗi model có cache riêng.
- Effort level — mỗi mức effort có cache riêng cho cùng một model.
Đây là lý do docs khuyên: chọn model và effort ở đầu phiên, để /compact cho các điểm nghỉ tự nhiên giữa các task. Chi tiết về hai trục model/effort tôi đã viết ở bài tra cứu model và effort theo tác vụ.
2. Tám hành động làm mất cache
Mỗi hành động dưới đây khiến request kế tiếp miss một phần hoặc toàn bộ cache — bạn trả một lượt chậm và đắt, sau đó prefix mới được cache lại.
1. Đổi model. Mỗi model một cache. /model giữa phiên nghĩa là request kế tiếp đọc lại toàn bộ lịch sử với 0 cache hit, kể cả khi nội dung y hệt. Lưu ý hai trường hợp ẩn: setting opusplan đổi model mỗi lần bật/tắt plan mode (Opus khi plan, Sonnet khi execute); và automatic fallback trên Fable 5 — khi safety classifier chặn một request, Claude Code tự chạy lại trên Opus, cũng là một lần đổi model.
2. Đổi effort level. Cùng cơ chế — cache key có effort. Claude Code hiện hộp thoại xác nhận trước khi áp thay đổi làm mất cache; đổi về đúng mức đang chạy thì bỏ qua hộp thoại và giữ cache.
3. Bật fast mode. Fast mode thêm một request header nằm trong cache key. Chi phí này trả một lần mỗi hội thoại: sau lượt fast mode đầu tiên, Claude Code giữ nguyên header và chỉ đổi setting speed (không nằm trong cache key), nên tắt/bật lại fast mode sau đó không mất cache nữa. Bật fast mode ở đầu phiên rẻ hơn hẳn bật giữa một phiên dài.
4. MCP server kết nối hoặc ngắt kết nối. Phụ thuộc vào cách tool được load. Với deferred tools (mặc định trên model hỗ trợ tool search): server vào/ra chỉ append nội dung mới, cache an toàn. Với tools load thẳng vào prefix (Haiku, gateway tùy chỉnh, server đánh dấu alwaysLoad): mọi thay đổi làm vỡ cache — và nó có thể xảy ra ngoài ý muốn khi một stdio server chết, HTTP session hết hạn, hay server tự reconnect.
5. Bật/tắt plugin có MCP server. Plugin chỉ chứa skills, commands, agents, hooks, themes thì không bao giờ làm mất cache (nội dung của chúng append vào sau). Chỉ plugin mang theo MCP server mới theo luật ở mục 4.
6. Deny nguyên một tool. Thêm rule deny dạng tên tool trần (Bash, WebFetch, Bash(*)) gỡ tool đó khỏi system prompt → vỡ cache. Rule có scope như Bash(rm *) và mọi rule allow/ask thì an toàn — chúng được kiểm tra lúc Claude gọi tool, không đổi prefix.
7. /compact. Thay lịch sử bằng bản tóm tắt — theo thiết kế thì layer conversation phải vỡ. Điểm hay ít người biết: bản thân lượt tóm tắt lại đọc từ cache (nó dùng chung prefix với hội thoại của bạn), nên phần chậm của compact là sinh bản tóm tắt, không phải cache miss.
8. Upgrade Claude Code. Phiên bản mới thường đổi system prompt hoặc tool definitions → lượt đầu sau upgrade rebuild từ đỉnh. Đau nhất là resume một phiên dài sau khi upgrade: toàn bộ lịch sử được xử lý lại không cache — có thể là request đắt nhất bạn gửi trong ngày.
3. Những hành động an toàn (và vài bất ngờ)
- Sửa file trong repo — nội dung file chỉ vào context khi Claude đọc; sửa file không đổi bản đọc cũ trong lịch sử, Claude Code chỉ append một ghi chú “file đã thay đổi”.
- Sửa CLAUDE.md giữa phiên — không mất cache, nhưng bất ngờ ở chỗ: bản sửa cũng không được áp dụng. CLAUDE.md được đọc một lần lúc mở phiên; nội dung mới chỉ load sau
/clear,/compacthoặc restart. - Đổi output style, đổi permission mode — an toàn (trừ plan mode với
opusplan, vì đó là một lần đổi model). - Gọi skill / command — inject dạng user message, prefix nguyên vẹn.
/recap— khác/compact: chỉ hiển thị tóm tắt, không thay lịch sử./rewind— cắt hội thoại về một lượt cũ. Phần còn lại chính là nội dung cache được build từ trước đó, nên request kế tiếp hit thẳng vào cache entry cũ. Muốn bỏ một nhánh đã đi sai,/rewindrẻ hơn/compactrõ rệt.- Subagent — chạy trong context riêng, tự build cache riêng; cache của phiên chính không bị ảnh hưởng.
4. Cache sống bao lâu (TTL)
Cache entry hết hạn sau một khoảng không hoạt động; mỗi lần hit sẽ reset đồng hồ.
- Gói Claude subscription (Pro/Max/Team): Claude Code tự xin TTL 1 giờ — nghỉ ăn trưa quay lại vẫn còn cache. Nếu bạn đã vượt limit và đang chạy bằng usage credits (trả tiền), TTL tự hạ về 5 phút.
- API key / Bedrock / Vertex / Foundry: mặc định TTL 5 phút (rẻ hơn). Muốn 1 giờ: set
ENABLE_PROMPT_CACHING_1H=1. - Subagent luôn dùng TTL 5 phút, kể cả trên subscription.
Một chi tiết về phạm vi cache: system prompt của Claude Code nhúng working directory, platform, git branch… nên cache thực tế bó theo một máy + một thư mục. Hai worktree của cùng repo miss cache của nhau; hai phiên song song trong cùng thư mục thì đọc chung cache.
5. Tự kiểm tra cache hit rate
API trả về hai con số ở mỗi response, xem trực tiếp nhất qua statusline script đọc object current_usage:
| Field | Ý nghĩa |
|---|---|
cache_read_input_tokens | Token đọc từ cache — tính giá ~10% input thường |
cache_creation_input_tokens | Token ghi mới vào cache — giá cao hơn input thường một chút |
Tỷ lệ read/creation cao = cache đang làm việc tốt. Nếu creation cao lượt này qua lượt khác, một thứ gì đó trong prefix đang thay đổi — dò lại danh sách 8 hành động ở mục 2.
Tóm tắt một dòng
- Chốt model + effort ở đầu phiên. Đổi giữa chừng = đọc lại cả lịch sử.
- Bỏ nhánh sai?
/rewind, đừng/compact. - Sửa CLAUDE.md giữa phiên vô dụng — nó chỉ load lại sau
/clear,/compacthoặc restart. - Phiên chậm bất thường sau khi update Claude Code là bình thường — một lượt rebuild rồi thôi.
Nguồn tham khảo
- How Claude Code uses prompt caching — Claude Code Docs
- Prompt caching — Claude Platform Docs
- Model configuration — Claude Code Docs
Đối chiếu docs lần cuối ngày 14/07/2026. Bài cùng cụm: Chọn Model và Effort trong Claude: bảng tra cứu theo từng tác vụ.