How to Configure Node Storage Backends in PrivateGPT: Simple File vs PostgreSQL
Set nodestore.database to "simple" for file-based storage or "postgres" for PostgreSQL, then install the appropriate extras package if using the database backend.
PrivateGPT separates vector embeddings from metadata storage, allowing you to configure node storage backends independently from your vector database. This flexibility lets you choose between zero-configuration file storage for local development or PostgreSQL for production deployments requiring concurrent access and durability.
Understanding Node Storage Architecture
PrivateGPT stores index metadata and document metadata (collectively called the "node store") separately from the vector embeddings. The NodeStoreComponent in private_gpt/components/node_store/node_store_component.py initializes the appropriate backend during application startup based on your configuration.
Simple File Storage Backend
The simple backend uses SimpleIndexStore and SimpleDocumentStore from llama-index to persist metadata as JSON files on disk. This is the default configuration requiring no external dependencies.
- Persistence location: Files under the
local_data_pathdirectory (default:local_data/private_gpt) - Required packages: None (included with base installation)
- Best for: Single-instance deployments, development, and testing
PostgreSQL Storage Backend
The postgres backend uses PostgresIndexStore and PostgresDocumentStore from llama-index to store metadata in PostgreSQL tables, enabling multiple PrivateGPT instances to share the same metadata.
- Persistence location: Tables in a PostgreSQL database
- Required packages:
storage-nodestore-postgresextra - Best for: Production deployments, high availability, and multi-instance setups
Configuring the Node Storage Backend
The backend selection is controlled by the nodestore.database field in your YAML configuration files.
Settings Model and Allowed Values
In private_gpt/settings/settings.py, the NodeStoreSettings model restricts the database value to specific literals:
class NodeStoreSettings(BaseModel):
database: Literal["simple", "postgres"]
This validation ensures only supported backends can be configured.
YAML Configuration Examples
Simple file storage (default in settings.yaml):
nodestore:
database: simple
PostgreSQL storage (example from settings-ollama-pg.yaml):
nodestore:
database: postgres
postgres:
host: localhost
port: 5432
user: postgres
password: postgres
database: private_gpt
schema_name: public
PrivateGPT loads these settings at startup and instantiates the corresponding storage classes.
Installing PostgreSQL Dependencies
When selecting the PostgreSQL backend, you must install the optional dependencies. If the required packages are missing, NodeStoreComponent raises an ImportError with explicit installation instructions.
Install the extra using Poetry:
poetry install --extras storage-nodestore-postgres
Or if using pip with the private package index:
pip install private-gpt[storage-nodestore-postgres]
The component imports PostgresIndexStore and PostgresDocumentStore from llama_index.storage.index_store.postgres and llama_index.storage.docstore.postgres respectively only after this installation.
How the Backend Selection Works
The NodeStoreComponent class in private_gpt/components/node_store/node_store_component.py implements the backend switching logic using Python's match statement:
match settings.nodestore.database:
case "simple":
self.index_store = SimpleIndexStore.from_persist_dir(
persist_dir=str(local_data_path)
)
self.doc_store = SimpleDocumentStore.from_persist_dir(
persist_dir=str(local_data_path)
)
case "postgres":
from llama_index.storage.docstore.postgres import PostgresDocumentStore
from llama_index.storage.index_store.postgres import PostgresIndexStore
self.index_store = PostgresIndexStore.from_params(
**settings.postgres.model_dump(exclude_none=True)
)
self.doc_store = PostgresDocumentStore.from_params(
**settings.postgres.model_dump(exclude_none=True)
)
This construction happens once at application startup when the dependency injection container creates the singleton instance of NodeStoreComponent.
Accessing the Node Store in Code
The NodeStoreComponent is registered as a singleton in the dependency injection container. You can access the initialized stores throughout your application:
from private_gpt.di import global_injector
from private_gpt.components.node_store.node_store_component import NodeStoreComponent
# Retrieve the singleton component
node_store = global_injector.get(NodeStoreComponent)
# Access the underlying stores
index_store = node_store.index_store
doc_store = node_store.doc_store
The concrete implementations (SimpleIndexStore or PostgresIndexStore) are determined entirely by your YAML configuration, allowing you to switch backends without modifying application code.
Summary
- Node storage in PrivateGPT handles index and document metadata separately from vector embeddings, configured via
nodestore.databasein your YAML settings. - Simple file storage requires no extra dependencies and persists JSON files to
local_data/private_gpt, ideal for development. - PostgreSQL storage requires installing the
storage-nodestore-postgresextra and provides durable, shared metadata storage for production. - The
NodeStoreComponentinprivate_gpt/components/node_store/node_store_component.pyautomatically instantiates the correct backend based on your configuration settings.
Frequently Asked Questions
How do I migrate from simple file storage to PostgreSQL?
PrivateGPT does not provide an automatic migration tool between node store backends. To migrate, you must export your index and document metadata from the simple file stores (JSON files in local_data/private_gpt) and import them into PostgreSQL using llama-index's storage APIs, or rebuild your index from source documents after switching the configuration.
Can I use different backends for the node store and vector store?
Yes. PrivateGPT decouples these concerns entirely. You can configure the node store to use PostgreSQL while using a local vector store like Chroma or Qdrant, or vice versa. Each component reads its own configuration section independently.
What happens if I select postgres but forget to install the extras?
The application will fail to start with an ImportError raised by NodeStoreComponent. The error message explicitly instructs you to run poetry install --extras storage-nodestore-postgres to resolve the missing dependencies.
Is PostgreSQL node storage more performant than simple file storage?
PostgreSQL provides better concurrency and durability for multi-instance deployments, but simple file storage has lower latency for single-instance, local development. For high-throughput production environments with multiple PrivateGPT instances, PostgreSQL is the recommended backend.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →