Operations
Health checks, upgrades, backups and restores, erasure replay, embedding model changes and other maintenance for self-hosted Agent Memory.
Health checks
| Endpoint | Auth | Use |
|---|---|---|
GET /health/live | none | Liveness: the process is up. |
GET /health/ready | none | Readiness: start-up finished, the schema matches this build, and PostgreSQL and Redis respond. A tenant whose dedicated database is pending reports Degraded. |
GET /api/health | none | Simple { "status": "healthy", "timestamp": … }. |
GET /api/version | none | { "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):
| Endpoint | Effect |
|---|---|
GET /api/admin/tenants/{tenantId}/embedding-index | Status of the tenant's active and inactive index slots. |
POST …/embedding-index/rebuild | Start re-embedding into the inactive slot with the configured model. A background job does the work. |
POST …/embedding-index/cutover | Switch reads to the rebuilt slot. |
POST …/embedding-index/rollback | Switch back. |
POST …/embedding-index/stamp?apply=true | Label 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 …):
| Command | Effect |
|---|---|
--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 …):
| Command | Effect |
|---|---|
--migrate | Create 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.