# Memos — Full content > Memos is an open-source, self-hosted note-taking app for your everyday thoughts. It’s a place to write what’s on your mind as you go about your day. A single sentence can be a whole memo, or you can take your time with a longer entry, using Markdown to give your words more structure. These moments of writing gradually become a personal record. Each memo stays with the day you wrote it, bringing your thoughts together in a timeline you can look back through. Tags connect related thoughts across those days, making it easy to pick up a topic again or find something you remember writing. That record lives on your own server, and your data stays yours. You choose what stays private, what to share with family and friends, and what to publish on the web. In shared spaces, you can write alongside others while each person keeps their own memos. # Documentation URL: https://usememos.com/docs Memos is an open-source, self-hosted note-taking app for your everyday thoughts. It’s a place to write what’s on your mind as you go about your day. A single sentence can be a whole memo, or you can take your time with a longer entry, using Markdown to give your words more structure. These moments of writing gradually become a personal record. Each memo stays with the day you wrote it, bringing your thoughts together in a timeline you can look back through. Tags connect related thoughts across those days, making it easy to pick up a topic again or find something you remember writing. That record lives on your own server, and your data stays yours. You choose what stays private, what to share with family and friends, and what to publish on the web. In shared spaces, you can write alongside others while each person keeps their own memos. Start with Getting Started, then move into deployment, configuration, and daily use. The usage and configuration guides cover **0.31.0**, the latest stable release. Read the [release changelog](/changelog/0-31-0) and [0.31 upgrade notes](/docs/operations/upgrade#upgrading-to-031) before upgrading. The API reference provides separate version selections. ## Popular Paths [#popular-paths] Start a local instance with one Docker command and write your first memo. Run Memos in a single container with a persistent data directory. Use a checked-in Compose file for repeatable self-hosted deployments. Put Memos behind your public domain with TLS and proxy headers. Lock down authentication, public access, and deployment defaults. Protect your memos with a clear recovery path before you need it. Explore the REST and gRPC APIs for automation and integrations. Connect Memos to the rest of your stack with event-driven automation. ## Browse All Docs [#browse-all-docs] Start an instance with Docker and write your first memo. Run Memos with Docker, Compose, source builds, or Kubernetes. Configure runtime flags, database, storage, authentication, and security. Instance settings and user management. Write memos in Markdown, then find them again with search, tags, and Views. Explore Bullet Journal, GTD, and Zettelkasten in Memos. API access, MCP, webhooks, and community tools. Plan backups, upgrade safely, and tune production performance. Common issues and fixes. Quick answers about licensing, data, and limits. REST and gRPC API reference. Set up a local environment, build Memos, test changes, and contribute. --- # Admin URL: https://usememos.com/docs/admin Instance administration shapes how people join and use your Memos instance. Start here to manage shared settings and accounts, and to understand how instance roles relate to Space membership and memo ownership. Manage access and registration policies, storage, notifications, and memo behavior across the instance. Understand instance and Space roles, manage accounts, and resolve memberships before removing a user. ## Choose the question you need to answer [#choose-the-question-you-need-to-answer] | If you want to know… | Start with… | | ---------------------------------------------------- | -------------------------------------------------------------------- | | How do I control registration and public access? | [Instance Settings](/docs/admin/instance-settings) | | Where do I configure uploads, email, or memo limits? | [Instance Settings](/docs/admin/instance-settings) | | What can an instance admin or a Space admin do? | [Users & Roles](/docs/admin/users-roles) | | What must I check before removing an account? | [Users & Roles](/docs/admin/users-roles#removing-access-or-accounts) | Active instance administrators can read and manage individual memos, including private and Space-only content. Collection listings still filter by audience, and administrators do not automatically become Space members. Review roles and membership together when deciding who needs access. For server configuration and sign-in setup, continue to [Configuration](/docs/configuration). For creating and using a shared workspace, see [Spaces](/docs/usage/spaces). --- # Instance Settings URL: https://usememos.com/docs/admin/instance-settings Instance settings control authentication, storage, and memo policies. Admins can update these settings in the app or via the Instance Settings API. Common areas include: * Instance access policy: public or private access, stored independently of the canonical instance URL. * General access controls: user registration, password auth, username and nickname changes, week start day, and custom instance profile. * Storage settings: named database, local filesystem, or S3-compatible configurations with stable IDs, a default for new uploads, file path templates, and upload limits. * Memo-related settings: content length limits, double-click editing, and allowed reaction values. * Notification settings: SMTP email delivery, sender details, reply-to address, and the email test endpoint. * AI settings: instance-level OpenAI or Gemini providers and speech-to-text transcription defaults. Tag colors and content-blur rules are user settings in Memos 0.30 and later, not instance settings. See [Tags](/docs/usage/tags). ## Access policy [#access-policy] In 0.31, the `ACCESS` setting determines whether anonymous visitors may read public content. `MEMOS_INSTANCE_URL` supplies the canonical external address and no longer changes an existing access policy. Use [deployment-managed access configuration](/docs/configuration/deployment-configuration#access-policy) when infrastructure should own this setting. Active instance admins manage these policies and can read and manage individual memos, including other authors' private and Space-only memos. They do not automatically become Space members, and collection listings still filter by audience. See [Users & Roles](/docs/admin/users-roles). ## Sensitive settings [#sensitive-settings] Storage, notification, and AI settings can contain credentials. API responses do not return stored S3 secrets, SMTP passwords, or AI provider API keys in plaintext. When updating those settings, submit a new secret only when you intend to replace it. ## Related API [#related-api] * [Get Instance Setting](/docs/api/latest/instanceservice/GetInstanceSetting) * [Batch Get Instance Settings](/docs/api/latest/instanceservice/BatchGetInstanceSettings) * [Update Instance Setting](/docs/api/latest/instanceservice/UpdateInstanceSetting) * [Test Instance Email Setting](/docs/api/latest/instanceservice/TestInstanceEmailSetting) --- # Users & Roles URL: https://usememos.com/docs/admin/users-roles Memos has two instance roles: **Admin** and **User**. The first account created during setup becomes an instance admin. Instance admins manage accounts, instance configuration, and access policy. ## Instance roles and Space roles [#instance-roles-and-space-roles] Each [Space](/docs/usage/spaces) has its own accepted **Admin** and **User** memberships. Instance roles and Space roles are independent: an instance User can create and administer a Space, while an instance Admin has no automatic membership in another user's Space. Space admins manage the Space's metadata, invitations, and members. A Space admin role does not grant editing rights to another author's memos. Active instance administrators can read and manage individual memos, including private and Space-only memos, without being the author or a Space member. Collection listings still filter by audience; instance administrators do not automatically join Spaces. ## Usernames [#usernames] Sign-in and username lookup are case-sensitive: `Alice` and `alice` are different spellings. New and renamed usernames must contain 1–36 ASCII letters or digits, with hyphens allowed only inside the name. Underscores, email addresses, and non-ASCII usernames cannot be newly assigned. Legacy usernames remain addressable with their exact spelling. Spellings outside the new grammar cannot be written as new mentions. See [Authentication](/docs/configuration/authentication) and [Mentions](/docs/usage/reactions-comments#mentions). ## Removing access or accounts [#removing-access-or-accounts] Removing a Space member leaves their contributions in that Space. A Space must always retain an active admin, so assign another admin before removing or archiving the last one. Deleting an account is blocked while it has active Space memberships, including when the API request sets `force`. Resolve those memberships first. Deleting a Space instead permanently deletes all directly assigned memos; it is not an equivalent way to remove one user's access. --- # Configuration URL: https://usememos.com/docs/configuration Configure Memos around how your instance runs, where its data lives, and how people sign in. These pages explain startup options, deployment-managed settings, database and attachment storage, and access controls. Set the listen address, port, data directory, database connection, and canonical instance URL. Load selected instance settings and identity providers from mounted JSON files at startup. Configure SQLite, MySQL, or PostgreSQL and understand the operational tradeoffs. Choose where attachments live and manage named storage configurations for new and existing files. Configure password sign-in, SSO providers, and personal access tokens. Review HTTPS, credentials, sharing, and recovery as part of operating your instance. ## Choose the question you need to answer [#choose-the-question-you-need-to-answer] | If you want to know… | Start with… | | ------------------------------------------------------------------ | -------------------------------------------------------------------------------- | | How do I change the port, data path, or external URL? | [Environment Variables](/docs/configuration/environment-variables) | | How do I keep settings under deployment or secret-manager control? | [Deployment-Managed Configuration](/docs/configuration/deployment-configuration) | | Which database fits my deployment? | [Database](/docs/configuration/database) | | Where should uploads be stored? | [Storage](/docs/configuration/storage) | | How do I set up SSO or authenticate an integration? | [Authentication](/docs/configuration/authentication) | | What should I review before exposing the instance? | [Security](/docs/configuration/security) | ## Configuration layers [#configuration-layers] Runtime flags and `MEMOS_*` environment variables control server startup. Instance settings manage policies and services through the UI or API. When a supported setting is supplied by a deployment-managed file, that file is authoritative for the server process; changes to it require a restart. In Memos 0.31, the `ACCESS` instance setting selects public or private access independently of `MEMOS_INSTANCE_URL`. Set the URL to the canonical external HTTP(S) address, including for private instances behind a proxy. Manage access in instance settings or a [deployment-managed access file](/docs/configuration/deployment-configuration#access-policy). For the installation itself, start with [Deploy](/docs/deploy). Once Memos is running, use [Admin](/docs/admin) for ongoing instance and account management, and [Reverse Proxy](/docs/deploy/reverse-proxy) for HTTPS and forwarded headers. --- # Authentication URL: https://usememos.com/docs/configuration/authentication Memos supports three primary authentication mechanisms: * password-based sign-in * OAuth2 or SSO identity providers * personal access tokens for API use Use password sign-in for simple private instances. Use SSO when your team already has a central identity provider and you want Memos sign-in to follow that identity system. Use personal access tokens for scripts and integrations. ## Session model [#session-model] | Token type | Lifetime | Storage | Notes | | --------------------------- | --------------------------------------- | ------------------ | -------------------------------------- | | Access token (JWT) | 15 min | Client memory | Stateless; verified without a DB query | | Refresh token (JWT) | 30 days | HTTP-only cookie | Database-backed, revocable | | Personal access token (PAT) | User-selected; no expiration by default | SHA-256 hash in DB | Format: `memos_pat_<32 random chars>` | The plain PAT is shown only once at creation time. Only its SHA-256 hash is stored in the database. For automation or external tools, use personal access tokens instead of browser-style cookie flows. ## Password authentication [#password-authentication] Password authentication is enabled by default. It is simple and works well for single-user or small private instances. Password auth is usually the right starting point when: * the instance is personal or very small * you do not already have a central identity provider * you want minimal setup complexity Users sign in with their Memos username and password. Archived users cannot sign in. Failed sign-in attempts use the same error message for unknown usernames and wrong passwords, so the login page does not reveal whether a username exists. ### Username spelling [#username-spelling] In 0.31, sign-in and lookup use exact-case usernames. `Alice` and `alice` are distinct spellings. New or renamed usernames must contain 1–36 ASCII letters or digits, with hyphens only inside the name. Existing legacy names remain addressable, but unsupported spellings cannot be used for new mentions. When diagnosing a failed sign-in after upgrading, check the stored username and its case before resetting credentials. ### Disable password authentication [#disable-password-authentication] Admins can disable password sign-in for regular users after SSO is configured. When password auth is disabled: * regular users must sign in with SSO * password-based registration is unavailable * admins can still use password sign-in through the admin sign-in path * the regular sign-in page hides the password form Keep at least one admin account with a known password. This gives you a recovery path if an SSO provider is misconfigured or temporarily unavailable. ## OAuth2 and SSO [#oauth2-and-sso] SSO is the right choice for team instances that already use a central identity system. Configure the provider in instance settings, then test login with a non-admin account before forcing the whole instance onto SSO-only behavior. The OAuth2 callback URL for your Memos instance is: ```text https:///auth/callback ``` Register that exact URL in the OAuth2 application for your identity provider. ### How SSO users are matched [#how-sso-users-are-matched] Memos stores local users separately from external SSO accounts. When a user signs in through SSO, Memos reads the configured identifier field from the provider's user info response and looks for an existing linked identity. If a matching linked identity already exists, Memos signs in to the same local user. If no match exists and registration is allowed, Memos creates a regular local user and links that external account. If user registration is disabled, first-time SSO sign-in is rejected until an account is created or linked by another flow. For a new SSO user, Memos first tries to use the mapped external identifier as the local username when it satisfies the username rules and is not reserved. If that value is invalid or already belongs to another account, Memos generates a UUID-based username instead. It never links an SSO identity to an existing account merely because the usernames match. ### OAuth2 provider fields [#oauth2-provider-fields] Each identity provider requires: * `clientId` and `clientSecret` from the OAuth2 application * `authUrl`, `tokenUrl`, and `userInfoUrl` for the provider's OAuth2 endpoints * `scopes` the token should request * `fieldMapping` to map the provider's user info fields to Memos fields (`identifier`, `displayName`, `email`, `avatarUrl`) * optional `identifierFilter`, a regex applied to the identifier value; users that do not match are denied The `identifier` mapping is the most important setting. It becomes the external identity key that Memos uses for future sign-ins. Choose a stable provider field such as a subject ID, username, or email address depending on how your provider guarantees identity stability. Changing the provider UID or the `fieldMapping.identifier` value after users have signed in can prevent Memos from finding existing linked identities. Treat those settings as stable once SSO is in use. Use `identifierFilter` to restrict who can sign in. For example, a filter can allow only users from a specific email domain. Test the regex carefully; a bad filter can block every SSO user. Memos only reads string fields from the user info response. If your provider returns nested objects or non-string values for a field, adjust the provider configuration or expose a flat string claim. ### GitHub [#github] ```json { "title": "GitHub", "type": "OAUTH2", "config": { "oauth2Config": { "clientId": "", "clientSecret": "", "authUrl": "https://github.com/login/oauth/authorize", "tokenUrl": "https://github.com/login/oauth/access_token", "userInfoUrl": "https://api.github.com/user", "scopes": ["read:user", "user:email"], "fieldMapping": { "identifier": "login", "displayName": "name", "email": "email", "avatarUrl": "avatar_url" } } } } ``` GitHub's `email` field can be empty depending on the user's profile privacy and granted scopes. If you need a guaranteed identifier, use `login` or another stable field from your identity policy. ### Google [#google] ```json { "title": "Google", "type": "OAUTH2", "config": { "oauth2Config": { "clientId": "", "clientSecret": "", "authUrl": "https://accounts.google.com/o/oauth2/v2/auth", "tokenUrl": "https://oauth2.googleapis.com/token", "userInfoUrl": "https://www.googleapis.com/oauth2/v2/userinfo", "scopes": ["openid", "profile", "email"], "fieldMapping": { "identifier": "email", "displayName": "name", "email": "email", "avatarUrl": "picture" } } } } ``` Google `email` works well for many private deployments, especially when combined with an `identifierFilter` that limits access to your domain. If your organization can rename or recycle email addresses, prefer a stable subject field if your provider exposes one through user info. ### Safe SSO rollout [#safe-sso-rollout] 1. Create the OAuth2 application with `https:///auth/callback` as the callback URL. 2. Add the identity provider in Memos and save the client ID, client secret, endpoints, scopes, and field mappings. 3. Test SSO sign-in with a non-admin account. 4. Confirm first-time SSO behavior matches your registration policy. 5. Keep admin password access available as a recovery path. 6. Disable password authentication for regular users only after SSO is working. ## Linked identities [#linked-identities] Users can link an external SSO account to their existing Memos account from account settings. After a provider is linked, signing in with that SSO account opens the same Memos user. Each Memos user can link at most one external account per identity provider. The same external account cannot be linked to multiple Memos users. Unlinking removes only the relationship between the Memos user and the external account. It does not delete the Memos user, the identity provider configuration, or the external account. Before unlinking, make sure the user still has another usable sign-in method. See [Linked Identities](/docs/usage/linked-identities) for the end-user workflow. ## Personal access tokens [#personal-access-tokens] PATs are intended for scripts, integrations, and external tools. Use PATs when: * calling the API from automation * integrating with external services * avoiding interactive browser login flows Operational guidance: * create a separate token for each application or integration * choose an expiration when the integration does not need a permanent credential; new tokens default to no expiration * review the last-used timestamp to find abandoned credentials * rotate tokens periodically * delete tokens that are no longer needed * do not embed PATs into public clients or front-end code ## API references [#api-references] * [Auth Service: SignIn](/docs/api/latest/authservice/SignIn) * [Identity Provider Service: CreateIdentityProvider](/docs/api/latest/identityproviderservice/CreateIdentityProvider) --- # Database URL: https://usememos.com/docs/configuration/database Memos supports three database backends: * `sqlite` for the default single-instance setup * `mysql` for managed or larger deployments * `postgres` for managed or larger deployments ## SQLite [#sqlite] SQLite is the default and the best fit for most personal deployments or small teams running a single node. Useful defaults in Memos include WAL mode and a busy timeout, which help reduce common lock contention problems. Typical SQLite setup: ```bash MEMOS_DRIVER=sqlite MEMOS_DATA=/var/opt/memos memos ``` If you need an explicit file path: ```bash MEMOS_DRIVER=sqlite MEMOS_DSN=/opt/memos/memos.db memos ``` SQLite is usually enough when: * one instance handles all writes * your dataset is modest * operational simplicity matters more than cluster-style scaling ## MySQL and PostgreSQL [#mysql-and-postgresql] Use MySQL or PostgreSQL when: * you want managed backups and tooling * you already operate a database server * you expect larger datasets or more operational controls * you do not want the application host to carry the database file locally Examples: ```bash MEMOS_DRIVER=mysql \ MEMOS_DSN="memos_user:password@tcp(db:3306)/memos?charset=utf8mb4&parseTime=True&loc=Local" \ memos ``` ```bash MEMOS_DRIVER=postgres \ MEMOS_DSN="postgres://memos_user:password@db:5432/memos?sslmode=disable" \ memos ``` ## Selection guidance [#selection-guidance] * choose SQLite for one-node simplicity * choose MySQL or PostgreSQL for operational flexibility * keep backups aligned with your database choice * if you store attachments outside the database, back those up separately ## Performance implications [#performance-implications] Database choice changes where bottlenecks show up: * SQLite tends to surface write contention first * MySQL and PostgreSQL push complexity into networked DB operations and tuning * attachment storage can dominate recovery and backup time even when the DB is healthy --- # Deployment-Managed Configuration URL: https://usememos.com/docs/configuration/deployment-configuration Memos 0.30 and later can load selected configuration from JSON files mounted under `/etc/secrets`. Use this when settings such as SSO, storage credentials, or registration policy should be controlled by Docker Compose, Kubernetes, GitOps, or a secret manager instead of the admin UI. File-backed configuration is loaded once at startup and remains authoritative for that server process. Settings not supplied by files continue to use the database and can be managed normally in Memos. ## Quick start with Docker Compose [#quick-start-with-docker-compose] Create a directory for the configuration files: ```text . ├── compose.yaml └── memos-secrets/ └── memos-instance-setting-general.json ``` Add `memos-secrets/memos-instance-setting-general.json`: ```json { "key": "GENERAL", "generalSetting": { "disallowUserRegistration": false, "disallowPasswordAuth": false, "additionalScript": "", "additionalStyle": "", "weekStartDayOffset": 1, "disallowChangeUsername": false, "disallowChangeNickname": false, "customProfile": { "title": "Team Memos", "description": "Notes for our team", "logoUrl": "https://example.com/logo.png" } } } ``` Mount the directory read-only at `/etc/secrets`: ```yaml services: memos: image: neosmemo/memos:stable ports: - "5230:5230" volumes: - ./memos-data:/var/opt/memos - ./memos-secrets:/etc/secrets:ro ``` Make sure the files are readable by the Memos container user, then recreate the container: ```bash docker compose up -d --force-recreate docker compose logs memos ``` The startup log reports how many identity providers and instance settings were loaded. It does not print configuration values or secrets. ## Supported files [#supported-files] Memos scans direct children of `/etc/secrets` and reads only these filename patterns: | Resource | Filename | Stable key | | ------------------------ | ------------------------------------------ | -------------- | | OAuth2 identity provider | `memos-idp-