GitLoom

The platform

How the hosted service is built — the AWS architecture, what touches your data, and the isolation and reliability guarantees behind it.

https://api.gitloom.cloud is the same engine described in How GitLoom works, run as a multi-tenant AWS service. This page is about that layer specifically: what runs where, what sees your data, and what is and is not guaranteed.

The engine and the cloud are separate modules, not just separate directories

GitLoom ships as two Go modules. The core — git storage, the SQLite/FTS5 index, vector scoring, the toolkit — carries no AWS dependency, and CI fails the build if one appears. Everything cloud-specific (tenant identity, Lambda handlers, DynamoDB, the CDK stack) lives in a second module that depends on the core and never the reverse.

That boundary is enforced by the compiler, not a convention someone has to remember: nothing under the cloud module is importable from the core, because the core's go.mod does not require it. The practical upshot is that the same engine that runs this hosted service is the one the CLI runs on your laptop with no network on the read path — there is one implementation of "what a memory is," not one for the product and a second for the open engine.

Architecture

API Gateway (HTTP API) ──▶ Lambda authorizer (JWT / API key)
        │
        ├─▶ api        namespaces, writes, keys, billing, usage, logs
        ├─▶ retrieve    the read path — retrieval and the graph view, its own function
        │                so nothing else can evict its warm memory cache
        ├─▶ chat        the playground's streaming Bedrock loop, over a Function URL
        └─▶ ingest      SQS-driven worker: extraction, cueing, relation-linking,
                         reconciliation, embedding, commit

Retrieval is deliberately its own Lambda function rather than a route inside the general API handler. A container keeps up to four namespaces warm on local disk to avoid re-fetching a repository on every request; sharing that function with routes that have nothing to do with reading would mean unrelated traffic evicting a cache the read path depends on for its latency budget.

Storage: DynamoDB for tenant metadata, usage counters and keys (single table, conditional writes for correctness); S3 for the packed git repositories, one per namespace; SQS (FIFO) for the ingest queue, grouped by account/namespace so writes to one namespace serialize while different namespaces run in parallel — see Writes are asynchronous.

Region

Storage is in ap-south-1 (Mumbai). Memories, their index and your account records are stored there, in S3 and DynamoDB, and nowhere else. There is no data-residency option and no multi-region failover. Where the models run is a separate question, answered below: the Claude calls may be processed in other AWS regions.

What touches your data

when model how it is called where it runs
writing a conversation: extraction, cues, relations Claude Haiku 4.5 (global.anthropic.claude-haiku-4-5-20251001-v1:0) Bedrock, through a global cross-region inference profile any AWS commercial region, not only ap-south-1
embedding cues on write, and the question on read Amazon Titan Text Embeddings v2 (amazon.titan-embed-text-v2:0, 1024-dim) Bedrock, in-region ap-south-1
mode=summary and mode=agentic Claude Haiku 4.5 or Sonnet 4.6 (global.anthropic.claude-sonnet-4-6): summary defaults to Haiku, agentic to Sonnet, and model picks global inference profile may be processed in other AWS regions
the dashboard playground and conversation summaries Claude Haiku 4.5 global inference profile may be processed in other AWS regions
rank=jev, and the experimental experimental=jev and experimental=jev_rank TypeSafe's Jev TypeSafe's API, api.typesafe.ai, outside AWS TypeSafe's infrastructure; opt-in per request only

A plain retrieval (the default: mode=raw, no rank=jev) calls no language model. The question is embedded with Titan in ap-south-1, and nothing goes to TypeSafe unless a request asks for one of the Jev paths.

The Claude calls go through Bedrock's Converse API and the Titan calls through InvokeModel, so a model change is a configuration change, not a rewrite of request handling. If your data must not be processed outside ap-south-1, the hosted service does not satisfy that today, because extraction runs through a global inference profile. The CLI runs the same engine on your own infrastructure, with the model provider you choose.

GITLOOM_EMBED_MODEL=off exists as a deployment option: with it, retrieval degrades to lexical and graph search only, and no embedding call is made. That is an operator-level switch, not a per-account setting today.

Isolation

A namespace is a distinct git repository under a distinct storage prefix — not a row behind a WHERE clause. Namespaces and multi-user patterns covers what this does and does not protect you from; the platform-level guarantee is that a bug in query construction cannot leak one namespace's content into another's response, because the two are never in the same searchable index to begin with. The warm-container cache follows the same rule: it is keyed by the exact account-and-namespace pair, so a shared Lambda execution environment cannot cross a namespace boundary either.

Authorization happens once, at the API Gateway edge, in a Lambda authorizer, before any handler runs — see Authentication for the credential model itself.

Measured reliability

Retrieval's server-side p99 is tracked against a 200 ms budget via CloudWatch, on the same metric Limits and behaviour quotes from — this section is about the platform doing the measuring, not a second set of numbers. A cold start (first request on a fresh container) has been observed at 167 ms of function duration against a single-digit-millisecond warm p50; a request is never served from a genuinely empty state, because freshness is checked by comparing a warm copy's commit against the namespace's recorded head on every read, not by a time-based cache expiry.

Ingest failures — extraction, embedding, or a transient AWS error — retry up to three times before landing in a dead-letter queue held for 14 days, which the operator treats as a correctness alarm, not a backlog to clear at leisure: a message reaching the DLQ is a memory that a user believes was stored and was not. See A partial failure that is not visible to you for the one failure mode that does not raise an alarm on its own.

Self-serve

Signup is open — there is no allowlist or manual provisioning step for an account using the API. What every new account gets, and what it costs to grow past it, is Plans and pricing.