# How memory reaches a reply

On the written channels memory is assembled into the draft, and the limit is relevance rather than length. On a live phone call it goes through `voice_engine.brief()` once, under hard character budgets — knowledge 4 facts and 2,000 characters, memory 700, the contact block 600 — because every character is paid for in the silence before the caller hears a voice.

- **Status:** Available
- **Audience:** both
- **Channels:** email, phone, whatsapp
- **In the app:** #/calls, #/inbox
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/memory/memory-in-channels/

## Two doors, two different costs

The four tiers resolve the same way everywhere. What differs is what happens next. A drafted email is written once, by a model that has as long as it needs, and a slightly longer instruction costs a fraction of a second nobody experiences. A live conversation is different in kind: the person on the other end is listening to silence while the model reads.

The evidence is on the record as `session.instructions_chars`. An instruction of 7,500 characters produced a first token in 1.2–1.8 seconds; 9,600 characters produced 2.3–3.4 seconds. That is the same conversation becoming noticeably worse for the sake of two thousand characters nobody asked for. The budgets exist because of that measurement, not as a precaution.

## What the brief carries, and how much of it

| Part | Budget | Rendered from |
|---|---|---|
| Persona and speaking style | about 2,500 for a human profile | The voice profile resolved for the line or the contact |
| The line's purpose | Not separately capped | The `channel_routes` row for that number |
| The contact's facts and standing instructions | 600 | The contact tier |
| Memory | 700 | All four tiers, resolved narrowest-first |
| Knowledge | 4 facts / 2,000 | Retrieval over the supplied [Knowledge](/docs/knowledge/) sources |
| The hard rules and supervisor guidance | Not separately capped | Connect Rules, and the live panel if a colleague is steering |

The brief is rendered **once per call**, not per turn. That has a consequence people meet the first time they try to fix a call while it is happening: a memory written mid-conversation does not reach the call it was written during. It lands on the next one.

## Why the budget is spent again on every turn

A Live session is re-billed for its entire context on every turn, and production calls run at 92% carried context by input token. So the instruction is not a one-off cost paid at the start of the conversation — it is re-read, re-charged and re-processed each time the voice answers. A 700-character memory block on a twenty-turn conversation is 700 characters twenty times.

Context compression exists for the long conversations this produces, and it is *sized* rather than defaulted: `brief.COMPRESSION_TRIGGER_TOKENS` and `_TARGET_TOKENS` are set deliberately, because the default trigger is the model's whole context window — which is to say, no compression in practice.

> **Note** On the default model, Gemini 3.1 Flash Live, the SDK marks the session **immutable**. Mid-call notes and supervisor guidance cannot reach it: a stalled reply is nudged in silence (`nudge {via: none}`), notes are recorded as undelivered and guidance as `guidance_undeliverable`. Where steering a live conversation matters more than a second per reply, the 2.5 model is the one to pick.

## The written channels

Email, WhatsApp and chat assemble memory into the draft along with the thread and whatever Knowledge the answer needs. There is no published character cap on that path, and inventing one here would be worse than saying so — the practical limit is relevance. A tier stuffed with detail produces replies that mention things nobody asked about, which reads as inattentive rather than well-informed.

**Email** — Longest tolerance for context. Signature and role come from the mailbox, not from memory.
**WhatsApp** — Shorter replies, so a long memory tier is more likely to crowd out the answer.
**Voice** — Hard budgets, rendered once per call, re-charged every turn.
**SMS** — Inbound and STOP work; outbound is foundation and the live carrier carries none, so memory may have no outbound message to shape.

## Questions

### Which memory gets dropped when the budget is reached?

The resolution order is what decides: narrowest first, so contact-tier material is the least likely to be cut and workspace-tier the most. That is the right priority for a conversation with a specific person, and it is another reason to keep the workspace tier short — it is competing with everything more specific than itself.

### Can I raise the budgets?

They are engineering settings rather than a screen control, and raising them buys a longer instruction at a measured cost in time-to-first-word. The productive move is almost always the other one: move background out of memory into Knowledge, where it is retrieved for the answer that needs it instead of carried on every call.

### I wrote a memory during a call and nothing changed. Is that a fault?

No. The brief is rendered once per call, so a row written mid-conversation applies from the next one. On the default model the session is immutable besides, so even a supervisor's guidance is recorded as undeliverable rather than injected. Place the next call and it is there.

## Related

- [The four memory tiers](https://connectbyjbrh.com/docs/memory/tiers/)
- [Business memory](https://connectbyjbrh.com/docs/memory/business-memory/)
- [Retrieving Knowledge for an answer](https://connectbyjbrh.com/docs/knowledge/retrieval/)
- [Phone and voice in Connect](https://connectbyjbrh.com/docs/phone/)
- [What every character of a prompt costs on a live call](https://connectbyjbrh.com/research/prompt-size-and-first-token/)
- [An older fact stopped being used](https://connectbyjbrh.com/docs/troubleshooting/memory-budget/)

## What this page is based on

- docs-source/sources/PHONE.md §7 — instruction size, budgets, immutable session
- docs-source/sources/PHONE.md §4 — re-billed context and sized compression
- docs-source/sources/PHONE.md §3 — brief() renders the call's instruction once
- `docs-source/facts.py` — MEASURED knowledge/memory/contact budgets
