Performance¶
Scope: standalone Python Runtime. For Desktop operations, see the Desktop guide.
Echo Agent's bottlenecks are usually model-call latency and local data I/O. This page covers the tuning levers that exist in the configuration.
Where the time goes¶
Measure model calls, tools and storage waits through traces. There is no measured percentage breakdown that applies to all deployments.
| Bottleneck | Symptom | Where to tune |
|---|---|---|
| Model latency | Long wait before the first token | Model selection, routing, compression |
| SQLite I/O | Slow task or cost queries | Check local storage and indexes; schedule VACUUM if needed |
| Process memory | OOM or swapping | Spill settings, session trimming |
| Knowledge retrieval | Slow similarity search | Chunking, index rebuild |
| Tool execution | External calls time out | Per-tool timeouts, parallel calls |
Model calls¶
Routing by task type¶
Route scenarios to appropriate models to balance cost against speed. Routing rules live in models.routes and match on task_types:
models:
default_model: claude-sonnet-4-5
routes:
- task_types: [chat]
provider: openai
model: gpt-4o-mini
max_tokens: 1000
- task_types: [code]
provider: anthropic
model: claude-sonnet-4-5
max_tokens: 8000
fallback_models: [gpt-4o]
There is no models.routing section grouping models by scenario name — routing is always expressed as a routes list with task_types.
Context compression¶
Echo Agent does not cache model responses (there is no models.cache in the configuration). The lever for reducing repeated input cost is context compression, under compression:
compression:
enabled: true
trigger_ratio: 0.7 # compress when context usage hits this ratio
summary_target_ratio: 0.2 # target share after compression
tool_pruning_enabled: true # prune historical tool output
Parallel tool calls¶
Independent tools run in parallel. The setting is agent.tool_concurrency, enabled by default:
Model fallback
Configure fallback models so a slow or failing primary model switches to a faster alternative. See Model routing and fallback.
SQLite¶
Echo Agent stores part of its runtime data in SQLite. USER and ENVIRONMENT memory entries are stored separately as JSON files under storage.memory_dir.
WAL mode¶
echo_agent/storage/sqlite.py sets PRAGMA journal_mode=WAL when connecting. There is no general database configuration section or exposed tuning field for synchronous, cache_size, or mmap_size.
What is configurable is the set of storage paths, under storage:
storage:
database_path: data/echo_agent.db
sessions_dir: data/sessions
memory_dir: data/memory
logs_dir: data/logs
spill_dir: data/spill
Database-level optimization therefore comes down to two things: keep database_path on a local SSD rather than a network filesystem, and run VACUUM periodically to reclaim fragmentation.
Index maintenance¶
# Check database size and fragmentation
sqlite3 ~/.echo-agent/data/echo_agent.db "
SELECT page_count * page_size as size_bytes FROM pragma_page_count(), pragma_page_size();
"
# Rebuild indexes (offline operation)
sqlite3 ~/.echo-agent/data/echo_agent.db "REINDEX;"
# Reclaim space
sqlite3 ~/.echo-agent/data/echo_agent.db "VACUUM;"
VACUUM regularly
SQLite does not shrink the file automatically after bulk deletes. Schedule VACUUM during low-load periods.
Memory¶
Context and history size¶
Controlled by session (runtime has a single field, single_instance, unrelated to memory):
session:
context_window_tokens: 0 # 0 means use the model's own window
max_history_messages: 500 # history entries retained
compression_window_cap: 200000 # upper bound on the compression window
expiry_hours: 72 # session expiry
Spill¶
Oversized tool output spills to disk. The section is top-level spill, not under runtime:
spill:
enabled: true
max_inline_chars: 6000 # spill past this many characters
max_total_mb: 512 # cap on total spill directory size
retention_days: 7 # retention window
sweep_interval_hours: 6 # cleanup scan interval
The spill directory path comes from storage.spill_dir. Artifacts are read back on demand with the read_spill tool — see the tool reference.
Monitoring¶
# Process status and resource usage
echo-agent status
# Linux: detailed memory maps
cat /proc/$(pgrep -f echo-agent)/status | grep -i vm
Knowledge retrieval¶
Chunking and retrieval size¶
The knowledge index is a local JSON file, not an HNSW-style vector index, so there are no ef_construction / ef_search / m knobs and no knowledge.index subsection. What you can tune is chunking and retrieval size:
knowledge:
enabled: true
chunk_size: 1200 # document chunk size (default 1200)
chunk_overlap: 120 # chunk overlap (default 120)
max_results: 5 # results per retrieval
auto_index: true # index automatically after changes
index_path: data/knowledge_index.json
docs_dir: data/knowledge
Chunks that are too small increase result count and recall noise; too large and you lose precision. Changes take effect only after an index rebuild.
Index rebuild¶
The index is a derived artifact: when its structure is damaged, rebuild rather than repair. Use the knowledge_index tool (action: rebuild) or the Dashboard's Knowledge page.
Embedding and reranking parameters live in the memory section (embedding_backend, rerank_enabled, rerank_top_k and so on) — see the configuration reference.
Network¶
There is no unified network section, and no connection-pool or global-timeout fields. Network settings sit with their consumers:
| Setting | Purpose |
|---|---|
execution.network_policy |
Master outbound switch; packaged default allow (schema default deny) |
tools.web.proxy |
Proxy for the web tool |
tools.web.timeout_seconds |
Web tool timeout, default 30 |
tools.browser.nav_timeout_sec |
Browser navigation timeout |
channels.telegram.proxy |
Proxy for the Telegram channel |
gateway.media_download_concurrency |
Gateway media download concurrency, default 4 |
execution:
network_policy: allow
tools:
web:
enabled: true
proxy: "http://proxy:8080"
timeout_seconds: 30
Web fetching and media downloads share redirect validation and DNS pinning through net_guard; browser requests validate their targets separately. This is not a universal network sandbox for model SDKs, channels or shell subprocesses. Manage their endpoints and deployment network permissions separately.
Resource guidance¶
Starting capacity for a light deployment (not a measured support minimum)¶
| Resource | Planning example | Notes |
|---|---|---|
| CPU | 2 cores | Measure with actual concurrency |
| Memory | 2 GB | Base runtime plus SQLite cache |
| Disk | 1 GB | Database, logs, spill |
| Network | Stable connection | Model API calls |
Recommended¶
| Resource | Recommended | Notes |
|---|---|---|
| CPU | 4 cores | Smooth tool parallelism |
| Memory | 4-8 GB | Comfortable cache headroom |
| Disk | 10 GB SSD | Fast I/O |
| Network | Low latency | Less time waiting on model calls |