PTENES
Skip to content
TRACK 3 · ADVANCED BEST PRACTICES

🟣 Advanced best practices

You already understand caching and what breaks it. Now comes the day-to-day rule of thumb: when caching solves the problem and when compact resolves how to design the prefix so that never invalidate unintentionally, and a kit of ready-to-use prompts to run in Claude Code today.

price per token ▲ token count ▶ full context 400k @ 1× cache: price ÷10 cache only 400k @ 0,1× compact: tokens ÷20 cache + compact 20k @ 0.1× · the sweet spot

Legend: cache moves the vertical axis down (price per token, ÷10) but doesn’t change the width; compact runs along the horizontal axis (number of tokens, ÷20). They’re different axes — you want both.

3
Modules
18
Topics
~2h
Duration
Advanced
Level

What you'll master by the end of this track

The cache is no longer a mystery to you. What’s left is make good decisions: the cache makes cheaper the price per token, but it doesn’t reduce how many tokens you load — and the context limit (1M) is about quantity. This track teaches you to read both axes and build the prefix for it never invalidate by accident, and provides ready-to-use prompts to audit and fix the cache directly in Claude Code.

Caching vs. compaction

Two different axes. When cached context still costs too much, and when 1 cold compaction write pays for itself.

Cache-friendly architecture

Frozen system, deterministic tools, a fork that reuses the parent’s prefix, a silent invalidator checklist, and pre-warming.

Ready-to-use prompts

6 copyable prompts: audit cache, order tools, decide when to compact, diagnose cache_read=0, review the system and plan breakpoints.

Trail map

0%
0 of 18

Detailed content

3.1 ~40 min · 6 topics

⚖️ Cache vs. Compaction

Caching optimizes the price per token; compaction optimizes how many tokens you carry. Different axes—and only compaction solves the context limit.

0%
What it is:

Caching optimizes the price per token of the context. Compact (summarize the history into a shorter version; in Claude Code, /compact) optimizes how many tokens you load.

Why learn:

Without separating the axes, you think caching “solves everything” and ignore the context limit—or compact too early and lose the warm cache.

Key concepts:

They don’t compete on the same axis; you want both. The decision is when to apply each one.

What it is:

Caching lowers the cost per token, but 400k tokens read at 0.1× still equal ~40k input tokens full per turn, every turn.

Why learn:

The discount is misleading: a huge context that’s cheap per token is still expensive overall.

Key concepts:

0.1× of a lot is still a lot; volume matters even with a high hit rate.

What it is:

The cache makes 900k tokens cheap, but they still take up 900k of 1M. At some point, you can’t continue without compacting or /clear.

Why learn:

The limit is about quantity; only compacting/clearing frees up space.

Key concepts:

Cheap ≠ small; the limit is on quantity, not price.

What it is:

Without compaction: 400k @0.1× ≈ 40k-equiv per turn, forever. Compacting to 20k: 1 cold write of 20k @1.25× ≈ 25k (once), then 20k @0.1× ≈ 2k-equiv per turn.

Why learn:

Payback in ~1 turn; each following turn is ~20× cheaper.

Key concepts:

Replaces one-time cost with much cheaper turns.

What it is:

A bloated context spreads the model’s attention (“context rot”) and, even when read from cache, 400k takes longer to reach the first token (higher TTFT) than 20k.

Why learn:

Compaction improves accuracy and speed, not just cost.

Key concepts:

Fewer tokens = more focus + faster response.

What it is:

Short conversation → DO NOT compact (you only lose the warm cache without any benefit). Large context, near the limit, or quality declining → compact.

Why learn:

The intuition that “compacting always saves money” is false for short conversations.

Key concepts:

Replaces 1 cold write with lighter turns — only worthwhile when enough turns remain.

3.2 ~45 min · 6 topics

🏛️ Cache-friendly architecture and audit

Design the prefix so it never gets invalidated by accident: frozen system, deterministic tools, a fork that copies the parent’s prefix, a checklist, and prewarming.

0%
What it is:

Don’t interpolate the date/time, mode, or user’s name into the system prompt — it comes before the prefix and invalidates everything. Inject dynamic context later, in the messages.

Why learn:

A variable in the system invalidates the entire tools + system cache every turn.

Key concepts:

Stable system = stable prefix; dynamic content goes at the end.

What it is:

Serialize the list of tools always in the same order (sort by name). An unsorted set/dict = variable order = miss.

Why learn:

Tools stay at position 0; an unstable order silently invalidates everything.

Key concepts:

Same order = same bytes = hit.

What it is:

Caching is model-specific. Switching models invalidates everything. Need a cheaper model for a subtask? Use a subagent while keeping the main loop on a single model.

Why learn:

Switching models “just for this one” restarts the entire prefix.

Key concepts:

One model per loop; delegate variation to subagents.

What it is:

A side operation (summary, subagent) that rebuilds system/tools/model differently loses the parent's cache. Copy system/tools/model verbatim and append the specific content at the end.

Why learn:

A well-made fork inherits the warm cache and only writes the new block.

Key concepts:

Identical to the parent's prefix + a turn-specific suffix at the end.

What it is:

Scan what feeds the prefix: datetime.now(), uuid, json.dumps without sort_keys, sets, per-user tools, conditional sections in the system.

Why learn:

These are the culprits behind cache_read_input_tokens always 0.

Key concepts:

Byte-by-byte deterministic prefix.

What it is:

Request max_tokens: 0 when the app starts, it writes the prefix cache and returns immediately. TTL 1h (write ~2×) for traffic with gaps > 5 min.

Why learn:

Only worthwhile if the first latency is noticeable, the prefix is large, and there’s a moment before traffic arrives.

Key concepts:

Warm the cache before the first user; use a 1-hour TTL for long pauses.

3.3 ~30 min · 6 topics

📋 Ready-to-use prompts (copy-run)

Six real, ready-to-paste prompts: each with an objective, a copyable block (with the parts you replace), and how to verify the result in Claude Code.

0%
What it is:

Prompt that asks Claude Code to scan the code that builds the prompt and list every silent invalidator + the fix.

Why learn:

Turns “my cache isn’t hitting” into an actionable checklist.

Key concepts:

Objective + copy-ready block + how to verify.

What it is:

Prompt that asks to sort the serialization of tools by name and confirm the order is stable across requests.

Why learn:

Eliminates the #1 source of silent misses at position 0.

Key concepts:

Stable serialization = identical prefix.

What it is:

Prompt that estimates the per-turn cost of loading the current context versus the one-time cost of compacting it, and makes a recommendation.

Why learn:

Takes the decision out of guesswork and puts numbers on it.

Key concepts:

Cost per turn vs. one-time cold write.

What it is:

Prompt that diffs the prefix bytes between two identical requests and points out the byte that changes.

Why learn:

cache_read_input_tokens always 0 = there’s an invalidator; the diff will find it.

Key concepts:

Two requests, one diff, the guilty byte.

What it is:

Prompt that removes dynamic interpolation from the system prompt and moves it to the end of the messages.

Why learn:

Freeze the system without losing dynamic context.

Key concepts:

Stable at the beginning, dynamic at the end.

What it is:

Prompt that suggests where to put cache_control (end of the stable system prompt; end of the shared section in a variable prefix + suffix) and a warning about the 20-block lookback.

Why learn:

A few breakpoints in the right places go further.

Key concepts:

Max. 4 breakpoints; watch out for the 20-block lookback.