PatternsGuide

Best Practices

Learn effective patterns for using HyperSpark Memory. From tool selection to Decision Intelligence workflows.

Choosing the Right Tool

remember vs ingest

Use remember when:

Storing from conversation context
Using MCP tools with AI assistants
Auto-extracting facts from dialogue

Use ingest when:

Calling REST API directly
Bulk importing from databases
Programmatic memory storage

Decision Intelligence Workflow

Complete Decision Tracking
The full workflow for making and tracking decisions
1

Search for Precedents

Before deciding, check if similar decisions were made before.

// Search for similar past decisions
const precedents = await find_precedent({
  situation: "Customer requesting 20% discount on annual plan",
  outcomeWanted: "successful",
  topK: 5
});
2

Log the Decision

Record your decision with full context and the memories that informed it.

// Log the decision with context
await log_decision({
  action: "approved_20pct_discount",
  context: "Customer requested discount. 3-year customer, no support issues.",
  rationale: "Long-term loyalty justifies retention discount.",
  memoriesConsidered: ["mem_abc123", "mem_def456"], // From precedent search
  setsPrecedent: true,
  policyApplied: "retention_discount_policy"
});
3

Update the Outcome

When you know the result, update the decision for future reference.

// Later, when outcome is known
await update_decision_outcome({
  decisionId: "mem_xyz789",
  outcome: "successful",
  outcomeNotes: "Customer renewed. Revenue retained: $2,400/year.",
  outcomeMetrics: {
    revenue_retained: 2400,
    customer_ltv_years: 4
  }
});

Multi-Tenant Patterns

When to Create Tenants
Use tenants for organizational boundaries

Create a tenant when:

Serving multiple end-customers
Need isolated memory spaces
Want per-customer usage tracking
Building a multi-tenant SaaS

Don't create tenants for:

Different users in same org
Different projects (use domains)
Testing environments
Personal use cases
// Always pass tenantId for tenant operations
await recall({
  query: "customer preferences",
  tenantId: "tenant_acme_corp",  // Scopes to this tenant
  topK: 10
});

Rate Limit Handling

Handling 429 Responses
Gracefully handle rate limits in your application

When you hit your query limit, the API returns a 429 response with helpful headers:

// Response headers on rate limit
{
  "X-Usage-Limit": "8000",
  "X-Usage-Used": "8000",
  "X-Usage-Remaining": "0",
  "X-Usage-Reset": "2025-02-01T00:00:00Z"
}

// Response body
{
  "success": false,
  "error": "Query limit exceeded",
  "code": "LIMIT_EXCEEDED",
  "resetAt": "2025-02-01T00:00:00Z",
  "upgradeUrl": "/dashboard/billing"
}

Best Practices:

Cache frequent queries to reduce API calls
Check X-Usage-Remaining header proactively
Show users a friendly message with resetAt
Consider credit packs for spiky workloads

Common Mistakes to Avoid

Not Restoring Context at Conversation Start

Skipping get_context means the AI has no memory of who the user is.

Wrong:

Jump straight into the task without context

Right:

Call get_context first, then proceed

Using recall When recall_recent is Better

Semantic search is slower and uses embeddings. For "what happened recently?", use the faster option.

Wrong:

recall({ query: "recent activity" })

Right:

recall_recent({ since: "7d" })
Forgetting to Update Decision Outcomes

Decisions logged as "pending" without outcome updates don't build useful precedent data.

Tip: Set revisitAfter when logging decisions to remind yourself to update the outcome later.

Missing tenantId in Multi-Tenant Operations

Without tenantId, operations use the parent org's memory space, not the tenant's.

Wrong:

recall({ query: "..." })  // No tenantId

Right:

recall({
  query: "...",
  tenantId: "tenant_xxx"
})

Ready to build?

Check out our quickstart guide or dive into the full API reference.