Trajectories
Trajectories provide full observability into the memory recall pipeline. Every time a recall operation runs, MemoryLayer records the decision trace — what was searched, how results were filtered, ranked, re-ranked, and whether any fallbacks occurred. Use trajectories to debug unexpected recall results and understand why certain memories were or were not returned.
What Trajectories Capture
A trajectory is a timestamped sequence of events for a single recall operation. Each event records one decision step in the pipeline.
Event Types
| Event Type | Description |
|---|---|
search | Initial vector or text search with query parameters and candidate counts |
filter | Filtering step (by context, tags, importance, time range) with before/after counts |
rank | Scoring and initial ranking of candidates |
threshold | Threshold application that drops low-scoring candidates |
association | Association-based expansion (knowledge graph traversal) |
rerank | Re-ranking pass (e.g., cross-encoder or LLM-based) |
fallback | Fallback triggered when primary results are insufficient |
Each event includes a timestamp and a data dictionary with event-specific details such as candidate counts, score distributions, and applied thresholds.
Retrieve a Trajectory
curl "$MEMORYLAYER_URL/trajectories/$TRAJECTORY_ID?workspace_id=$WORKSPACE_ID" \ -H "Authorization: Bearer $API_KEY"Response:
{ "id": "traj_abc123", "workspace_id": "ws_001", "query": "authentication timeout configuration", "events": [ { "type": "search", "timestamp": "2026-04-01T12:00:00.100Z", "data": { "method": "vector", "candidates_found": 150, "embedding_model": "text-embedding-3-small" } }, { "type": "filter", "timestamp": "2026-04-01T12:00:00.120Z", "data": { "context_id": "config-docs", "before_count": 150, "after_count": 42 } }, { "type": "rank", "timestamp": "2026-04-01T12:00:00.130Z", "data": { "method": "cosine_similarity", "top_score": 0.89, "bottom_score": 0.31 } }, { "type": "threshold", "timestamp": "2026-04-01T12:00:00.135Z", "data": { "threshold": 0.5, "before_count": 42, "after_count": 18 } }, { "type": "rerank", "timestamp": "2026-04-01T12:00:00.250Z", "data": { "method": "cross_encoder", "candidates_reranked": 18 } } ], "created_at": "2026-04-01T12:00:00.095Z", "ttl_seconds": 86400}List Trajectories
curl "$MEMORYLAYER_URL/trajectories?workspace_id=$WORKSPACE_ID&limit=20&offset=0" \ -H "Authorization: Bearer $API_KEY"Response:
{ "trajectories": [...], "total_count": 128, "limit": 20, "offset": 0}Trajectory Expiration
Trajectories are ephemeral by default. Each trajectory has a ttl_seconds field (default 86400 = 24 hours). Expired trajectories return 404 on fetch. This keeps storage lean while providing a window for debugging recent recall behavior.
Debugging Recall Behavior
Why were no results returned?
Walk the event sequence to find where candidates were eliminated:
- Check the
searchevent — were any candidates found? - Check
filterevents — did context or tag filters eliminate too many? - Check
thresholdevents — was the threshold too aggressive?
Why was the wrong memory returned?
- Look at the
rankevent for initial scoring - Check if
rerankchanged the order - Check
associationevents for graph-based expansion that may have introduced unexpected results
Why was recall slow?
Compare timestamps between events to identify latency bottlenecks. Common causes:
- Large candidate sets in the
searchphase - Cross-encoder re-ranking on too many candidates
- Association traversal with deep graph exploration
Typical Trajectory Flow
search -> filter -> rank -> threshold -> [association] -> [rerank] -> [fallback]Not all events appear in every trajectory. For example, fallback only occurs when the primary pipeline returns fewer results than requested, and association only fires when knowledge graph expansion is enabled.