Agent Memory
Self-hosting

Operations

Health checks, upgrades, backups and restores, erasure replay, embedding model changes and other maintenance for self-hosted Agent Memory.

Health checks

EndpointAuthUse
GET /health/livenoneLiveness: the process is up.
GET /health/readynoneReadiness: start-up finished, the schema matches this build, and PostgreSQL and Redis respond. A tenant whose dedicated database is pending reports Degraded.
GET /api/healthnoneSimple { "status": "healthy", "timestamp": … }.
GET /api/versionnone{ "version", "sha" } of the running build.

Point load-balancer health probes at /health/live and readiness gates at /health/ready.

Logs and telemetry

In Production both hosts write JSON log lines with tenant-correlated scopes (tenant, workspace, request). Every error response's traceId appears in the matching log lines. Set Otel__Enabled=true and an OTLP endpoint to export traces and metrics. See Configuration.

Upgrades

Build or pull the new image and update IMAGE.

Run the migration job: docker compose up migrate (the console host with --migrate). It applies schema changes to the control-plane and shared databases and then to every dedicated tenant database. If a dedicated database fails to migrate, that tenant is marked unavailable (its requests answer 503 PLACEMENT_UNAVAILABLE), the others continue, and the command exits non-zero so you can stop the rollout.

Roll the API and worker containers. A new build that finds pending migrations either applies them itself (when Database:ApplyMigrationsOnStartup is on and it has owner connections) or reports not-ready.

Upgrading from releases before agent binding

Keys and grants created before credentials were bound to agents can be backfilled from their own write history. Run the console host with --bind-keys to report the proposed bindings, then --bind-keys --apply in the same deploy step as --migrate, before the new API serves.

Backups and restore

Back up all three databases — agentmemory, tenant_shared, agentmemory_platform — plus every dedicated tenant database. Redis holds caches, idempotency records and short-lived session memory; enable append-only persistence (--appendonly yes) to survive restarts, but PostgreSQL is the system of record.

After restoring a tenant-data database from a backup, re-apply every erasure and purge recorded since the backup was taken, so deleted memories are not resurrected. Run this with the console host, before the API serves:

# dry run — reports what would be re-erased
dotnet /app/console/AgentMemory.dll --replay-erasures --backup-taken-at 2026-10-01T02:15:00Z

# apply
dotnet /app/console/AgentMemory.dll --replay-erasures --backup-taken-at 2026-10-01T02:15:00Z --apply

--tenant <id> or --placement <id> narrow the replay. A non-zero exit means the restored data is not yet clean.

Changing the embedding model

Vectors from different embedding models cannot be mixed. To move a tenant to a new model without downtime, platform operators use the embedding-index endpoints (platform-admin only):

EndpointEffect
GET /api/admin/tenants/{tenantId}/embedding-indexStatus of the tenant's active and inactive index slots.
POST …/embedding-index/rebuildStart re-embedding into the inactive slot with the configured model. A background job does the work.
POST …/embedding-index/cutoverSwitch reads to the rebuilt slot.
POST …/embedding-index/rollbackSwitch back.
POST …/embedding-index/stamp?apply=trueLabel legacy vectors with the tenant's active model generation (dry run without apply).

Refusals (for example a cutover before the rebuild finished) answer 409 with the reason. A configured model wider than the stored vector columns is refused at start-up rather than truncated.

Idle-run consolidation

The maintenance loop consolidates runs idle for longer than MemoryMaintenance:IdleTimeoutMinutes (30 by default), checking every MemoryMaintenance:IntervalMinutes (5), at most MemoryMaintenance:MaxRunsPerTenantPerCycle runs per tenant per pass. It runs in the worker (console host, Runtime__Mode=service) or in the API with MemoryMaintenance__Host=api — configure exactly one.

One-shot commands

API host (dotnet /app/api/AgentMemory.Api.dll …, or docker compose run --rm --no-deps api …):

CommandEffect
--bootstrap-key --tenant-name <name> --agents <a,b>Create a tenant, a workspace and one agent-bound key.
--provision-tenant <spec.json> [--out <result.json>]Idempotently provision a tenant with workspaces, applications, keys and admins.
--purge-workspace-data <tenantId> --confirm <tenant name> [--workspace <id>]…Delete all memory data of a tenant's workspaces (all of them when no --workspace is given). Guarded: the tenant's name must be repeated.

Console host (dotnet /app/console/AgentMemory.dll …):

CommandEffect
--migrateCreate roles and databases and apply all migrations.
--bind-keys [--apply]Backfill agent bindings for legacy keys and grants.
--replay-erasures [--apply]Re-apply recorded erasures after a restore.
--stamp-embedding-generation [--apply]Label unlabelled vectors with the configured embedding generation.

Platform operator console

The user whose email matches Admin:RootEmail gets the operator console at /admin/ after signing in: the tenant directory, plans and quota overrides, tenant operations (such as suspension, maintenance mode and export), dedicated database placements and operational status. Everything else in the console is per organization.

On this page