ampup-memory serve. Search indexes are Lance datasets derived from the tables.
Catalogs
AMPUP_MEMORY_PLATFORM picks the catalog. Every non-local platform speaks the Iceberg REST catalog protocol; an adapter
only supplies the address, auth and storage properties.
Storage is resolved per table location:
gs://, s3://, abfss:// (Azure Data Lake Storage Gen2) and file://.
A secret variable can also be given as a file: <VAR>_FILE (for mounted secrets) where the code reads it that way
(SNOWFLAKE_PAT, the DATABRICKS_* credentials).
On BigQuery or Snowflake, the same tables are readable by their own engines.
Laptop: serve --local
DIR/warehouseholds the tables,DIR/indexthe search index,DIR/embeddingsthe embedding cache, andDIR/catalog.jsonnames each table’s current metadata file, so a restart picks up where it stopped.- No Docker, no catalog service, no sign-in. Every request reads as one caller in group
local(or the groups given after the port). It binds to 127.0.0.1 and refuses to start ifAMPUP_MEMORY_SERVE_BINDnames anything else; requests whoseHostorOriginisn’t this machine are refused. - One process owns a directory at a time. Commands with
--local DIR(schema set,runs load,compile,advice,extract,load, …) need the server stopped.
Any Iceberg REST catalog over S3
This is the configuration the repository’s catalog tests run (Apache Iceberg’s REST fixture on MinIO,tests/fixtures/rest-catalog/):
AMPUP_MEMORY_REST_PROPS takes key=value;key=value catalog and storage properties (a REST catalog’s credential
and scope for OAuth, s3.* for storage). The search index reaches S3 through the AWS_* variables.
Results on REST catalogs (from the catalog tests):
- Apache Iceberg’s REST fixture 1.10 (JDBC catalog, S3FileIO) on MinIO: every flow passes, including forget and org delete leaving no object of the removed memory in the bucket.
- Apache Polaris 1.8 as shipped refuses two things a table rewrite needs (
ALLOW_TABLE_LOCATION_OVERLAP,DROP_WITH_PURGE_ENABLED). With both flags on, every flow passes. Without them,users forgetandorg deleterefuse up front and change nothing.
GCS, S3, Azure
Point the catalog’s warehouse at a bucket (gs://…, s3://…, abfss://<filesystem>@<account>.dfs.core.windows.net/…)
and AMPUP_MEMORY_INDEX_URI at a durable location. GCS is reached with GCP_ACCESS_TOKEN when set, else application
default credentials; S3 with the standard AWS_* credentials and AWS_ENDPOINT, AWS_REGION.
Setup steps for a specific cloud (Terraform, Cloud Run, Kubernetes manifests) are not part of this guide yet.
Model providers
Extraction, compiling, advice, judging, routing and dreaming all call a model through one backend (AMPUP_MEMORY_EXTRACT, with per-job overrides). OpenRouter is the default; Amazon Bedrock, Vertex AI, Snowflake
Cortex, Anthropic, and any OpenAI-compatible API (OpenAI, vLLM, Ollama) are direct options for requests that must
stay in a cloud or on a machine. See configuration.md.
Several servers on one catalog
Any number of servers may share a catalog.- Readiness.
GET /readyanswers 503 until warm-up is done (the directory, the ledger, every scope with its indexes), then 200. PastAMPUP_MEMORY_READY_TIMEOUT_SECS(300) of slowness it answers 200 anyway and keeps warming. Any other unknown path (/health,/healthz) answers as soon as the port is bound. - One writer. Background writing (extraction, compiling, advice learning, session sweeps, index updates) runs
on one server per catalog at a time: the holder of a lease kept beside the system tables. A commit is refused
once the lease is lost.
AMPUP_MEMORY_WRITER_LEASE=offskips it, for a catalog no other server shares. Alert onsum(memstore_writer_lease_held) == 0for 5 minutes. - Freshness. A server reads other servers’ writes within
AMPUP_MEMORY_MAX_STALENESS_MS(1000); a read blocks only on a cold cache, right after its own write, or pastAMPUP_MEMORY_HARD_STALENESS_MS(60000). - Stopping. On SIGTERM a server answers
/readywith 503 but keeps answering forAMPUP_MEMORY_SHUTDOWN_DRAIN_SECS(5), then finishes in-flight requests for up toAMPUP_MEMORY_SHUTDOWN_WAIT_SECS(60). A KubernetesterminationGracePeriodSecondsmust cover both plus about 30 seconds. - Behind a load balancer. With sign-in (
AMPUP_MEMORY_CALLER_IDENTITY=token), setAMPUP_MEMORY_PUBLIC_URLto the URL people reach; a server listening beyond loopback won’t start without it. KeepAMPUP_MEMORY_API_KEYSthe same file on every server (each reads it again within 2 seconds of a change), andAMPUP_MEMORY_HEADER_TIMEOUT_SECS(660) above the balancer’s idle timeout. The connection and in-flight caps are per server. - Throughput. Every commit is one compare-and-set on the ledger table: about 1 to 2.5 commits a second under
contention. Batch writes (
/ingesttakes 500 episodes a commit;/runstakes 1,000 runs) where throughput matters.
Maintenance
- Every commit expires its table’s snapshots past
AMPUP_MEMORY_MAINTAIN_KEEP(10).ampup-memory maintain <scope> [keep]does it at once. - Rewrites (table and ledger compaction, scheduled purges, dream passes) run only in a nightly window,
AMPUP_MEMORY_MAINTAIN_WINDOW(default02:00-06:00 America/Los_Angeles;alwaysoroff), one scope at a time. Each scope’s turn logs onemaintenance: {…}line of counts. ampup-memory compact-ledger [--dry-run] [--local DIR]compacts the ledger at once; the window does it up toAMPUP_MEMORY_LEDGER_COMPACT_MAX_FILES(2000) data files and asks for the command past that (memstore_ledger_compaction_cli_needed).- Deletion never waits for the window: forget and retract take effect on request.
Backup and restore
Back up, together and at one point in time:- the warehouse: every scope’s namespace with its data, metadata and episode bodies;
- the
memory_systemnamespace:ledger(without it nothing is visible),directory,directory_snapshot,audit,key_usage; - the catalog’s own record of tables (for a REST catalog, its database);
- outside the catalog:
AMPUP_MEMORY_API_KEYS, the disabled-users file, andAMPUP_MEMORY_SECRET_KEY.
ampup-memory index <scope> at once). Take the backup with servers
stopped, or from a storage snapshot taken after the catalog’s, since commits land in the tables first and the
ledger last. A backup holds what was deleted after it: apply forgets and deletes to backups too, or expire them.
Observability
- Metrics.
/metricsis Prometheus text. Serve it on its own port withAMPUP_MEMORY_METRICS_PORT=9464(expose it to the scraper only), or read it on the public port with the operator’s admin key. Labels come from fixed sets: route templates, statuses, reason codes, the directory’s orgs. Useful series:memstore_http_requests_total,memstore_http_request_seconds,memstore_auth_refusals_total,memstore_index_freshness_lag_seconds,memstore_store_commit_failures_total,memstore_extraction_backlog_episodes,memstore_model_tokens_total,memstore_model_cache_total,memstore_writer_lease_held,memstore_directory_blocked. - Slow requests. A request taking
AMPUP_MEMORY_SLOW_REQUEST_MS(1000) or longer is logged with its route and time. Every advice call and every MCP request is logged once with the caller’s app and outcome. - Errors to Sentry. Set
SENTRY_DSN(andSENTRY_ENVIRONMENTother thanlocal) to report 500s and panics. No DSN is compiled in. ampup-memory support-bundle --engine <url> [--admin-key-file F] [--logs-file F]writes a redacted diagnostics bundle to a directory and sends nothing.
Caps
AMPUP_MEMORY_MAX_EPISODEScaps the episodes a deployment holds across every org; a write past it answers 403{"cap_reached": true}. Reads go on.- Workspaces take
--max-episodes,--max-factsand--max-index-bytes.
Telemetry and the control plane
The engine can enroll with a control plane (ampup-memory deployment enroll) and then send counts-only telemetry. It
sends nothing unless enrolled; AMPUP_MEMORY_TELEMETRY=off sends and writes nothing. ampup-memory telemetry schema prints
the contract, and GET /telemetry (admin key) shows exactly what would be sent. The hosted control plane and
its onboarding wizard are not part of the ampup-memory repository, and the ampup-memory agent deployment agent is not documented here.
Testing
tests/it/rest_catalog.rs run against the fixture above with
source tests/fixtures/rest-catalog/env.sh; without AMPUP_MEMORY_TEST_REST_URI they skip.