Skip to main content
Version: v1.7.5-1 🚧

Vector database

Enterprise h2oGPTe uses a vector database (the VEX service) to store document chunks and their embeddings for retrieval. VEX exposes a unified API and routes requests to a pluggable storage backend selected at deploy time.

Supported backends​

VEX separates vector storage (for similarity search) from fulltext storage (for lexical search). They are configured independently:

BackendVector store (vex.config.vectorDb)Fulltext store (vex.config.fulltextDb)Notes
PostgreSQLpostgres (uses pgvector)postgresDefault. Shared with the application database. Scales horizontally with vex replicas.
Embedded HNSWhnsw (uses hnswlib)sqlite (uses SQLite FTS5)Legacy in-pod storage. Single-pod only — indexes live on the pod's PVC. Performance degrades around 10M–50M entries per collection.
Elasticsearchelastic_searchelastic_searchExternal cluster, experimental.
Milvusmilvusn/a (use postgres or sqlite)External cluster, experimental.
QdrantqdrantqdrantExternal cluster, experimental.
RedisredisredisSingle instance or cluster mode, experimental.
note

A separate index is created per Collection, so per-backend limits apply at the Collection level. Connection settings for external backends (host, credentials, TLS) are documented in vex/README.md and are passed through to the vex pods via vex.extraEnv in the Helm chart.

note

Please contact us if your preferred vector database is not listed above — additional backends can be added based on customer interest.

Choosing a backend​

  • PostgreSQL (default) — recommended for most deployments. Uses the same database as the application, simplifies operations and backups, and lets you scale vex to multiple replicas. Requires the pgvector extension binaries to be present in the Postgres image; mux runs CREATE EXTENSION automatically on startup, but it will fail if the image does not ship pgvector.
  • Embedded HNSW + SQLite — fastest option for small, single-node deployments. Limited to one vex pod; cannot be scaled horizontally because indexes live on the pod's local volume.
  • External (Elasticsearch / Milvus / Qdrant / Redis) — for organizations that already operate one of these systems or need backend-specific features. Each vex pod becomes stateless; the external database is the source of truth.

Configuring vector encryption​

VEX protects a collection's on-disk data in two independent ways, both gated by enabled:

  • Vector encryption — obfuscates or encrypts embeddings with a distance-preserving scheme (so similarity search still works), using the method chosen by provider.
  • Fulltext encryption — encrypts fulltext .lex files with SQLCipher. This applies automatically to new files whenever enabled: true, regardless of provider.

Encryption is enabled at the vex service level; once enabled, each collection can opt in or out of vector encryption at creation time — see Encrypt vectors at rest.

vex:
encryption:
enabled: true
provider: "internal"
secret: ""
approximationFactor: "7.2"
tenantId: "default"
OptionMeaning
enabledMaster switch. When false, nothing is encrypted and the per-collection encryption toggle does not appear in the UI. When true, fulltext .lex files are SQLCipher-encrypted for new collections no matter what provider is set to — but provider must also be internal or ironcore to actually encrypt vectors. Leaving provider at its default ("", equivalent to noop) stores vectors in plaintext even with enabled: true.
providerinternal (recommended) — built-in distance-preserving vector obfuscation via orthogonal rotation. This is obfuscation, not cryptographic encryption: it makes vectors unreadable without the key, but a sophisticated attacker with known plaintext could recover the rotation matrix. It relies on SQLCipher (which derives from the same secret and is enabled alongside it) for full encryption at rest. ironcore — IronCore Alloy vector encryption; requires switching the vex deployment to the separate, AGPL-licensed vex-ironcore image. noop, "" (default), or none — vectors are stored in plaintext; fulltext files are still SQLCipher-encrypted whenever enabled: true.
secretHex-encoded 32-byte (64 hex character) secret used to derive both the vector-encryption and SQLCipher keys. Provide it via --set or an external secret — do not commit it to a values file.
approximationFactorironcore only. Controls the security/search-accuracy tradeoff.
tenantIdironcore only. Tenant identifier used for key derivation.
caution

The internal provider is an obfuscation technique, not cryptographic encryption of the vectors themselves — treat it accordingly when assessing risk, and rely on SQLCipher (enabled alongside it) for the actual at-rest protection.

caution

The ironcore provider is AGPL-licensed and ships as a separate container image. Confirm this is acceptable for your deployment's license policy before enabling it.

note

Existing collections keep their current format when this setting changes — they are not bulk-converted. Re-ingest a collection to change its encryption status.

Migrating between backends​

The blocking migration strategy copies all collections during a maintenance window before mux starts serving traffic.

Blocking migration (planned downtime)​

warning

If your deployment uses a vector backend other than PostgreSQL, set mux.config.skipPgvectorInitScript to 0 before starting the migration. This lets mux create the vex schema and install the pgvector extension on startup. Without this setting, the migration fails with schema "vex" does not exist.

mux:
config:
skipPgvectorInitScript: 0
vexMigration:
enabled: true
sourceDb: "internal"
destinationDb: "postgres"
blocking: true
overrideExistingCollections: false
bulkSize: 1000
collectionTimeoutSeconds: 600
concurrency: 20
continueOnError: false

Mux halts startup until every collection is copied from sourceDb to destinationDb, then resumes serving traffic with vex pointed at the new backend. Use this when you can schedule a maintenance window.

OptionMeaning
skipPgvectorInitScriptSet to 0 to let mux create the vex schema and install the pgvector extension. Required when migrating to PostgreSQL from a backend that did not use pgvector. Lives under mux.config, not inside vexMigration.
enabledMaster switch for the migration. When false, mux ignores every other field in this block.
sourceDbBackend collections are read from. Valid values: internal (hnsw+sqlite), postgres, milvus, elasticsearch, qdrant, redis.
destinationDbBackend collections are written to. Same valid values as sourceDb. Must match vex.config.vectorDb/fulltextDb.
blockingtrue halts mux startup until every collection is copied.
overrideExistingCollectionsIf true, collections already present on the destination are dropped and re-copied. Leave false to skip them and resume an interrupted migration.
bulkSizeRows copied per batch within a single collection. Higher values increase throughput at the cost of memory.
collectionTimeoutSecondsPer-collection deadline. A collection that exceeds it is marked failed (or aborts the run depending on continueOnError).
concurrencyNumber of collections migrated in parallel. Bound by destination-backend write capacity.
continueOnErrorfalse aborts the whole migration on the first per-collection failure (recommended for blocking runs so issues surface immediately). true skips the failure and continues.
Live migration — coming soon

A zero-downtime "live" migration mode (background copy while the deployment keeps serving traffic) is planned for an upcoming release. Configuration guidance will be published here once it's ready.

Monitoring migrations​

Admins can monitor migration progress from the VEX Migration page — see VEX Migration for details.


Feedback