---
title: "Change the speech model cache directory in C#"
url: https://recursiveai.org/onespeech/cookbook/configure-speech-model-cache/
description: "Choose where OneSpeech stores downloaded models and the files it converts for inference."
version: "1.1.0"
---

# Change the speech model cache directory in C#

**OneSpeech** is a free, open-source speech recognition library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneSpeech) · [GitHub](https://github.com/recursive-ai-oss/onespeech-csharp) · [Docs](https://recursiveai.org/onespeech/docs/) · [Download example (.zip)](https://recursiveai.org/onespeech/cookbook/configure-speech-model-cache/configure-speech-model-cache.zip)

Choose where OneSpeech stores downloaded models and the files it converts for inference.

```shell
dotnet add package RecursiveAI.OneSpeech
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using OneSpeech.Catalog;
var home = Environment.GetFolderPath(
    Environment.SpecialFolder.UserProfile);
ModelStore.Default = new ModelStore(
    cacheDirectory: Path.Join(home, "speech-models"));
Console.WriteLine("Cache configured.");
```

Unzip [the example](https://recursiveai.org/onespeech/cookbook/configure-speech-model-cache/configure-speech-model-cache.zip), then `dotnet run`.

Prints:

```text
Cache configured.
```

## The full program

```csharp
using OneSpeech.Catalog;
using static System.Environment;

var cache = Path.Combine(
    GetFolderPath(SpecialFolder.UserProfile),
    "speech-models");
ModelStore.Default = new ModelStore(cacheDirectory: cache);
Console.WriteLine("Cache configured.");
Console.WriteLine($"Absolute path: {Path.IsPathFullyQualified(ModelStore.Default.CacheDirectory)}");
Console.WriteLine($"Selected directory: {ModelStore.Default.CacheDirectory == Path.GetFullPath(cache)}");
```

The full program configures the process-wide store and checks the selected path; it downloads nothing. Use a directory only your account can write. Later pulls report ordinary I/O errors for permission or storage failures.

```text
Cache configured.
Absolute path: True
Selected directory: True
```

## Variations

Use the environment variable instead of a constructor override. Set it before creating the store:

```csharp
using OneSpeech.Catalog;
var cache = Path.Join(
    Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
    "speech-models");
Environment.SetEnvironmentVariable("ONESPEECH_MODEL_CACHE", cache);
var store = new ModelStore();
Console.WriteLine(store.CacheDirectory == Path.GetFullPath(cache));
```

```text
True
```

You can also set the directory before starting the application. On Linux or macOS:

```shell
export ONESPEECH_MODEL_CACHE="$HOME/speech-models"
```

On Windows, set it for future terminals:

```bat
setx ONESPEECH_MODEL_CACHE "%USERPROFILE%\speech-models"
```

Open a new terminal after `setx`. These settings apply only when you omit the `cacheDirectory` constructor argument.

## Related recipes

- [Prefetch models for offline use](https://recursiveai.org/onespeech/cookbook/prefetch-models-for-offline-use/)
- [Report download progress](https://recursiveai.org/onespeech/cookbook/report-model-download-progress/)

## The short answer

Pass `cacheDirectory` to `ModelStore`, then assign that store to `ModelStore.Default` before starting high-level `Speech` requests. Alternatively, set `ONESPEECH_MODEL_CACHE` before constructing the store. The constructor argument wins over the environment variable; the platform default is used only when neither is supplied.

Configuring a store does not fetch any models. The example reports the selected path properties without printing your user-directory name. It does not move an existing cache or change requests that have already started.

## How do I change the model cache directory?

Use an application-specific directory under your own user profile, as the snippet at the top does. `CacheDirectory` is the absolute cache root. A relative constructor argument is resolved to a full path, so a path derived explicitly from the user profile avoids depending on the application’s current working directory.

There are two separate choices: which store your code holds and which store the high-level API uses. Constructing a local `store` variable affects only calls you make through that instance. Assigning it to `ModelStore.Default` supplies the process-wide store used by `Speech`. Make that assignment during startup, before concurrent requests. Replacing the default does not alter requests already in progress or dispose borrowed model sources.

If configuration comes from the process environment, the variation above reads `ONESPEECH_MODEL_CACHE` through a newly constructed store. Changing that variable later does not rewrite the path held by an existing store. For deployed applications, set the environment before startup rather than changing it while work is running.

## Where are downloaded speech models stored?

Without an override, Windows uses `LocalApplicationData/OneSpeech/models`. macOS uses `~/Library/Caches/OneSpeech/models`. Other platforms use `$XDG_CACHE_HOME/onespeech/models`, falling back to `~/.cache/onespeech/models`. These are OneSpeech’s own cache rules; environment variables for another model client do not replace them.

The cache contains verified publisher files and registered runtime conversions, not merely a single weights file. Model subdirectories depend on the model ID, pinned revision and upstream filenames and digests. Different revisions therefore cannot silently reuse an old pin. Do not construct subdirectory names yourself; obtain a resolved model from `PullAsync` when you need its directory.

Use a trusted per-user location, not a directory writable by unrelated users. Do not replace model files or cache directories with symbolic links. This is a trust requirement for local files, not a filesystem sandbox.

## Does changing the cache directory download models again?

Assignment alone does not download anything. Later pulls acquire missing files in the selected location. A new empty location does not automatically inherit the files in an old cache. Conversely, files that are already present are rehashed on first open per store instance and do not cause network requests.

Verification state is kept in memory rather than in a writable disk marker. A corrupt cached file is removed and reported with `ModelIntegrityException`; retry explicitly if you want to fetch it again. A persistent `.lock` file coordinates pulls across processes. Its continued presence does not mean a download is still active, and deleting it can split locking between processes. Leave lock-file management to the library. See the [cache and trust documentation](https://recursiveai.org/onespeech/docs/models/#cache-and-trust) for the full behavior.
