Prompt caching

Every turn sends the model the whole conversation again: instructions, tool descriptions, everything said so far, plus your new message. Most of that is identical to the previous request. Prompt caching lets the Syntic platform keep that repeated start of the request ready, so the next turn reads it from the cache instead of processing it from scratch. Cached input is cheaper and faster than fresh input.

You do not have to switch anything on. This page explains what Syntic Code does to keep the cache useful, what breaks it, and the few settings you can change.

How a request is laid out

The cache works on the beginning of a request. A later request can reuse a cached part only if everything up to that point is exactly the same, byte for byte. So Syntic Code orders each request from most stable to least stable, and places cache markers where the stable part ends:

PartChangesCached
Core instructions and tool rulesAlmost never in a sessionYes, marker at its end
Session details: environment, git status at start, memory files, working folderOnce per sessionNo (kept after the marker so they cannot spoil the part above)
Earlier conversationGrows each turn, but old parts stay the sameYes, a rolling marker on the last message before your new one
Your new messageEvery turnNo

The system prompt is split in two at a fixed boundary. Everything before it is the same for every session on every machine, so it is cached as one block. Session details come after it, so a different folder or branch does not throw away the cached instructions.

A second, rolling marker moves forward as the conversation grows. It always sits on the newest message that will still be identical in the next request, so each turn reuses everything up to the previous turn.

Where the cache lives

The cache is kept by the Syntic platform, not on your computer. It is tied to your account and the exact request content. Nothing extra is stored locally.

What keeps the cache warm

  • The system prompt is built once. By default it is assembled when the session starts and reused for every request. Editing SYNTIC.md in the middle of a session does not change the cached prefix.
  • Steady tool list. Tool descriptions are part of the cached start. They stay the same until you connect or remove an MCP server or a plugin.
  • Sibling subagents start a moment apart. When the agent starts several subagents of the same type at once, they share the same opening. The first one starts at once and the others wait briefly, so they read the cache the first one wrote instead of each paying to write it. The wait is 1,500 ms by default; SYNTIC_AGENT_STAGGER_MS changes it, and 0 turns it off.

What breaks the cache

These change the start of the request, so the next turn is processed fresh and the cache is rebuilt from there:

ActionWhy
Switching model (/model, fast mode)Each model has its own cache.
Compacting (/compact or automatic)The old conversation is replaced by a summary.
Connecting or removing an MCP server, turning a plugin on or offThe tool descriptions change.
Rewinding to an earlier messageThe conversation after that point is gone.
A pause longer than the cache lifetimeThe cached entry has expired (see below).
Starting with --system-prompt-snapshot offThe system prompt is rebuilt every request, so edits show up at once but the instructions block is re-sent each time.

Working on files, running commands and asking new questions do not break the cache: they only add to the end.

Cache lifetime

A cached entry expires if it is not used for a while. The default lifetime is five minutes, refreshed every time a request reuses it. If you often step away for longer and come back to the same session, a one-hour lifetime saves the cost of rebuilding.

Setting or variableEffect
"promptCacheTtl": "1h"Ask for a one-hour lifetime for the main conversation. "5m" asks for five minutes explicitly.
"subagentPromptCacheTtl": "1h"The same for every subagent. Subagents do not inherit the main setting, because most of them run once.
cacheTtl: 1h in an agent fileA lifetime for that one custom agent, used when subagentPromptCacheTtl is not set.
SYNTIC_ENABLE_PROMPT_CACHING_1H=1Use one hour for the main conversation when no setting chose a lifetime.
SYNTIC_FORCE_PROMPT_CACHING_5M=1Force five minutes everywhere, whatever the settings say.

Order of precedence for the main conversation: SYNTIC_FORCE_PROMPT_CACHING_5M, then promptCacheTtl, then SYNTIC_ENABLE_PROMPT_CACHING_1H, then the platform default.

{
  "promptCacheTtl": "1h",
  "subagentPromptCacheTtl": "5m"
}

Share the cache across machines

In scripted runs on many machines (CI runners, for example), the session details in the system prompt differ from machine to machine. Add --exclude-dynamic-system-prompt-sections to a -p run to leave those details out, so the same task on different runners can reuse one cache. The same switch can be set with SYNTIC_EXCLUDE_DYNAMIC_PROMPT_SECTIONS=1. See Scripting and CI.

Check how well it works

WhereShows
/statsPer model: input, output, cache read (cache r) and cache write (cache w) tokens, plus cost.
--output-format jsonusage.cache_read_input_tokens and usage.cache_creation_input_tokens for the run.
syntic agents --jsonUncached input and output tokens per background run.

A healthy long session shows cache reads far larger than fresh input. If cache writes keep growing while reads stay small, look for one of the actions in What breaks the cache happening every turn.

Cost figures already account for caching: cache reads are billed at a lower rate than fresh input. See Usage and billing.