diff --git a/docs/ai-integration/vector-search/overview.mdx b/docs/ai-integration/vector-search/overview.mdx
index 52a5619172..3db31e661a 100644
--- a/docs/ai-integration/vector-search/overview.mdx
+++ b/docs/ai-integration/vector-search/overview.mdx
@@ -31,6 +31,7 @@ import Panel from '@site/src/components/Panel';
* [Vector search in RavenDB](../../ai-integration/vector-search/overview.mdx#vector-search-in-ravendb)
* [Vector search using a dynamic query](../../ai-integration/vector-search/overview.mdx#vector-search-using-a-dynamic-query)
* [Vector search using a static-index](../../ai-integration/vector-search/overview.mdx#vector-search-using-a-static-index)
+ * [Vector search on encrypted databases](../../ai-integration/vector-search/overview.mdx#vector-search-on-encrypted-databases)
@@ -246,5 +247,17 @@ It explains how to define the index, configure indexing & query-time parameters,
+
+
+
+## Vector search on encrypted databases
+
+* Vector queries on [encrypted databases](../../server/security/encryption/database-encryption.mdx#vector-search-node-cache) run without the HNSW node cache.
+ Without the cache, vector queries may require more disk reads, which can reduce query performance.
+
+* Disabling the cache does not change query results.
+ See [Indexing.Corax.VectorSearch.CacheSizeInMb](../../server/configuration/indexing-configuration.mdx#indexingcoraxvectorsearchcachesizeinmb) for cache configuration.
+
+
diff --git a/docs/indexes/index-administration.mdx b/docs/indexes/index-administration.mdx
index 6e3ea9564d..8fc0469278 100644
--- a/docs/indexes/index-administration.mdx
+++ b/docs/indexes/index-administration.mdx
@@ -78,7 +78,6 @@ import LanguageContent from "@site/src/components/LanguageContent";
##### Reset index
* Resetting an index will force re-indexing of all documents that match the index definition.
- An index usually needs to be reset once it reached its error quota and is in an _Error_ state.
An index usually needs to be reset when it reaches its error quota and enters the _Error_ state.
* See [reset index](../client-api/operations/maintenance/indexes/reset-index.mdx) for detailed information.
diff --git a/docs/server/configuration/indexing-configuration.mdx b/docs/server/configuration/indexing-configuration.mdx
index df5ae451ad..e6cfa7ef29 100644
--- a/docs/server/configuration/indexing-configuration.mdx
+++ b/docs/server/configuration/indexing-configuration.mdx
@@ -68,6 +68,7 @@ import LanguageContent from "@site/src/components/LanguageContent";
[Indexing.Corax.MaxMemoizationSizeInMb](../../server/configuration/indexing-configuration.mdx#indexingcoraxmaxmemoizationsizeinmb)
[Indexing.Corax.Static.ComplexFieldIndexingBehavior](../../server/configuration/indexing-configuration.mdx#indexingcoraxstaticcomplexfieldindexingbehavior)
[Indexing.Corax.UnmanagedAllocationsBatchSizeLimitInMb](../../server/configuration/indexing-configuration.mdx#indexingcoraxunmanagedallocationsbatchsizelimitinmb)
+ [Indexing.Corax.VectorSearch.CacheSizeInMb](../../server/configuration/indexing-configuration.mdx#indexingcoraxvectorsearchcachesizeinmb)
[Indexing.Corax.VectorSearch.DefaultMinimumSimilarity](../../server/configuration/indexing-configuration.mdx#indexingcoraxvectorsearchdefaultminimumsimilarity)
[Indexing.Corax.VectorSearch.DefaultNumberOfCandidatesForIndexing](../../server/configuration/indexing-configuration.mdx#indexingcoraxvectorsearchdefaultnumberofcandidatesforindexing)
[Indexing.Corax.VectorSearch.DefaultNumberOfCandidatesForQuerying](../../server/configuration/indexing-configuration.mdx#indexingcoraxvectorsearchdefaultnumberofcandidatesforquerying)
@@ -603,6 +604,27 @@ The maximum amount of memory in megabytes that Corax can use for memoization dur
+## Indexing.Corax.VectorSearch.CacheSizeInMb
+
+* The memory budget (in MB) used to size the HNSW node cache for each vector field in an index.
+ The cache keeps the upper-level nodes of the HNSW graph in memory, so vector queries read less from disk.
+
+* Set to `0` to disable the cache.
+ Changing this value does not require re-indexing.
+
+* The cache is not supported on [encrypted databases](../../server/security/encryption/database-encryption.mdx#vector-search-node-cache).
+ This setting is ignored on encrypted databases, and vector search reads the HNSW graph from disk.
+
+* This setting is available from RavenDB 7.2.5.
+
+---
+
+- **Type**: `int`
+- **Default**: `10`
+- **Scope**: Server-wide, or per database, or per index
+
+
+
## Indexing.Corax.VectorSearch.DefaultMinimumSimilarity
* The default minimum similarity to use when making a vector search query.
diff --git a/docs/server/security/encryption/database-encryption.mdx b/docs/server/security/encryption/database-encryption.mdx
index ee864255a9..cbc43fffd3 100644
--- a/docs/server/security/encryption/database-encryption.mdx
+++ b/docs/server/security/encryption/database-encryption.mdx
@@ -1,5 +1,5 @@
---
-title: "Encryption: Database Encryption"
+title: "Database Encryption"
sidebar_label: Database Encryption
description: "Encrypt RavenDB databases at rest using XChaCha20-Poly1305 encryption with master key protection and per-database encryption keys."
sidebar_position: 1
@@ -8,149 +8,275 @@ sidebar_position: 1
import Admonition from '@theme/Admonition';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
-import CodeBlock from '@theme/CodeBlock';
import LanguageSwitcher from "@site/src/components/LanguageSwitcher";
import LanguageContent from "@site/src/components/LanguageContent";
+import Panel from "@site/src/components/Panel";
+import ContentFrame from "@site/src/components/ContentFrame";
-# Encryption: Database Encryption
+
-In RavenDB you can create encrypted databases. Each encrypted database will have its own secret key which is used to encrypt and decrypt data.
+* RavenDB supports database encryption at rest.
+ Each encrypted database has its own secret key, used to encrypt and decrypt its data.
-## Creating An Encrypted Database Using The Studio
+* In this article:
+ * [Creating an encrypted database using Studio](#creating-an-encrypted-database-using-studio)
+ * [Creating an encrypted database using the REST API and the Client API](#creating-an-encrypted-database-using-the-rest-api-and-the-client-api)
+ * [Windows example](#windows-example)
+ * [Linux example](#linux-example)
+ * [Considerations for encrypted databases](#considerations-for-encrypted-databases)
-When [creating an encrypted database using the Studio](../../../studio/database/create-new-database/encrypted.mdx), you will receive a secret key which will
-allow you to recover the encrypted data in case of a disaster, and when restoring from backup. During normal operations there is no need to supply the secret key to RavenDB.
+
+
+
+
+When [creating an encrypted database using Studio](../../../studio/database/create-new-database/encrypted.mdx), Studio provides the database's secret key.
+Save this key for recovery, including restoring backups encrypted with that key.
+You do not need to supply it during normal database operations.
See [Secret Key Management](../../../server/security/encryption/secret-key-management.mdx) for more information.

-
-Download, print, or copy and save the secret key in a safe place. It will NOT be available again!
+
+
+#### Save the secret key
+
+Download, print, or copy the secret key and store it in a safe place before completing database creation.
+After creation, the key will no longer be displayed in the database creation dialog.
+
-## Creating An Encrypted Database Using The REST API And The Client API
+
-Before creating the database, a secret key must be generated. Generating and storing secret keys is restricted to `Operator` or `ClusterAdmin` Security Clearances.
-RavenDB uses a [cryptographically secure pseudo-random number generator](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) and
-it is recommended that you use it. If you must use your own secret key, please make sure it is 256 bits long and cryptographically secure.
+
-You must use a client certificate to make the request because the server is using authentication.
+Before creating the database, generate a 32-byte (256-bit) key and supply it as a Base64 string.
+
+The examples below use RavenDB's key generation endpoint.
+If you generate your own key, use a cryptographically secure random number generator.
+Keep a secure copy of the key for recovery.
-## Windows Example
+These examples require:
-Load the client certificate in PowerShell:
-
-
-{`$cert = Get-PfxCertificate -FilePath C:\\secrets\\admin.client.certificate.example.pfx
-`}
-
-
+* A RavenDB server configured for HTTPS and authentication.
+* A license that includes database encryption.
+* A client certificate with `Operator` or `ClusterAdmin` clearance.
+* An initialized `DocumentStore` configured with that certificate.
-Make sure to use TLS 1.2 (or 1.3):
-
-
-{`[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-`}
-
-
+The examples create `MyEncryptedDatabase` on a single node (`A`).
+Replace `https://your-server-url` with the URL of the node that will host the database,
+and replace `A` with that node's tag.
+
+Storing a key through `/admin/secrets` installs it only on the server receiving the request.
+For multiple nodes, use `POST /admin/secrets/distribute?name=MyEncryptedDatabase&node=A&node=B&node=C`
+to store the same key on each node before creating the database.
+Send the Base64 key in the request body. Include those same nodes in `DatabaseRecord.Topology.Members`.
+
+Use a new database name when repeating the complete example.
+By default, RavenDB rejects a different secret key if one is already stored for that name.
+
+
+
+### Windows example
+
+These commands use Windows PowerShell 5.1.
+
+Load the client certificate:
+
+```powershell
+$cert = Get-PfxCertificate -FilePath C:\secrets\admin.client.certificate.example.pfx
+```
+
+
+Configure Windows PowerShell to use TLS 1.2:
+
+```powershell
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+```
+
Ask RavenDB to generate a key for you:
-
-
-{`$response = Invoke-WebRequest https://your-server-url/admin/secrets/generate -Certificate $cert
-`}
-
-
-Then send the key to the RavenDB server on which the database will be created. Note that the database doesn't exist yet, but you will still need to supply its name. Make the following POST request to assign the secret key to a specific database:
-
-
-{`$payload = [System.Text.Encoding]::ASCII.GetString($response.Content)
-Invoke-WebRequest https://your-server-url/admin/secrets?name=MyEncryptedDatabase -Certificate $cert -Method POST -Body $payload
-`}
-
-
+```powershell
+$response = Invoke-WebRequest -UseBasicParsing `
+ -Uri "https://your-server-url/admin/secrets/generate" `
+ -Certificate $cert
+```
+
+
+Store the key on the node that will host the database, using the future database name (`MyEncryptedDatabase`).
+The database does not need to exist yet:
+
+```powershell
+$payload = [System.Text.Encoding]::ASCII.GetString($response.Content)
+
+Invoke-WebRequest -UseBasicParsing `
+ -Uri "https://your-server-url/admin/secrets?name=MyEncryptedDatabase" `
+ -Certificate $cert `
+ -Method POST `
+ -ContentType "text/plain" `
+ -Body $payload
+```
+
Finally, create the encrypted database using the Client API:
-
-{`store.Maintenance.Server.Send(new CreateDatabaseOperation(new DatabaseRecord("MyEncryptedDatabase")
-{
- Encrypted = true
-}));
-`}
-
+```csharp
+store.Maintenance.Server.Send(
+ new CreateDatabaseOperation(
+ new DatabaseRecord("MyEncryptedDatabase")
+ {
+ Encrypted = true,
+ Topology = new DatabaseTopology
+ {
+ Members = { "A" }
+ }
+ }));
+```
-
-{`await store.Maintenance.Server.SendAsync(new CreateDatabaseOperation(new DatabaseRecord("MyEncryptedDatabase")
-{
- Encrypted = true
-}));
-`}
-
+```csharp
+await store.Maintenance.Server.SendAsync(
+ new CreateDatabaseOperation(
+ new DatabaseRecord("MyEncryptedDatabase")
+ {
+ Encrypted = true,
+ Topology = new DatabaseTopology
+ {
+ Members = { "A" }
+ }
+ }));
+```
-## Linux Example
+
-When generating a client certificate using RavenDB, you will receive a Zip file containing an admin client certificate (.pfx, .crt, .key).
+
-First we will create a .pem certificate file from the .crt and .key files:
-
-
-{`cat admin.client.certificate.example.crt admin.client.certificate.example.key > clientCert.pem
-`}
-
-
+### Linux example
+
+The certificate ZIP downloaded from Studio contains `.pfx`, `.crt`, and `.key` files.
+Use the `.crt` and `.key` files to create a `.pem` file:
+
+```bash
+cat admin.client.certificate.example.crt \
+ admin.client.certificate.example.key > clientCert.pem
+```
+
Ask RavenDB to generate a key for you:
-
-
-{`key=$(curl --cert clientCert.pem https://your-server-url/admin/secrets/generate)
-`}
-
-
-Then send the key to the RavenDB server on which the database will be created. Note that the database doesn't exist yet, but you will still need to supply its name. Make the following POST request to assign the secret key to a specific database:
-
-
-{`curl -X POST -H "Content-Type: text/plain" --data $key --cert clientCert.pem https://your-server-url/admin/secrets?name=MyEncryptedDatabase
-`}
-
-
+```bash
+key=$(
+ curl --fail --silent --show-error \
+ --cert clientCert.pem \
+ "https://your-server-url/admin/secrets/generate"
+)
+```
+
+
+Store the key on the node that will host the database, using the future database name (`MyEncryptedDatabase`).
+The database does not need to exist yet:
+
+```bash
+curl --fail --silent --show-error \
+ -X POST \
+ -H "Content-Type: text/plain" \
+ --data "$key" \
+ --cert clientCert.pem \
+ "https://your-server-url/admin/secrets?name=MyEncryptedDatabase"
+```
+
Finally, create the encrypted database using the Client API:
-
-{`store.Maintenance.Server.Send(new CreateDatabaseOperation(new DatabaseRecord("MyEncryptedDatabase")
-{
- Encrypted = true
-}));
-`}
-
+```csharp
+store.Maintenance.Server.Send(
+ new CreateDatabaseOperation(
+ new DatabaseRecord("MyEncryptedDatabase")
+ {
+ Encrypted = true,
+ Topology = new DatabaseTopology
+ {
+ Members = { "A" }
+ }
+ }));
+```
-
-{`await store.Maintenance.Server.SendAsync(new CreateDatabaseOperation(new DatabaseRecord("MyEncryptedDatabase")
-{
- Encrypted = true
-}));
-`}
-
+```csharp
+await store.Maintenance.Server.SendAsync(
+ new CreateDatabaseOperation(
+ new DatabaseRecord("MyEncryptedDatabase")
+ {
+ Encrypted = true,
+ Topology = new DatabaseTopology
+ {
+ Members = { "A" }
+ }
+ }));
+```
-## Remarks
+
+
+
-Database encryption must be enabled when creating the database. If you wish to use encryption in an existing database, it must be exported and then imported back into a new encrypted database.
+
-
-Indexing is most efficient when it is performed in the largest transactions possible. However, using encryption is very memory intensive, and if memory
-runs out before the transaction completes, the entire transaction will fail. To avoid this, you can limit the size of indexing batches in encrypted
-databases using [Indexing.Encrypted.TransactionSizeLimitInMb](../../../server/configuration/indexing-configuration.mdx#indexingencryptedtransactionsizelimitinmb).
+
+
+### Enabling database encryption
+
+* Database encryption must be enabled when creating the database.
+
+* To encrypt an existing database, export its data and import it into a new encrypted database.
+
+
+
+### Indexing transaction size
+
+* Indexing is most efficient when it is performed in the largest transactions possible.
+ However, using encryption is very memory intensive, and if memory runs out before the transaction completes, the entire transaction will fail.
+
+* To avoid this, you can limit the size of indexing batches in encrypted databases
+ using [Indexing.Encrypted.TransactionSizeLimitInMb](../../../server/configuration/indexing-configuration.mdx#indexingencryptedtransactionsizelimitinmb).
+
+
+
+
+
+### Vector search node cache
+
+* The HNSW node cache is disabled for **Corax vector indexes on encrypted databases**.
+ This applies to both static indexes and auto-indexes created by dynamic vector queries.
+
+* The cache is incompatible with encryption, so [Indexing.Corax.VectorSearch.CacheSizeInMb](../../../server/configuration/indexing-configuration.mdx#indexingcoraxvectorsearchcachesizeinmb) is ignored on encrypted databases.
+ Vector queries read the HNSW graph from disk.
+
+* Without the cache, vector queries may require more disk reads, which can reduce query performance.
+ Query results remain unchanged.
+
+* Lucene indexes and Corax indexes without vector fields are unaffected.
+ On unencrypted databases, the HNSW node cache remains available and is controlled by `Indexing.Corax.VectorSearch.CacheSizeInMb`.
+
+
+
+
+
+### Recovering vector indexes affected by RavenDB 7.2.5 regression
+
+* A regression in RavenDB 7.2.5 caused Corax vector indexes on encrypted databases to fail during indexing.
+
+* If an index entered Error state because of this regression, upgrade to RavenDB 7.2.6 or later and [reset the affected index](../../../indexes/index-administration.mdx#reset-index).
+ With the [default index startup behavior](../../../server/configuration/indexing-configuration.mdx#indexingerrorindexstartupbehavior), upgrading alone does not clear the Error state.
+ Resetting rebuilds the index from the documents.
+
+
+