Self-hosting
Run the open-source FishMem service and dashboard.
Self-hosting is the application platform path: run apps/web, own the database
and credentials, and expose the same /v1 API consumed by @fishmem/sdk.
Components
- the TanStack Start web application and REST API;
- the configured relational store for canonical memory and control-plane data;
- a keyword/vector projection backend;
- optional LLM and embedding providers;
- one durable task pickup path for memory inference, file extraction, and maintenance work;
- secrets for authentication and external providers.
An LLM is required for the default infer:true add path and for configured
profile/state synthesis. Applications that always submit already-distilled
infer:false records do not need an LLM for writes. A semantic embedder is
required for semantic recall.
infer:true never keeps an HTTP request open for the provider call. The API
commits an operation_tasks row, returns an Event API receipt, and a worker
claims it under a lease. Docker Compose includes the task-worker poller. On
Cloudflare, Queue delivery is the low-latency wakeup and the minute cron repairs
lost delivery; D1 remains the only status, retry, and result authority.
Deployment flow
- Clone the repository and install workspace dependencies with pnpm.
- Copy
apps/web/.env.exampleto your deployment's secret configuration. - Provision the database and any projection bindings referenced by the web configuration.
- Apply the migrations in
apps/web/migrations. - Set a distinct
FISHMEM_SETUP_TOKENdeployment secret. - Build and deploy
apps/webplus the task poller, or configure the Cloudflare Queue consumer and scheduled trigger. - Enter the setup token once to create the initial admin, then create an API key in the dashboard.
- Configure the SDK with your deployed origin:
const fishmem = new FishMem({
apiKey: process.env.FISHMEM_API_KEY!,
baseUrl: "https://memory.example.com",
});Verify both worker paths before serving traffic:
- submit an
infer:trueadd withIdempotency-Key; - confirm HTTP
202and retain itsevent_id; - poll
/v1/events/{event_id}throughPENDING/RUNNINGtoSUCCEEDED; - stop the immediate wakeup path once and confirm scheduled pickup repairs it;
- force a provider failure and confirm bounded retry, terminal error, and manual Dashboard retry.
The precise environment variables and platform bindings live in
apps/web/.env.example, apps/web/wrangler.jsonc, and the app README so they
remain versioned with the implementation.
Choose self-hosting when
- memory must remain in your account or region;
- you need network isolation or custom providers;
- you want to integrate the service with internal observability;
- your team accepts responsibility for migrations, backups, and upgrades.
Choose FishMem Cloud when you want the same application surface without operating it.
Workspace isolation
Every memory is tagged with your project id, every read is filtered by it, and the key never leaves the data layer — so your data can't bleed into another workspace.
Self-hosted dashboard
Run the FishMem control-plane — dashboard, API keys, operations, webhooks, REST API, and file extraction — with Docker or on Cloudflare.