CortexDB Docs
Self-Hosting

Upgrading

Move a self-hosted server, its clients and its connectors to a newer release, what each upgrade does to existing data, and how to roll back.

The rest of these docs describe the current release. This page is the one place that lists what changes when you move an existing deployment forward, and what to do about it.

Upgrade procedure

docker pull cortexdb/cortexdb:latest      # or pin a version, e.g. :v0.10.2
docker stop -t 120 cortexdb               # graceful stop; never docker rm -f a running server
docker rm cortexdb
docker run -d --name cortexdb --restart unless-stopped --stop-timeout 120 \
  -p 127.0.0.1:3141:3141 -v cortexdb-data:/data \
  -e CORTEX_INSECURE_NO_AUTH=1 -e CORTEX_EMBEDDING_API_KEY=$OPENAI_API_KEY \
  cortexdb/cortexdb:latest                # same flags + the SAME volume

Give the server 120 seconds to stop

On SIGTERM the server finishes running forgets and erasures (up to 60 s), persists its snapshots, then drains the erasure clean-up pass (up to 20 s). Docker's default stop grace is 10 seconds, after which it kills the process. Use docker stop -t 120, --stop-timeout 120 on docker run, stop_grace_period: 120s in Compose, or TimeoutStopSec=120 in a systemd unit. docker rm -f skips the graceful stop entirely.

Most releases are drop-in: no data migration, and existing data directories work as-is. Check the release notes at cortexdb.ai/changelog for anything that isn't. Take a verified cold backup before a major upgrade, and re-check GET /v1/admin/ready after.

From v0.9.13 to v0.10.1

v0.10.1 opens a v0.9.13 data directory with no migration step and does its one-time work in the background:

  • Erasure index backfill. The first start files every existing event into a new erasure index. Until erasure_index.wal.ready is true on GET /v1/admin/metrics, erasures still work but read the whole store.
  • Belief rebuild (only with incremental layers, CORTEX_V1_LAYERS_INCREMENTAL). Beliefs whose topic key changed are swept and rebuilt; they are missing until GET /v1/admin/layers/stats reports belief_reconcile.done: true. Without incremental layers, old beliefs stay until you run POST /v1/beliefs/build for each scope. Belief ids are now stable across rebuilds; earlier builds minted new ids on every build.
  • Code plane (only with CORTEX_CODE_PLANE on): every registered repository re-indexes once. Repository access is now checked against the repository's scope, not only the tenant: a repository bound under a scope no roster governs answers 404 REPO_NOT_FOUND to per-actor tokens until you register that scope (POST /v1/scopes) and seat its members.

After the upgrade:

  • Capabilities. GET /v1/admin/version lists ten capabilities. Gate the new request fields (language, scripts, query_variants, and the others) on that list: an older server refuses them with 422 INVALID_BODY.
  • Blob links for older events. Events written before the upgrade carry no source_blob_ids, so erasing them does not delete their blobs. Run the backfill once: POST /v1/admin/index-audit/source-blob-links (dry run by default; see Admin).
  • Derived data from enrichment-on stores. Earlier builds could store facts with a lost negation, merge different people into one entity, and count opposite-polarity facts in beliefs. v0.10.1 stops new damage; POST /v1/admin/derived/rederive repairs what is stored, from the event log (Admin). Take a cold backup before an apply.
  • Entity ids. Names with non-ASCII characters now get hashed ids (ent_jose-0f66606aa13f1258). Ids stored earlier (such as ent_Jos_) still resolve on reads.
  • Error codes. A capture that waits on a running forget gets the retriable 409 DESTRUCTIVE_OPERATION_IN_PROGRESS (was 403 POLICY_DENIED). Forgetting an id stored in another scope answers 200 with zero counts (was 502 FORGET_BACKEND_FAILED). A ?wait=indexed capture that a concurrent forget blanked is no longer reported as 502 INDEXING_FAILED. Cancelling a finished erasure answers 404 NOT_FOUND (was 405).
  • Usage ledger. Streamed answers now book their input tokens, so the recorded answer cost rises if your clients stream.

From v0.9.9 or earlier

Several v0.9.10 to v0.9.12 changes affect a deployment that was set up earlier. Check each before upgrading:

  • The key is required on every preset. A request with only X-Cortex-Actor and no bearer now gets 401 on every deployment preset, including the default dev_local. See Authorization.
  • Retention is enforced. A sweeper erases events older than the deployment's default_retention_ttl_secs or a per-scope policy. Check both before upgrading, because expiry is irreversible. See Retention & WAL.
  • Scope types are validated when a scope is created (422 UNREGISTERED_SCOPE_TYPE), following allowed_scope_types. See Scopes.
  • No silent mock embeddings. A configured embedding endpoint without a credential refuses to boot. Earlier images booted on mock embeddings and pinned the data directory to them; such a store needs a fresh volume or the offline rebuild in Embeddings.
  • Cluster flags are refused at boot (exit 78, CLUSTER_MODE_UNSUPPORTED). Earlier images started independent single-node servers. Remove the flags. See Storage & Cluster.
  • The extraction cache is retired. A boot measures the old <data_dir>/extraction_cache and deletes nothing; set CORTEX_EXTRACTION_CACHE_PURGE=1 once to remove it.
  • Usage figures. The durable usage ledger uses one price book for every lane; re-check any cost figures taken from an older server.

Rolling back

A v0.9.13 image opens and serves a data directory v0.10.1 has used. Stop v0.10.1 with the 120-second grace, then start the older image on the same volume. During the rollback window v0.9.13 ignores the new event fields (language, scripts, context.timezone, context.refers_to, source_blob_ids), deletes no blobs on erasure, and builds beliefs without claim keys. After a derived-data repair apply, roll back only by restoring the cold backup taken before it. The v0.10.1 release notes have the full list and the steps for upgrading again.

Clients

Keep every client on its current release; the table in Versioning and SDK compatibility lists them. Points that matter when you upgrade from an older client:

  • cortexdb-mcp 0.2.x used retired endpoints (/v1/remember, /v1/recall_memories) and gets 404 on every call. Releases 0.7.3 and 0.7.4 have tool failures; use the current release.
  • cortexdbai (Python) 0.10.0 and earlier default to port 3142; current releases default to 3141. Pass the URL explicitly either way.
  • cortexdb-cli: cortexdb auth tokens --scope no longer confines a token (0.5.4 sent it as scopes). Use --confine CAP:PREFIX; see CLI.

Connectors

  • GitHub. Connector releases before 0.2.22 stored most GitHub content empty (pull requests without a description, pushes without commits, comments cut at 200 characters, no inline review comments), and 0.2.22 re-keys GitHub records. Events written earlier stay as they were; re-sync to get the full text. See GitHub.

  • Wire keys. From 0.2.21 the key sent to CortexDB is a derived cxsrc: value, so GET /v1/experience/status?idempotency_key= needs the cxsrc: value from the connector log.

  • Freshdesk 0.2.19 or earlier stopped ingesting tickets after 10 conversations. Backfill after upgrading; re-ingest is safe, unchanged records converge on the events already stored:

    cortexdb-sync status                      # note the current cursor first
    cortexdb-sync sync freshdesk --since 2020-01-01T00:00:00Z
  • Teams 0.2.20 or earlier deduplicated an edited message against its first ingest instead of keeping it as a new version. Current releases keep edits.

On this page