# YAML Config

import { FileTree } from '@astrojs/starlight/components';
import SettingsDocs from '@lib/components/SettingsDocs.astro';

Runtime settings, including the location of files and directories, memory usage, and performance, are managed via the `invokeai.yaml` config file or environment variables. A subset of settings may be set via commandline arguments.

Settings sources are used in this order:

- CLI args
- Environment variables
- `invokeai.yaml` settings
- Fallback: defaults

### InvokeAI Root Directory

On startup, InvokeAI searches for its "root" directory. This is the directory that contains models, images, the database, and so on. It also contains a configuration file called `invokeai.yaml`.

<FileTree>

- models/

- outputs/

- databases/

- workflow_thumbnails/

- style_presets/

- nodes/

- configs/

- invokeai.example.yaml

- **invokeai.yaml**

</FileTree>

InvokeAI searches for the root directory in this order:

1. The `--root <path>` CLI arg.
2. The environment variable INVOKEAI_ROOT.
3. The directory containing the currently active virtual environment.
4. Fallback: a directory in the current user's home directory named `invokeai`.

### InvokeAI Configuration File

Inside the root directory, we read settings from the `invokeai.yaml` file.

It has two sections - one for internal use and one for user settings:

```yaml
# Internal metadata - do not edit:
schema_version: 4.0.2

# Put user settings here - see https://invoke.ai/configuration/invokeai-yaml/:
host: 0.0.0.0 # serve the app on your local network
models_dir: D:\invokeai\models # store models on an external drive
precision: float16 # always use fp16 precision
```

The settings in this file will override the defaults. You only need
to change this file if the default for a particular setting doesn't
work for you.

You'll find an example file next to `invokeai.yaml` that shows the default values.

Some settings, like [Model Marketplace API Keys], require the YAML
to be formatted correctly. Here is a [basic guide to YAML files].

#### Custom Config File Location

You can use any config file with the `--config` CLI arg. Pass in the path to the `invokeai.yaml` file you want to use.

Note that environment variables will trump any settings in the config file.

#### Donation Links

The **Help & resources** and app menus show a heart icon labeled **Donate to InvokeAI**, which opens [GitHub Sponsors](https://github.com/sponsors/invoke-ai) in a new tab. Hosted deployments can hide both entries by adding this setting to `invokeai.yaml`:

```yaml
show_donation_link: false
```

The default is `true`. Restart InvokeAI and reload the browser after changing this setting. It can also be set with the `INVOKEAI_SHOW_DONATION_LINK` environment variable.

#### Model Marketplace API Keys

Some model marketplaces require an API key to download models. You can provide a URL pattern and appropriate token in your `invokeai.yaml` file to provide that API key.

The pattern can be any valid regex (you may need to surround the pattern with quotes):

```yaml
remote_api_tokens:
  # Any URL containing `models.com` will automatically use `your_models_com_token`
  - url_regex: models.com
    token: your_models_com_token
  # Any URL matching this contrived regex will use `some_other_token`
  - url_regex: '^[a-z]{3}whatever.*\.com$'
    token: some_other_token
```

The provided token will be added as a `Bearer` token to the network requests to download the model files. As far as we know, this works for all model marketplaces that require authorization.

:::tip[Hugging face Models]
If you get an error when installing a HF model using a URL instead of repo id, you may need to [set up a HF API token](https://huggingface.co/settings/tokens) and add an entry for it under `remote_api_tokens`. Use `huggingface.co` for `url_regex`.
:::

#### Model Hashing

Models are hashed during installation, providing a stable identifier for models across all platforms. Hashing is a one-time operation.

```yaml
hashing_algorithm: blake3_single # default value
```

You might want to change this setting, depending on your system:

- `blake3_single` (default): Single-threaded - best for spinning HDDs, still OK for SSDs
- `blake3_multi`: Parallelized, memory-mapped implementation - best for SSDs, terrible for spinning disks
- `random`: Skip hashing entirely - fastest but of course no hash

During the first startup after upgrading to v4, all of your models will be hashed. This can take a few minutes.

Most common algorithms are supported, like `md5`, `sha256`, and `sha512`. These are typically much, much slower than either of the BLAKE3 variants.

#### Path Settings

These options set the paths of various directories and files used by InvokeAI. Any user-defined paths should be absolute paths.

#### Multi-GPU Generation

On a machine with more than one GPU, InvokeAI can run several generation sessions at the same time — one per GPU — instead of processing the queue one job at a time. In multi-user deployments with the default `session_queue_mode: round_robin`, jobs are distributed fairly across users, so a single user's large batch cannot monopolize every GPU while others wait.

This is controlled by the `generation_devices` setting:

```yaml
generation_devices: auto # default value
```

| Value             | Behavior                                                                                                                                                                                                                          |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `auto`            | Use every available CUDA GPU, running one generation session per GPU concurrently. This is the default. Exception: if the legacy `device` setting is pinned to a specific device, `auto` uses only that device (see Notes below). |
| `[cuda:0,cuda:1]` | Use the specific devices listed, one session per device. Useful for reserving a GPU for other work.                                                                                                                               |
| `[cuda:0]`        | Use a single specific device. Generation runs serially, as it did before multi-GPU support.                                                                                                                                       |

Each entry in the list must be one of `cpu`, `cuda`, `mps`, or `cuda:N`, where `N` is a zero-based device number (`cuda:0` is the first GPU, `cuda:1` the second, and so on). The list may not be empty — use `auto` (or a single-device list) instead.

```yaml
# Use the first and third GPUs, leaving the second free for other tasks
generation_devices: [cuda:0, cuda:2]
```

Notes:

- If the legacy `device` setting is pinned to a specific device (e.g. `device: cuda:1`), `auto` resolves to that single device rather than every GPU. This preserves the behavior of installs that pinned `device` before multi-GPU support existed (for example, to keep generation off a display GPU). An explicit `generation_devices` list overrides `device`.
- On a system without a CUDA GPU, `auto` resolves to the single best available device (`mps` on Apple Silicon, otherwise `cpu`), so generation runs serially.
- Each active GPU gets its own model cache, but the CPU (system RAM) copy of each model's weights is shared between the caches, so a model loaded on several GPUs is held in RAM only once. Running many GPUs in parallel can still increase RAM usage (different GPUs may hold different models), so ensure you have ample system memory before enabling a large device list.
- When a GPU finishes a job, it prefers queued jobs whose models it already has loaded (among the same user's equal-priority jobs) to avoid slow model reloads. Set `session_queue_mode: FIFO` to disable this reordering and enforce strict submission order.
- Duplicate entries are ignored; `[cuda:0, cuda:0]` is treated as `[cuda:0]`.
- You can restrict which physical GPUs InvokeAI sees with the `CUDA_VISIBLE_DEVICES` environment variable. When set, `auto` only enumerates the visible subset, and `cuda:N` indices refer to positions within that subset.

During parallel generation, the progress display shows one progress bar per active session, stacked vertically, each disappearing as its session completes.

#### Text Encoder Offload to Idle GPUs

When more than one GPU is configured for generation but not all of them are busy, InvokeAI can run a session's text/prompt encoder on a currently-idle GPU instead of the GPU running its denoise pipeline. This avoids evicting the denoise model from VRAM just to make room for the encoder, and lets the cached encoder be reused across generations — making repeated generations noticeably smoother.

This is controlled by the `offload_text_encoders_to_idle_gpus` setting:

```yaml
offload_text_encoders_to_idle_gpus: true # default value
```

| Value   | Behavior                                                                                                         |
| ------- | ---------------------------------------------------------------------------------------------------------------- |
| `true`  | Run text encoders on an idle GPU when one is available. This is the default.                                     |
| `false` | Always run text encoders on the same GPU as the rest of the pipeline (the behavior before this feature existed). |

Notes:

- This has no effect unless at least two `generation_devices` are configured. On a single device — or when every GPU is already busy with its own session — encoders run on the session's own GPU, exactly as if the setting were `false`.
- It is purely a placement optimization and does not change generated images.
- A borrowed GPU is used exclusively for the encoder while it runs, so it never interferes with a generation session running on that same GPU.

#### Prompt Tools and Image Indexing on Multiple GPUs

**Expand Prompt**, **Image to Prompt** and image embedding for the image map and search by image run outside the generation queue. With two or more GPUs configured, each such request takes an idle GPU for as long as it runs — the first idle one in `generation_devices` order — so it no longer competes for memory with a generation running on another GPU. While a GPU is lent this way, queued generations start on the other GPUs rather than waiting for it, and these requests never take every GPU at once, so the queue always has one to start on. When no GPU can be taken, the request runs on the default device as it did before. There is no setting for this, and a single-GPU install behaves as it always has.

Background indexing of new images already waits until no generation is running, so it simply takes the first idle GPU; it is search by image that benefits during a generation.

#### Attention Kernel

`attention_backend` decides how attention runs. The default, `auto`, uses PyTorch's exact attention kernels ranked flash, cuDNN, memory-efficient, math: each call takes the first one the GPU and the PyTorch build support for it. `sage` uses [SageAttention](/configuration/optimization/sage-attention/) for the models listed there.

For measurements and support questions you can rank one of PyTorch's kernels first instead, for the attention of every model on CUDA and ROCm GPUs. It takes effect after restarting InvokeAI:

```yaml
attention_backend: cudnn
```

| Value       | Kernel ranked first                                                                                                                   |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `cudnn`     | cuDNN attention. ROCm builds of PyTorch do not have it.                                                                               |
| `flash`     | Flash attention. PyTorch's Windows builds do not have it.                                                                             |
| `efficient` | Memory-efficient attention.                                                                                                           |
| `math`      | PyTorch's unfused fallback. It builds the full attention score matrix, so it is much slower and needs far more memory. For debugging. |

The working-memory estimates of most model families do not include the score matrix `math` builds, so with `math` generations can run out of memory; startup logs a warning saying so.

A pinned kernel is never exclusive. A call it cannot serve — the build or GPU has no such kernel, or the call's precision, head size, mask or grouped-query heads rule it out — runs on the next kernel of the default order, and the log says so once per node type and reason:

```
attention_backend 'flash' is not possible for attention in flux_denoise: this PyTorch build or GPU (cuda:0) has no flash kernel; it runs on CUDNN_ATTENTION.
```

The PiD decoder's attention is ranked the same way, but not reported. Images can differ slightly between kernels at the same seed. On the CPU and on Apple Silicon, PyTorch picks its kernels itself and the ranking does not apply.

#### Image Subfolder Strategy

By default, generated images are stored in a single flat directory under `outputs/images/`. The `image_subfolder_strategy` setting lets you organize newly-created images into subfolders automatically. You can edit this setting in `invokeai.yaml` or, as an admin user, under **Settings → Server → Image storage**.

```yaml
image_subfolder_strategy: flat # default value
```

Available strategies:

| Strategy | Example Path                           | Description                                                                                       |
| -------- | -------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `flat`   | `outputs/images/abc123.png`            | Store images directly in the images directory.                                                    |
| `date`   | `outputs/images/2026/03/17/abc123.png` | Organize images by creation date.                                                                 |
| `type`   | `outputs/images/general/abc123.png`    | Organize images by image category.                                                                |
| `hash`   | `outputs/images/ab/abc123.png`         | Use the first two characters of the image UUID for filesystem performance with large collections. |

Changing this setting only affects newly-created images. Existing images remain in their current locations unless you run [Image Storage Maintenance](/users-guide/gallery/image-storage-maintenance/).

#### Response Compression

API responses (JSON, HTML, JS, CSS, SVG) are gzipped before being sent. Already-compressed responses — PNG, WebP, JPEG, MP4 — are passed through untouched, since compressing them costs CPU and returns a body no smaller than the original.

Compression runs on the server's event loop, which means it blocks _everything else_ for its duration: no other request is served and no progress event is delivered while it runs. The `http_compression_level` setting controls that trade-off:

```yaml
http_compression_level: 9 # default value
```

| Value   | Behavior                                                                                  |
| ------- | ----------------------------------------------------------------------------------------- |
| `0`     | No compression. Responses are sent as-is and the compression middleware is not installed. |
| `1`     | Fastest compression, slightly larger output.                                              |
| `2`–`8` | Progressively slower, marginally smaller.                                                 |
| `9`     | Smallest output, by far the slowest. This is the default.                                 |

The setting can also be given as the `INVOKEAI_HTTP_COMPRESSION_LEVEL` environment variable.

If the UI feels sluggish while a large library is being browsed, lowering this is one of the cheapest wins available. Measured on the image-name list of a 200,000-image library (8.48 MB of JSON):

| Level |    Time |        Output |
| ----- | ------: | ------------: |
| `1`   | 16.4 ms | 6.1% of input |
| `6`   | 36.1 ms | 5.9% of input |
| `9`   | 90.2 ms | 5.7% of input |

Level 9 spends 5.5× the event-loop time to save 0.4 percentage points of bandwidth. On a locally-served install the bandwidth is free and the stall is not, so `http_compression_level: 1` is usually the better setting there — the default stays at `9` only so that upgrading does not silently change how anyone's install behaves.

:::tip[Behind a reverse proxy]
If you serve InvokeAI through nginx, Caddy, or similar, set `http_compression_level: 0` and let the proxy compress instead. The proxy does that work in its own process rather than on InvokeAI's event loop, and it avoids compressing the same bytes twice.
:::

#### Database Durability

This section concerns the default SQLite database. A [MySQL or MariaDB database](/configuration/external-database/), set with `db_url`, has its durability set on the server.

Every write to InvokeAI's SQLite database is committed to disk before the request returns. How hard that commit is pushed to the physical disk is controlled by `db_synchronous`:

```yaml
db_synchronous: full # default value
```

| Value    | Behavior                                                                                                                           |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `full`   | Every commit is flushed to disk before it is acknowledged. What InvokeAI has always used, and SQLite's default on standard builds. |
| `normal` | Commits are acknowledged without waiting for the flush. Much faster; a power loss may lose the last few.                           |

The setting can also be given as the `INVOKEAI_DB_SYNCHRONOUS` environment variable.

**`normal` cannot corrupt the database, as long as WAL is in effect.** InvokeAI runs SQLite in WAL mode, and WAL guarantees a consistent database either way. What `normal` gives up is the _most recent transactions_ if the machine loses power or the OS crashes mid-write — a just-written image record or a queue status. The image file itself survives on disk, but nothing rebuilds the row, and the gallery is driven by the database: the image is simply gone from it. An administrator can use **Settings > Data & workspace > Gallery maintenance** to review and remove database records whose image files are missing, or archive untracked image files for later review. Maintenance does not import archived files; use the separate `invokeai/frontend/install/import_images.py` script to import images.

Running the database on a network share is not a supported configuration -- SQLite's locking is unreliable over NFS and SMB, and this is worth avoiding for reasons well beyond durability. Keep `db_dir` on local storage.

The safeguard exists anyway, because WAL needs shared memory and a few setups cannot provide it: a database on a network share, some container volume drivers, and SQLite builds compiled without WAL all leave a rollback journal in place instead — and on a rollback journal, `normal` _can_ corrupt the database on power loss. InvokeAI reads back the journal mode it actually got, so in that case it ignores `normal`, uses `full`, and logs a warning naming the mode. An in-memory database (`use_memory_db`) has no durability to trade and is unaffected.

`db_synchronous` applies to the application's own database connection, which gallery maintenance (an administrator action in Settings) uses too, and to the image import script, `invokeai/frontend/install/import_images.py`, which reads the same `invokeai.yaml`. The measurements below describe the running app.

Measured on a copy of a real library, 300 single-row inserts each committed on its own:

| Setting  | Median commit | p95 commit |
| -------- | ------------: | ---------: |
| `full`   |      0.427 ms |   0.811 ms |
| `normal` |      0.035 ms |   0.121 ms |

That is 12x shorter at the median. It matters more than the raw numbers suggest, because all database work is serialised through a single lock: a shorter write is also a shorter time during which every read is blocked.

The default stays at `full`, which is what InvokeAI has always run with, so upgrading does not weaken anyone's durability. It is now applied explicitly, which does tighten it on the uncommon SQLite build compiled with `SQLITE_DEFAULT_WAL_SYNCHRONOUS=1`, where WAL connections previously started at `normal`. If you generate in large batches on a machine with reliable power, `normal` is the cheaper setting.

#### Logging

Several different log handler destinations are available, and multiple destinations are supported by providing a list:

```yaml
log_handlers:
  - console
  - syslog=localhost
  - file=/var/log/invokeai.log
```

- `console` is the default. It prints log messages to the command-line window from which InvokeAI was launched.

- `syslog` is only available on Linux and Macintosh systems. It uses
  the operating system's "syslog" facility to write log file entries
  locally or to a remote logging machine. `syslog` offers a variety
  of configuration options:

```yaml
syslog=/dev/log`      - log to the /dev/log device
syslog=localhost`     - log to the network logger running on the local machine
syslog=localhost:512` - same as above, but using a non-standard port
syslog=fredserver,facility=LOG_USER,socktype=SOCK_DRAM`
- Log to LAN-connected server "fredserver" using the facility LOG_USER and datagram packets.
```

- `http` can be used to log to a remote web server. The server must be
  properly configured to receive and act on log messages. The option
  accepts the URL to the web server, and a `method` argument
  indicating whether the message should be submitted using the GET or
  POST method.

```yaml
http=http://my.server/path/to/logger,method=POST
```

The `log_format` option provides several alternative formats:

- `color` - default format providing time, date and a message, using text colors to distinguish different log severities
- `plain` - same as above, but monochrome text only
- `syslog` - the log level and error message only, allowing the syslog system to attach the time and date
- `legacy` - a format similar to the one used by the legacy 2.3 InvokeAI releases.

### Environment Variables

All settings may be set via environment variables by prefixing `INVOKEAI_`
to the variable name. For example, `INVOKEAI_HOST` would set the `host`
setting.

For non-primitive values, pass a JSON-encoded string:

```sh
export INVOKEAI_REMOTE_API_TOKENS='[{"url_regex":"modelmarketplace", "token": "12345"}]'
```

We suggest using `invokeai.yaml`, as it is more user-friendly.

### CLI Args

A subset of settings may be specified using CLI args:

- `--root`: specify the root directory
- `--config`: override the default `invokeai.yaml` file location

### Low-VRAM Mode

See the [Low-VRAM mode docs][low-vram] for details on enabling this feature.

### All Settings

The full settings reference is below. Additional explanations for selected settings appear earlier on this page.

<SettingsDocs />

[basic guide to yaml files]: https://circleci.com/blog/what-is-yaml-a-beginner-s-guide/
[Model Marketplace API Keys]: #model-marketplace-api-keys
[low-vram]: /configuration/optimization/low-vram-mode/