What is the difference between static and dynamic context?

Short answer: Static context is fixed on every call; dynamic context is assembled fresh from the current situation.

System prompts and standing policies often stay the same. Retrieved memories, tool results, and turn-specific facts change. Naming which pieces are static versus dynamic helps you cache what you can and rebuild only what must stay current.

RAG and memory retrieval both pull content into context before a model generates its response. Not every piece of a context window gets assembled the same way, though. Some content is fixed and identical on every single call, while other content has to be freshly assembled based on exactly what’s happening right now. Being explicit about which category a given piece of content belongs to, rather than treating the whole context window as one undifferentiated blend, clarifies a lot about how a system should actually be built.

What Distinguishes Static Context From Dynamic Context?

Static context is identical across every call, authored once ahead of time and reused without modification: a system prompt, a fixed set of standing instructions, a list of available tools that doesn’t change from one request to the next. Dynamic context is assembled fresh for each specific call, varying based on who’s asking, what they’re asking about, and what’s actually relevant at that particular moment: retrieved memory, recent conversation history, live tool results.

This distinction connects directly to the earlier chapter on system prompts as long-lived memory, since static context is essentially the universal, project-wide layer, while dynamic context is the individually varying layer built fresh on top of it for each specific situation.

Why Does It Matter Which Category a Given Piece of Content Falls Into?

Getting this categorization right determines how a piece of content should actually be engineered. Static content can be optimized once and left alone, since it’s reused identically every time, meaning it’s worth investing real care into getting its wording exactly right, since that investment pays off across every future call rather than needing to be redone. Dynamic content has to be engineered as a process, a reliable pipeline that assembles the right material correctly every single time, since it’s never the same twice and can’t simply be perfected once and forgotten.

Confusing the two leads to real mistakes. Treating something that’s genuinely static as if it needed per-call assembly wastes effort rebuilding something that never actually changes. Treating something that’s genuinely dynamic as if it were static, hardcoding what should have been freshly retrieved, produces exactly the kind of universal-prompt mistake already covered when discussing system prompts, content that’s individually specific getting incorrectly applied to everyone.

Is the Line Between Static and Dynamic Always Perfectly Clean?

Not always, and the boundary can genuinely shift depending on how a system is scoped. A system prompt is static across all users of a given deployment, but if a business runs several distinct deployments, each with its own tailored instructions, that same content becomes more like a bounded, project-scoped piece of dynamic content, one static block per deployment rather than one universal block for everyone globally. What matters isn’t finding one universal, unbreakable rule for exactly where the line falls, but being deliberate about where the line falls in a specific system, and engineering each side according to what that side actually needs.

Does Dynamic Content Ever Become Effectively Static Within a Single Session?

It can, and this is worth noticing because it changes how that content should be handled during that session. A bounded, per-user profile fetched once at the start of a conversation and then reused without re-fetching for the rest of that session behaves like static content for the remainder of that conversation, even though it was dynamically assembled at the outset and would differ for a different user entirely. Recognizing this can save real, unnecessary retrieval cost: if a piece of dynamic content genuinely isn’t going to change again for the rest of an ongoing task, re-fetching it on every single call wastes effort re-deriving something already settled.

How Does Weaviate Engram Support Both Categories Working Together in One System?

Weaviate Engram’s fetched, bounded topics and its ranked, query-driven search naturally map onto these two categories: a fetched profile behaves like a semi-static block, reused as-is for a stretch of interaction, while a ranked search genuinely reassembles fresh, dynamic content for each new question. Consider an auction-house cataloging assistant helping appraisers describe estate-sale items, where standing cataloging standards stay fixed while item-specific research has to be assembled freshly for each new piece:

from engram import EngramClient

client = EngramClient(api_key=os.environ["ENGRAM_API_KEY"])

client.memories.add(
    "This appraiser specializes in mid-century furniture and prefers provenance notes listed before condition details in every catalog entry.",
    user_id="appraiser-2210",
    topics=["AppraiserProfile"],
)

The appraiser’s profile, fetched once at the start of a cataloging session, behaves like static content for the rest of that session, since it isn’t going to change mid-session no matter how many items get cataloged:

profile = client.memories.search(
    query="appraiser profile",
    user_id="appraiser-2210",
    topics=["AppraiserProfile"],
    retrieval_config=FetchRetrieval(limit=1),
)

item_research = client.memories.search(
    query="Any prior notes on this specific maker or piece style?",
    user_id="appraiser-2210",
    properties={"item_id": "lot-4471"},
    retrieval_config=HybridRetrieval(limit=5),
)

The item-specific research search, by contrast, has to be freshly assembled for every single new item that comes across the appraiser’s desk, since each piece genuinely needs its own distinct search rather than reusing whatever was retrieved for the previous item. Treating the profile as effectively fixed for the session, and the item research as genuinely dynamic on every call, keeps the assistant efficient without sacrificing accuracy: nothing gets wastefully re-fetched that didn’t need to be, and nothing gets stale by being reused when it should have been refreshed.

Distinguishing static from dynamic context clarifies how each piece of a context window should be engineered. Having covered how context gets assembled well, it’s worth turning directly to what happens when that assembly goes wrong in specific, recognizable ways, beyond the pollution and rot already covered. Our next chapter, What are context engineering failure modes?, brings those specific patterns together.