Introduction to Prompt Caching in CrewAI
As AI-powered applications scale, the cost of repeated LLM API calls becomes a significant concern. CrewAI, a popular framework for orchestrating role-playing AI agents, supports prompt caching — a technique that stores and reuses responses for identical or semantically similar prompts. This guide walks you through everything you need to know to implement prompt caching effectively in your CrewAI projects, reducing both latency and API spend.
What Is Prompt Caching?
Prompt caching is the practice of storing the results of LLM calls so that when the same prompt is submitted again, the cached response is returned instead of making a new API request. In the context of CrewAI, this means that when multiple agents or tasks generate identical prompts — for example, repeated system instructions, shared context blocks, or common tool descriptions — the framework can skip redundant calls to the underlying LLM provider.
There are two main flavors of caching relevant to CrewAI developers:
- Exact-match caching: Returns a stored response only when the prompt matches byte-for-byte with a previously seen prompt.
- Provider-side prefix caching: Some providers, like Anthropic and OpenAI, cache long prompt prefixes on their servers, reducing the cost of repeated system prompts even when the user message differs.
CrewAI integrates with both approaches, giving developers flexibility depending on their provider and use case.
Why Prompt Caching Matters
Cost reduction is the most obvious benefit, but caching delivers several advantages that compound in production:
- Lower API costs: Cached tokens are billed at a fraction of the standard rate, or not at all for exact local matches.
- Reduced latency: Skipping a network round-trip can shave hundreds of milliseconds off agent responses.
- Improved throughput: Fewer live calls means you stay further from rate limits during peak usage.
- Reproducibility: Cached responses make debugging and testing more deterministic.
In multi-agent CrewAI workflows, where the same system prompt or context document may be referenced dozens of times across tasks, caching can cut total token costs by 50% or more.
How CrewAI Handles Caching Internally
CrewAI uses LiteLLM under the hood for LLM provider abstraction. LiteLLM exposes a caching layer that CrewAI taps into when you enable it. The cache can be backed by an in-memory store, a Redis instance, or a local disk cache. When a crew executes a task, the LLM call is routed through LiteLLM, which checks the cache before forwarding the request to the provider.
The cache key is typically derived from the model name, the full prompt (system + user messages), and any generation parameters such as temperature. This means that even small changes to a prompt will result in a cache miss, so prompt stability is important for maximizing hit rates.
Setting Up Prompt Caching in CrewAI
Prerequisites
Make sure you have CrewAI installed and a working LLM provider configured. This guide uses CrewAI 0.40+ and OpenAI as the example provider, but the same approach works with Anthropic, Azure OpenAI, and others.
pip install crewai crewai-tools litellm redis
Enabling the Built-in Cache
CrewAI exposes caching configuration through the Crew object. The simplest way to enable caching is to set cache=True and provide a cache handler. Here is a minimal example:
from crewai import Agent, Task, Crew, Process
from crewai.llms import LLM
# Define the LLM with caching enabled
llm = LLM(
model="gpt-4o-mini",
temperature=0.2,
)
researcher = Agent(
role="Research Analyst",
goal="Summarize the key points of a given topic",
backstory="You are an expert at distilling complex information.",
llm=llm,
verbose=True,
)
task = Task(
description="Summarize the benefits of prompt caching for LLM applications.",
expected_output="A concise bullet-point summary.",
agent=researcher,
)
crew = Crew(
agents=[researcher],
tasks=[task],
process=Process.sequential,
cache=True, # Enable CrewAI's caching layer
verbose=True,
)
result = crew.kickoff()
print(result)
With cache=True, CrewAI will store the LLM response for this exact prompt. If you run the crew again with the same input, the cached result is returned instantly without an API call.
Using a Persistent Cache Backend
The default in-memory cache is lost when your process exits. For production workloads, use a persistent backend like Redis or a local disk cache via LiteLLM's configuration.
import litellm
from crewai import Agent, Task, Crew, Process
from crewai.llms import LLM
# Configure LiteLLM to use Redis as the cache backend
litellm.cache = litellm.Cache(
type="redis",
host="localhost",
port=6379,
password="yourpassword",
)
llm = LLM(model="gpt-4o-mini", temperature=0.2)
writer = Agent(
role="Content Writer",
goal="Write a short article based on an outline.",
backstory="You are a skilled writer with a concise style.",
llm=llm,
)
outline_task = Task(
description="Write a 200-word article about renewable energy.",
expected_output="A short article.",
agent=writer,
)
crew = Crew(
agents=[writer],
tasks=[outline_task],
cache=True,
)
# First run: cache miss, makes an API call
result_one = crew.kickoff()
# Second run: cache hit, returns stored result
result_two = crew.kickoff()
assert result_one.raw == result_two.raw
print("Cache hit confirmed!")
Disk-Based Cache for Local Development
If you do not want to run Redis locally, a disk-based cache is a convenient alternative for development and testing:
import litellm
litellm.cache = litellm.Cache(type="disk", path="./.litellm_cache")
This stores cached responses as files on disk, surviving process restarts without any external dependencies.
Leveraging Provider-Side Prefix Caching
Beyond CrewAI's own cache, you can take advantage of provider-side caching. Anthropic, for example, supports explicit cache breakpoints in prompts. Long system prompts, tool definitions, and reference documents can be marked as cacheable, reducing the cost of subsequent calls that reuse the same prefix.
from crewai import Agent, Task, Crew
from crewai.llms import LLM
# Anthropic models support prompt caching natively
llm = LLM(
model="anthropic/claude-3-5-sonnet-20240620",
temperature=0.3,
extra_params={
"cache_control": {"type": "ephemeral"},
},
)
analyst = Agent(
role="Financial Analyst",
goal="Analyze quarterly earnings reports.",
backstory="You have 20 years of experience in equity research.",
llm=llm,
)
# A large reference document included in the task description
with open("earnings_report.txt", "r") as f:
report_text = f.read()
task = Task(
description=f"""Analyze the following earnings report and provide
a summary of key metrics:
{report_text}
""",
expected_output="A summary with revenue, EPS, and guidance.",
agent=analyst,
)
crew = Crew(agents=[analyst], tasks=[task], cache=True)
result = crew.kickoff()
When using Anthropic's cache control, the first call writes the prefix to Anthropic's cache (billed at a higher write rate), and subsequent calls within the cache's TTL (typically 5 minutes) read from it at a steeply discounted rate.
Best Practices for Maximizing Cache Hits
Keep Prompts Stable
Cache keys are sensitive to every character in the prompt. Avoid injecting timestamps, random IDs, or other volatile values into system prompts or shared context. If you must include dynamic data, place it at the end of the prompt so the stable prefix can still benefit from provider-side caching.
Structure Prompts for Prefix Caching
Organize your prompts so that the largest, most stable content appears first. A recommended structure is:
- System prompt (role, rules, format)
- Tool definitions
- Reference documents
- Dynamic user input
This ordering maximizes the portion of the prompt that can be cached by providers like Anthropic and OpenAI.
Set Appropriate Temperatures
Caching is most valuable when responses are deterministic. Use low temperatures (0.0–0.3) for tasks where consistency matters, such as data extraction, summarization, or classification. Higher temperatures produce varied outputs that are less useful to cache.
Monitor Cache Hit Rates
LiteLLM logs cache hits and misses. Enable verbose logging during development to measure your hit rate and identify prompts that are not being reused as expected.
import litellm
litellm.set_verbose = True
Use Caching for Read-Heavy Workloads
Caching shines in scenarios like batch processing, evaluation pipelines, and interactive demos where the same prompts recur. For one-off, highly personalized tasks, the overhead of cache management may not be worth it.
Common Pitfalls and How to Avoid Them
- Stale cache entries: If your reference documents change, clear the cache to avoid returning outdated responses. Use versioned cache keys or namespace your cache by content hash.
- Over-caching creative tasks: Caching a brainstorming agent defeats its purpose. Disable caching for tasks that thrive on variability.
- Ignoring TTLs: Provider-side caches expire. If your workflow runs over a long period, expect cache misses after the TTL window and budget accordingly.
- Mismatched parameters: Changing
temperature,max_tokens, or model version between runs invalidates the cache. Pin these values in configuration.
Measuring Cost Savings
To quantify the impact of caching, track token usage before and after enabling it. LiteLLM provides callback hooks for logging usage:
import litellm
total_cost = 0.0
def log_usage(kwargs, completion_response, start_time, end_time):
global total_cost
cost = litellm.completion_cost(completion_response=completion_response)
total_cost += cost
cached = completion_response.get("_hidden_params", {}).get("cache_hit", False)
print(f"Call cost: ${cost:.6f} | Cache hit: {cached}")
litellm.success_callback = [log_usage]
# Run your crew here...
# After execution, total_cost reflects actual spend
print(f"Total spend: ${total_cost:.4f}")
Compare this figure against a non-cached baseline run to calculate savings. Many teams report 40–70% reductions in token costs after implementing caching for repetitive workflows.
Conclusion
Prompt caching is one of the highest-leverage optimizations available to CrewAI developers. By enabling CrewAI's built-in cache, choosing a persistent backend like Redis or disk, and structuring prompts to take advantage of provider-side prefix caching, you can dramatically reduce both API costs and response latency. The key is to combine stable, well-ordered prompts with disciplined cache management — monitor hit rates, version your cache keys when content changes, and reserve caching for deterministic, read-heavy tasks. With these practices in place, your CrewAI crews will run faster, cheaper, and more predictably at scale.