The short version: In Letta (formerly MemGPT), you give your agent a background "dream" subagent by passing one flag — enable_sleeptime=True — to client.agents.create in the letta-client Python SDK. Letta then creates two agents that share the same memory blocks: a primary agent that talks to the user, and a sleep-time agent that runs in the background, reflects on the conversation history and any attached files, and rewrites the shared memory into cleaner "learned context." The primary agent stays fast because the memory work happens off the critical path. You pay for it in extra background LLM calls.
That's the whole idea. The rest of this piece is the why it matters and the how to tune it.
Why founders should care#
If you've shipped an agent, you already know the two-front war: users want it to remember everything, and they want it to reply now. Those pull in opposite directions. Cramming more history and richer summaries into the context window makes answers better and responses slower — and it burns tokens on every single turn.
Sleep-time agents let you stop paying that tax on the hot path. The expensive work — deciding what matters, compressing a rambling conversation into a tight profile, reconciling contradictions — is moved into a background agent that doesn't have to answer anyone in real time. Your user-facing latency doesn't move. Your memory quality does.
This is the applied version of a concept we've written about separately: where an agent should spend its thinking. Test-time compute is the thinking you do while the user waits. Sleep-time compute is the thinking you do before they ask. Letta's own benchmarks (from the sleep-time compute paper) put numbers on it: roughly 5× less test-time compute for the same accuracy, and when a context is reused across related queries, about 2.5× lower average cost per query. That last clause is the whole game — more on it below.
What actually gets created#
When you flip the flag, Letta doesn't just add a cron job. It provisions a small multi-agent system:
- A primary agent, wired with
conversation_searchandarchival_memory_searchtools so it can look things up. - A sleep-time agent, wired with tools to edit the primary agent's memory blocks.
- A group binding them, managed by a
SleeptimeManager.
A memory block, in Letta's model, is a labeled, character-limited section of the context window — and critically, blocks can be shared between agents. That shared-block design is what makes the two agents feel like one mind with a subconscious. The sleep-time agent writes; the primary agent reads the result on its next turn. No handoff, no message passing, no glue code from you.
The sleep-time agent's actual job is what Letta calls turning raw context into learned context. Given the original material — conversation history, uploaded files, data sources — it reflects and iteratively derives the important insights, then writes that distilled version into a shared block. It's memory consolidation, and yes, at a publication called dreaming.press we're contractually obligated to point out that this is the closest thing an agent has to sleep: quiet downtime spent reorganizing the day into something worth keeping.
The code#
Enabling it is genuinely one argument. Verify against the official docs as the SDK moves, but the current shape is:
from letta_client import Letta
client = Letta(api_key="LETTA_API_KEY")
# One flag. Letta creates the primary + sleep-time pair,
# grouped and sharing memory blocks.
agent = client.agents.create(
model="openai/gpt-4o-mini",
enable_sleeptime=True,
)
# Talk to the primary agent exactly as normal.
response = client.agents.messages.create(
agent_id=agent.id,
messages=[
{"role": "user", "content": "I'm a solo founder, B2B, pre-revenue."}
],
)
You interact with the primary agent as you always would. The sleep-time agent fires in the background every N steps — default 5 — reading the recent history and updating the shared blocks. By your sixth-ish message, the primary agent is reasoning over a memory that's already been cleaned up, and it never once made the user wait for that cleanup.
To tune how often the dreaming happens, configure the group's manager. Higher frequency means fresher memory but more tokens; lower frequency means cheaper but staler:
from letta_client import SleeptimeManager
# Run the sleep-time agent every 3 turns instead of 5.
group = client.groups.create(
agent_ids=[primary_agent.id],
manager_config=SleeptimeManager(
manager_agent_id=primary_agent.id,
sleeptime_agent_frequency=3,
),
)
The tradeoff is blunt and worth saying plainly: the higher the frequency, the more tokens you spend, but the more revisions the agent gets to make its learned context better. Every sleep-time run is a real LLM call you're paying for, out of view of the user.
The non-obvious insight#
Here's the thing that separates people who benefit from sleep-time agents from people who just double their bill: sleep-time only pays off when the context is known early and reused across many queries.
The economics work because you consolidate once and then amortize that cost over dozens of downstream questions that hit the same memory. A long-running assistant, a customer-support agent that accumulates account history, a research agent chewing on a fixed document set — those reuse context constantly, so the background work gets cheaper per query the longer the session runs. A stateless, one-shot chatbot that never revisits anything gets none of the payoff and all of the extra LLM calls. If your agent doesn't reuse what it learns, don't turn this on.
The second thing to hold onto is that a bad consolidation persists. The sleep-time agent has write access to the shared memory blocks. If it "learns" something wrong — misreads a correction, over-compresses, invents a preference the user never stated — that error is now baked into the block the primary agent trusts, and it can compound across future runs. A dream can turn into a recurring bad dream. We went deep on this failure mode in why a bad memory consolidation can stick around; the short lesson is to keep important facts in their own tightly-scoped blocks and to actually read what the sleep-time agent is writing before you trust it in production.
Where it fits#
Sleep-time is Letta's built-in answer to a problem every agent-memory platform is circling from a different angle — persistence, consolidation, and retrieval without wrecking latency. If you're still deciding on a foundation rather than a feature, our comparison of Mem0, Zep, and Letta covers the tradeoffs; Letta's differentiator is precisely this native primary/sleep-time split rooted in the MemGPT memory-block model.
For most founders the calculus is simple. If your agent is stateful and reuses what it knows, enable_sleeptime=True buys you better memory for the price of some background tokens — and your users never feel the cost. Let the agent dream. Just check its dreams.



