Relatude Help

12.1 Every setting in relatude.db.json

The file is one JSON object, read into RelatudeDBServerSettings. Keys are case-insensitive, enums are written as names ("LocalDisk", "Native"), and // comments are allowed, though trailing commas are not. The tables list every key by the object it sits on. The default is the value used when the key is left out.

Server level

Key Default What it does
DefaultStoreId – The Id of the database ctx.Database returns. Required.
ContainerSettings – The databases, one entry each. Each has its own datamodel, storage, indexes and files.
Id new Guid Identifies the server. Only matters when several servers share settings.
Name, Description null Labels shown in the admin UI.
DBAdminUIUrlPath /relatude.db The admin UI's path. Overrides the argument to UseRelatudeDB(). A change needs a restart of the process.
InfoUrlPath /-info/ Where the server serves the bot check its pages carry, and takes their reports (§35.5).
DBSettingsFilePath null The file name the settings pages show as the source of the settings. It does not change which file is read.

The admin login. These keys protect the admin UI. They have nothing to do with your application's own users.

Key Default What it does
MasterUserName null The one admin user. Write it in lowercase: the login lowercases what is typed before comparing. Null means no one can log in.
MasterPassword null The admin password, compared exactly. Keep it in the RelatudeDB configuration section, not in this file.
TokenEncryptionSecret null The key that encrypts the session cookie. Without it each process makes a random key, so every restart signs everyone out. Use a long random string, unique per installation.
NoLoginRequiredForLocalhost true A browser on the same machine gets into the admin UI without logging in. This is why it just works in development.
AllowMasterLoginOutsideLocalhost false Allow the master login, and its sessions, from other machines. Turn it on only over HTTPS, with credentials set.
TokenCookieName "RelatudeDBToken" The session cookie's name. Change it when two apps share a host name.
TokenCookieMaxAgeInSec 864000 (10 days) How long a "remember me" cookie lasts. Older tokens are rejected.
TokenCookieSecure true The cookie's Secure flag.
TokenCookieSameSite true true gives SameSite=Strict, false gives None.
TokenLockedToIP false Tie a session to the IP address that started it. Safer, but users are logged out when their address changes.

A request counts as local only when it comes from a loopback address with no sign of a proxy: no forwarding headers, and not hosted behind IIS, Azure App Service or Kubernetes. Behind a reverse proxy nobody is local, so you need MasterUserName, MasterPassword and AllowMasterLoginOutsideLocalhost, or Sign in with Relatude Services (below).

Relatude Services. The account an installation uses for hosted AI, imaging, files to text and text messages, and for signing in to the admin UI (§35). All of it is optional: without ApiKey, nothing is charged and nothing is reported.

Key Default What it does
ApiKey null An API key from the license's page at services.relatude.com. It is all an installation needs to use the hosted services, which charge each call to that license. A secret: keep it in configuration.
LicenseKey null The license's id. Not needed: it is looked up from ApiKey, whose license wins if the two disagree.
AllowLicenseeAdminLogin false Adds Sign in with Relatude Services to the login page, for anyone with access to the license. Turning it off ends those sessions at once.
PublicUrl null The addresses the server is reached on, separated by commas: where a sign-in may return to. Every https address an admin uses is added automatically, and localhost always works.
DisableHeartbeat false Stop the installation reporting in (Reporting in). Applies without a restart. Not on the settings pages.
ServicesServerUrl https://services.relatude.com The license server. Change it only for a self-hosted or test server.

Container level

Key Default What it does
Id – The database's identity. DefaultStoreId points at it, and it stays when the name changes.
Name, Description null Labels. Name is what the admin UI shows and what the CLI's --store matches.
ShortName null Names the database's folder of shared settings, relatude.settings/<ShortName>/. Letters, digits, - and _. See below.
AutoOpen false Open the database when the app starts. Turn it on for the database your code uses, or it stays closed until someone opens it in the admin UI.
WaitUntilOpen false Hold the app's start until the database is open. When off, the app starts at once and requests during the open get a 503 progress page. Turn it on when a failed open should fail the start.
IOSettings – The storage backends this database can use. See below.
IoDatabase – The backend that holds the transaction log, the source of truth. Required.
IoIndexes IoDatabase Where the index engines write. Point it at a fast local disk when the log is on blob storage.
IoBackup IoDatabase Where backups are written.
IoLog IoDatabase Where the activity logs and the logs you define (§32) are written.
IoDatabaseSecondary null A second log on other storage. With LocalSettings.SecondaryBackupLog it keeps the history that a log rewrite removes, which FindOlderVersions reads (§16).
FileStoreSettings none The file stores that hold FileValue bytes. See below.
DatamodelSources none Where the node types come from. See Two ways to register a datamodel.
AISettings null The AI provider for embeddings and completions. Required for semantic search. See below.
ImagingSettings, FileToTextSettings, TranslationSettings, IPLookupSettings null The providers behind db.Services.Imaging, FileToText, Translation and IPLookup. Null means the hosted Relatude service, used with the installation's license (§34).
SMSSettings null The provider behind db.Services.SMS (§35). Null means no SMS, and db.Services.SMS throws.
LocalSettings defaults The engine settings. See below.

ShortName. A database's shared settings files are its log definitions, its GraphQL endpoints (§33.2) and its datamodel overrides. With a short name they live in relatude.settings/<ShortName>/; without one, directly in relatude.settings/. That is all you need with one database. Short names must be unique, and only one database can go without one. Set it in relatude.db.json, so that every installation reads the same folder.

IOSettings — a storage backend

{ "Id": "1a2b…", "Name": "Local disk", "IOType": "LocalDisk", "Path": "relatude.data" }
{ "Id": "9d8c…", "Name": "Azure",      "IOType": "AzureBlobStorage",
  "BlobConnectionString": "…", "BlobContainerName": "mydb", "LockBlob": true }
{ "Id": "5e6f…", "Name": "In memory",  "IOType": "Memory" }
Key Default What it does
Id – What the Io… keys and FileStoreSettings.IoProviderId refer to.
Name null Label.
IOType Memory LocalDisk, AzureBlobStorage, or Memory, where nothing survives a restart (tests and demos).
Path "~" LocalDisk only. Relative to the root data folder, which ~ stands for. relatude.data is the usual value.
BlobConnectionString null AzureBlobStorage only. Required.
BlobContainerName null AzureBlobStorage only. Required.
LockBlob false Lease every blob that has an open stream, so no other process can write or delete it. Use it wherever two instances can overlap, such as an overlapped recycle.

A LocalDisk path must stay inside the root data folder, even an absolute one, or the server refuses it. To keep the data somewhere else, move the root data folder with ServerOptions.DefaultDataFolderPath, which moves relatude.settings/ along with it. Several roles can share one backend: inside it, the log, state, backups, logs and indexes each get their own folder.

Blob leases. A lease lasts 60 seconds and is renewed while the stream is open. A process that dies without letting go keeps its blobs locked for at most a minute: an open that finds a blob leased waits up to 75 seconds, then fails with a FileLockedException. A lease that never ends, one taken by another tool for example, blocks every open of its blob. To release it, open Files in the admin UI on that storage and press Leases. It lists the leased blobs and breaks the leases this server does not hold itself. Break them only when no other instance uses the storage.

FileStoreSettings — where file bytes live

A new database gets one MultiFile store that keeps one copy per content and hashes with SHA256, as in the example above, and LocalSettings.DefaultFileStore names it. FileStoreSettings.CreateMultiFile(ioProviderId) makes the same store in code.

Key Default What it does
Id – What [FileProperty(FileStorageProviderId = "…")] and LocalSettings.DefaultFileStore refer to.
IoProviderId – The IOSettings entry that holds the bytes. It must exist, or the open fails.
StoreType SingleFile MultiFile writes one file per upload: use it when anything outside the engine reads the files. SingleFile packs all files into one append-only file, which means fewer file handles and is cheap on blob storage.
MultiFileFolderDepth 2 MultiFile only: levels of hashed subfolders, so that no folder grows too large.
SameHashSameFile false in JSON MultiFile only: keep one copy of each content. An upload with the same hash and length as a stored file points at that file instead of being stored again. Applies to new uploads.
HashAlgorithm MD5 in JSON MultiFile only: SHA256 or MD5. The hash stored in FileValue.Hash, which also decides whether two uploads are the same file. Use SHA256 when untrusted users upload, as two different files with the same MD5 can be made on purpose. Applies to new uploads.

A store written in JSON without SameHashSameFile and HashAlgorithm gets false and MD5. A store made in code, by the CLI or by the admin UI gets true and SHA256, and writes both keys out. So when you add a store by hand, write both keys. A SingleFile store ignores them.

When DefaultFileStore is not set, uploads go to an implicit store: MultiFile on IoDatabase, one file per upload, MD5. Each file records the store it went into, and the implicit store's id is the empty Guid. If you name a configured store as DefaultFileStore later, new uploads go there and the earlier files are still read from the implicit store.

Moving files to another store

Changing DefaultFileStore, SameHashSameFile or HashAlgorithm affects new uploads only. To bring the stored files along, use Storage › File storage › Rewrite files… in the admin UI. Choose the store to write into and how it writes: the hash, and Same hash, same file. Those two are saved as the store's own settings and apply to new uploads at once. They cannot be chosen for the implicit store, for a SingleFile store, or where configuration or code sets them. The job runs in the background while the database stays in use.

  • It writes every file that belongs in the store, wherever the file is now: the files of the properties that upload into it, as the default store or by name. Revisions and embedded objects are included. Files of properties that upload elsewhere stay where they are, so a store nothing uploads into has nothing to rewrite: make it the default first.
  • The target store writes each copy with its own hash, layout and sharing. A file that several values share is copied once. Name, image size, meta data and extracted text are kept, and nothing is indexed again.
  • A file already in the store is rewritten only where the store would now write it differently: with another hash, or not yet kept by its hash. So after you change a store's hash or turn on Same hash, same file, a rewrite into the same store brings its existing files in line.
  • A value that changes during the copy, a new upload for example, is left alone. A file that cannot be read is reported and its value is left as it was. Running the job again picks up whatever is left, including the rest of a cancelled run.
  • The old copies stay where they are, because older versions in a node's history still point at them. Storage › Missing and redundant files removes them; after that, those older versions have no file.

From code:

var local = (DataStoreLocal)db.Datastore;
var result = await local.RewriteFilesAsync(toStoreId,
    (step, percent) => Console.WriteLine($"{percent}% {step}"));
Console.WriteLine($"{result.ValuesRewritten} rewritten, {result.FailedCount} failed");

RewriteFilesAsync(fromStoreId, toStoreId, …) moves every file of one store into another, whatever store its property uploads to. Guid.Empty names the implicit store. Both return a RewriteFilesResult with the counts and the values that could not be rewritten. SetFileStoreWriteOptions(storeId, sameHashSameFile, hashAlgorithm) changes how an open MultiFile store writes new files; at the next open, the settings decide again.

AISettings — embeddings, completions and the vector index

AISettings gives a database an AI provider for embeddings, which semantic search uses, and for completions. TypeName picks the provider. All of these are built into Relatude.DB.Server, so there is nothing extra to install:

TypeName Provider
AzureAI (or empty) Azure OpenAI. ServiceUrl is the resource endpoint, and the model keys hold deployment names.
OpenAI OpenAI, or any OpenAI-compatible endpoint (Mistral, Groq, Ollama and the like) through ServiceUrl.
Anthropic Claude, for completions. Anthropic has no embeddings API, so point EmbeddingServiceUrl, EmbeddingApiKey and EmbeddingModel at an OpenAI-compatible endpoint.
RelatudeServices The hosted Relatude AI service. No vendor account: every call is charged to your Relatude license (§35).
Dummy Placeholder vectors: for tests, or to open a database whose real provider is unavailable.
anything else The assembly-qualified name of your own IAIProvider (§35.2).
"AISettings": {
  "TypeName": "AzureAI",
  "ServiceUrl": "https://my-resource.openai.azure.com",
  "ApiKey": "…",                                // better in configuration
  "EmbeddingModel": "text-embedding-3-small",
  "CompletionModel": "gpt-4o-mini"
}

With RelatudeServices on a server, leave ApiKey empty: calls are paid with the installation's own API key. Its models are names the service publishes, and left empty the service picks its default. The license needs a credit account with a balance for each kind of call: ai_embeddings for embeddings and ai_completion for completions.

Key Default What it does
TypeName AzureAI The provider, as above.
Name null Label.
ServiceUrl per provider The endpoint. Required for Azure. OpenAI defaults to https://api.openai.com/v1.
ApiKey null The vendor's key. Keep it in the RelatudeDB configuration section, not in this file.
ApiVersion per provider Overrides the api-version query parameter, for Azure OpenAI.
EmbeddingModel – The embedding model (on Azure, the deployment name).
EmbeddingServiceUrl, EmbeddingApiKey ServiceUrl, ApiKey A separate endpoint for embeddings. Required for Anthropic.
CompletionModel – The completion model (on Azure, the deployment name). Anthropic and RelatudeServices have a default.
CompletionModelsByKey null Named alternatives for GetCompletionAsync(prompt, modelKey), such as a cheap model and a strong one.
MaxOutputTokens not sent (Anthropic: 4096) The upper bound on a completion's length.
ModelDimensions the first vector's The embedding length. It must match the vectors in the index: a vector of another length is replaced by a placeholder, with a warning in the log, so search quality drops without an error.
DefaultSemanticRatio 0.5 The semanticRatio of a query that names none. 0 is pure BM25, 1 pure vector search.
DefaultMinimumSimilarity 0.34 Vector hits below this similarity are dropped.
MaxCharsInBatch 50 000 Characters per embeddings request.
MaxCountInBatch 500 Texts per embeddings request.
MaxCharsOfEach 20 000 Longer texts are cut to this length before embedding.
CacheType Native Where embeddings are cached, so a reindex does not pay for them twice: Native (a local file), Sqlite, Memory or None. The cache is keyed by the text and the model, so a new model never gets the old one's vectors.
FilePath the IoIndexes folder The folder for the embedding cache. Relative to the root data folder.

The vector index engine is not an AI setting. Choose it in LocalSettings with VectorIndexes and DefaultVectorIndex, below. Semantic indexes exist only on a database with AISettings.

LocalSettings — the engine

Every key has a working default. The groups start with the ones you change most often.

Indexing. What is indexed, and by which engine. Without engines, every index is kept in memory and loaded again at each open, which suits small databases only. A new relatude.db.json has a Native value engine and a Native text engine, with the defaults pointing at them. This example also keeps the vectors on disk:

"LocalSettings": {
  "EnableTextIndexByDefault": true,
  "ValueIndexes":  [ { "Id": "4d1f…", "TypeName": "Native" } ],
  "TextIndexes":   [ { "Id": "9b2c…", "TypeName": "Native" } ],
  "VectorIndexes": [ { "Id": "e7a0…", "TypeName": "HNSW", "MaxMemoryUsageInMb": 512 } ],
  "DefaultValueIndex":  "4d1f…",
  "DefaultTextIndex":   "9b2c…",
  "DefaultVectorIndex": "e7a0…"
}
Key Default What it does
EnableTextIndexByDefault false Put every node type in the BM25 text index unless it opts out. When off, only types with [Node(TextIndex = BoolValue.True)] and properties with IndexedByWords = true are searchable. Usually the first thing you change.
EnableSemanticIndexByDefault false The same for the vector index. Every node costs an embedding call, so prefer opting in per property.
EnableInstantTextIndexingByDefault false Index text inside the transaction instead of in the background, so a node is searchable as soon as the write returns. Writes get slower.
CultureSensitiveTextIndex false Keep a text index per culture, so a search in a culture finds the words of the version its readers see (§29). A change rebuilds the text indexes at the next open.
ValueIndexes null The engines that value indexes (Indexed = true) can run on: { "Id", "TypeName", "MaxMemoryUsageInMb" }. TypeName is Native, Sqlite (needs Relatude.DB.Plugins.Sqlite) or the full type name of your own IValueIndexEngine. An engine is used only when a default names it.
TextIndexes null The same for the BM25 indexes: Native, Lucene (needs Relatude.DB.Plugins.Lucene) or Sqlite. With Sqlite for both value and text indexes, one database holds both and each change commits in one transaction.
VectorIndexes null The same for semantic indexes: IVS (clustered, cheap to build) or HNSW (a graph kept in memory, higher recall). Compared in the vector index benchmarks.
DefaultValueIndex, DefaultTextIndex, DefaultVectorIndex empty Guid The Id of the engine behind every index of that kind. The empty Guid is the memory index. A change rebuilds those indexes at the next open.
MaxMemoryUsageInMb (per engine) 256 What the engine may use for caches and buffers. A limit, not an allocation: 0 uses as little as possible.
PersistedValueIndexFolderPath the IoIndexes folder Where the engines write, each in a subfolder named by its Id.
StateStore Memory Where the per-node state lives: ids, positions in the log, addresses and relations. Memory holds it in memory and saves it with the state snapshot. Native keeps it on disk, so memory use stays within the budget below however many nodes there are. A change rebuilds the state at the next open.
StateStoreMaxMemoryUsageInMb 256 The cache budget of the Native state store.

Culture, access and files.

Key Default What it does
DefaultCultureCode null The culture used when a node or a query names none. Null means cultures are not in play.
DefaultReadAccess Everyone Who may read a node when neither the node nor its type sets read access: Everyone, Member or Admins.
DefaultFileStore null The FileStoreSettings entry that file properties upload to when they name none. It must exist, or the open fails. Null means the implicit store.
ImageDefaultFormat Jpeg The format adaptive image variants resolve to: Jpeg, WebP or Png. Switching a site to WebP is this one key (§18.1).
ImageDefaultQuality 85 The quality used when a request names none. A change to this or ImageDefaultFormat makes new variants, under new URLs, as they are requested.
UrlOptions flat URLs The URL manager's settings (§18).
Passwords null The keys and hash settings of password properties (Passwords). Without an EncryptionKey, no password can be kept encrypted.
DefaultWriteAccess Everyone Has no effect.

Durability. How soon writes reach the disk. The defaults can lose the last second of writes in a crash, but never corrupt the database.

Key Default What it does
FlushDiskOnEveryTransactionByDefault false Treat every write as if flushToDisk: true were passed: full durability per transaction, at about two fsyncs per commit.
AutoFlushDiskInBackground true Flush on a timer instead.
AutoFlushDiskIntervalInSeconds 1 The timer, and so the most a crash can lose.
DelayAutoDiskFlushIfBusy true Put off a timed flush while the store is busy, so a burst of writes is not interrupted.
MaxDelayAutoDiskFlushIfBusyInSeconds 15 The longest a flush is put off.
ForceDiskFlushAfterActionCountLimit 10 000 Flush anyway once this many actions are waiting.
DeepFlushDisk false Also flush the operating system's write cache. Slower, and only matters where that cache has no battery backup.
BusyThresholdActivitiesLast10Sec 100 How many writes in the last 10 seconds count as busy.
BusyThresholdQueriesLast10Sec 1 000 How many queries in the last 10 seconds count as busy.
ThrowOnBadLogFile false Fail the open when the log ends mid-record, as it does after a crash, instead of replaying up to the last good record. For tests, never for production.
ThrowOnBadStateFile false Fail the open on a corrupt state snapshot, instead of rebuilding the state from the log.

State snapshots. A snapshot lets the next open skip replaying the log from the start.

Key Default What it does
AutoSaveIndexStates true Write snapshots in the background.
AutoSaveIndexStatesIntervalInMinutes 120 At most this often.
AutoSaveIndexStatesActionCountLowerLimit 50 000 Skip the snapshot when fewer actions than this came since the last one: replaying them is cheaper.
AutoSaveIndexStatesActionCountUpperLimit 200 000 Write one when more actions than this came, whatever the interval.

Backups. Off by default. The admin UI takes a backup with one click either way.

Key Default What it does
AutoBackUp false Take backups on a schedule.
NoHourlyBackUps, NoDailyBackUps, NoWeeklyBackUps, NoMonthlyBackUps, NoYearlyBackUps 10, 10, 4, 12, 10 How many backups to keep: the first of each of the last N hours, days, weeks, months and years. So the backups thin out with age.
TruncateBackups false Write backups that hold the current state only. Much smaller, but without version history (§16).
SecondaryBackupLog false Also append every transaction to IoDatabaseSecondary. That log survives rewrites, so it keeps the full history for FindOlderVersions.

With AutoBackUp on, a backup is taken every hour. The finest generation above 0 sets the pace: with NoHourlyBackUps at 0 a backup is taken once a day, with NoDailyBackUps at 0 too, once a week, and so on. With all five at 0 there are no automatic backups, and the existing ones are deleted unless they are marked keep.

Log truncation. The transaction log grows until something rewrites it.

Key Default What it does
AutoTruncate false Rewrite the log to the current state on a schedule. Frees space, but discards version history.
AutoTruncateIntervalInMinutes 240 At most this often.
AutoTruncateActionCountLowerLimit 100 000 Due once this many actions can go: deletes and replacements of nodes and relations.
AutoTruncateRedundantPercentageLimit 50 Also due once this share of the log can go, whichever comes first. 0 turns this check off.
AutoTruncateDeleteOldFileOnSuccess false Delete the old log after a successful rewrite. When off, it stays until you delete it.

Caches. Sizes in gigabytes. Both are upper limits, not reservations.

Key Default What it does
NodeCacheSizeGb 1 Cached node data. The biggest lever on read speed for a database larger than memory.
SetCacheSizeGb 1 Cached result sets: the id sets behind Where, facet counts and relation lookups. They make a repeated faceted query fast.
AutoPurgeCache true Trim the caches in the background, not only under memory pressure.
AutoPurgeCacheIntervalInMinutes 5 How often.
AutoPurgeCacheLowerSizeLimitInMb 1 Leave caches smaller than this alone.

Background tasks and diagnostics.

Key Default What it does
AutoDequeTasks true Run the task queue: text indexing, embeddings, file conversion. When off, tasks are queued but nothing runs them.
TaskQueueSpeed 90 How eagerly background work starts, 0–100: the Speed slider on the Tasks page. Higher runs longer rounds with shorter pauses, and keeps going on a busier database. 0 does not stop the queues; AutoDequeTasks does.
PersistedQueueStoreEngine Native Where queued tasks are kept: Native, Sqlite or Memory. Memory loses them at a restart.
PersistedQueueStoreFolderPath the IoIndexes folder Sqlite only: where the queue's database goes.
TaskConcurrency null How many batches of a task type may run at once: a list of { "Id", "TaskType", "MaxConcurrency" }. Edited as Batches at once in the admin UI.
Schedules null Which job runs when. Edited on Tasks › Scheduler (§36).
WriteSystemLogConsole true Echo the system log to the console.
LogRecording null Which activity logs record after a restart. Written by Save and remember changes on the Activity page; a log that is not listed starts off. The logs you define keep their own switches (§32).
MinQueryDurationMsBeforeLogging 0 Leave queries faster than this out of the query log. 0 logs every query.
MaxQueryDurationInSeconds 0 Stop a query still running after this long, with a TimeoutException. 0 means no limit. See Heavy queries, and stopping one.
WarnWhenQueryReadsNodesFromDisk 100 000 Warn in the system log, at most once a minute, about a query that reads more nodes than this from the log file. 0 turns it off.
DoNotCacheMapperFile false Has no effect.