Skip to main content

Adding a New Vector Store to cognee

This guide describes how to integrate a new vector database engine into cognee, following the same pattern used for existing engines (e.g., Weaviate, Qdrant, Milvus, PGVector, LanceDB).

Repository Options

Cognee used both the core and the community repositories to host vector-database adapters. 🚨 From now on every vector-database adapter – except LanceDB – will live in the cognee-community repository. Qdrant have already been migrated from the core library and the remaining adapters will follow shortly. You can find Redis, OpenSearch, and Azure AI Search integrations available in the community repo. Therefore all new adapter contributions must target the community repository.
The core repository will keep only the built-in LanceDB integration.

For Community Repository

To add a new adapter to cognee-community:
  1. Fork and clone the cognee-community repository, and branch from main — unlike the core Cognee repo, cognee-community has no dev branch.
  2. Create your adapter in packages/vector/<engine_name>/cognee_community_vector_adapter_<engine_name>/
  3. Inside that directory add __init__.py, <engine_name>_adapter.py, and register.py (see the Redis implementation as an example).
  4. At the package root packages/<engine_name>/ add __init__.py, pyproject.toml, and README.md.
  5. Run the shared vector conformance suite in packages/shared/contract_suite/vector_contract.py against your adapter.
  6. Submit a pull request to the community repository
Below are the recommended steps in more detail.

Why cognee-community?

cognee-community is the extension hub for Cognee.
Anything that is not part of the core lives here—adapters for third-party databases, pipelines, community contributed additional tasks, etc.
Placing your adapter in this repository means:
  • Your code is released under the community license and can evolve independently of the core.
  • It can be installed with pip install cognee-community-vector-adapter-(engine_name) without pulling in heavyweight drivers for users who don’t need them. For example, for Qdrant it is pip install cognee-community-vector-adapter-qdrant
  • These packages can be called with the cognee core package using the registration step described below.
If you are unfamiliar with the layout, have a look at the existing folders under packages/* in the community repo—each sub-folder represents a separate provider implemented in exactly the way you are about to do.

1. Implement the Adapter

File: packages/vector/<engine_name>/cognee_community_vector_adapter_<engine_name>/<engine_name>_adapter.py Your adapter must implement the VectorDBInterface protocol, implementing all required methods for collection management, data point operations, and search functionality. Here is a sample skeleton with placeholders:
Keep the method signatures consistent with VectorDBInterface. Reference the existing adapters like QDrantAdapter for more comprehensive examples.

What Cognee passes your constructor

Cognee never instantiates your adapter directly — the vector engine factory (create_vector_engine) does, resolving your class out of the registry by the provider name you passed to use_vector_adapter. It calls your __init__ with these keyword arguments, all by keyword, never positionally: Apart from embedding_engine, every value above comes from user configuration — set through config.set_vector_db_config({...}) or the matching VECTOR_DB_* environment variables. See the community adapters overview. Two normalization details to code against:
  • vector_db_port arrives as a string, not an int. Numeric values are stringified before forwarding. It also defaults to 1234 in VectorConfig, so you receive vector_db_port="1234" even when the user never configured a port — don’t treat a truthy port as proof the user chose one.
  • None never reaches you for these parameters. Any of them left as None is replaced by the factory’s own default, an empty string. So an unset host, username, or password arrives as "".
Accept **kwargs. Cognee may forward additional keywords to registry adapters over time, and an adapter with a closed signature fails at construction with TypeError: __init__() got an unexpected keyword argument. A trailing **kwargs (as in the skeleton above) keeps your adapter working across Cognee versions — ignore what you don’t need rather than declaring it.
If you store the credentials on the instance, keep them out of your logs and error messages — see Security below.

2. Test with a Dedicated Script

File: packages/vector/engine_name/examples/example.py Create a script that loads cognee, configures it to use your new <engine_name> provider, and runs basic usage checks. For example:
This script ensures a basic end-to-end test, verifying:
  • Your new adapter can be selected by cognee.
  • Data can be remembered into the vector database flow.
  • Recall functionality works correctly.
  • The database is empty after a prune operation.

3. Create a Test Workflow

File: .github/workflows/vector_db_tests.yml Add a new job to the existing vector database tests workflow:

5. Update pyproject.toml

Add your vector database client dependencies to the optional dependencies: pyproject.toml:
  • Run the shared conformance suite in packages/shared/contract_suite/vector_contract.py against your adapter — it is the common contract every community vector adapter is expected to satisfy.
  • If your backend can isolate storage per user + dataset, register a dataset-database handler from the same register.py:
    Without a handler, your adapter can only be used with ENABLE_BACKEND_ACCESS_CONTROL=false.
  • Create a test or example script test_<engine_name>.py or example.py that you can use in your test workflow.
  • Create** a test workflow: .github/workflows/engine_name/test_<engine_name>.yml.
  • Add required dependencies to pyproject.toml optional dependencies.
  • Open a PR to verify that your new integration passes CI.

Additional Considerations

Error Handling

  • Implement proper error handling for connection failures, timeouts, and API errors.
  • Log meaningful error messages that help with debugging.
  • Handle graceful degradation when the vector database is unavailable.

Performance

  • Design for instance reuse: Cognee’s vector engine factory caches adapter instances keyed by their configuration parameters. Multiple calls with identical settings return the same adapter object. Design your adapter to be safe for reuse — avoid per-instance mutable state that cannot be safely shared across concurrent calls, and prefer lazy or thread-safe initialization patterns. When an entry is evicted (e.g. cache eviction or cache_clear), the factory calls your adapter’s close(). For capacity eviction the close is deferred until every leased reference to that instance is released, but the dataset-queue teardown and the idle reaper force-close immediately even while idle references are still held (holders transparently re-resolve to a fresh instance on next use) — so implement close() idempotently and safe to run while stale references remain; if it raises, the error is logged and swallowed rather than propagated to the caller.
  • Consider implementing connection pooling if your vector database supports it.
  • Never check out a second pooled connection while holding a session. If your adapter is pool-backed, resolve tables and metadata before opening the session that uses them — helpers like get_table() open their own connection, so calling one inside a session pins two connections per in-flight call and deadlocks a bounded pool once concurrency reaches its ceiling. Cognee’s own PGVectorAdapter follows this ordering in retrieve(), search(), and delete_data_points().
  • Add proper async/await patterns to avoid blocking operations.
  • Implement batch operations efficiently where possible.

Security

  • Never log sensitive information like API keys or connection strings.
  • Validate inputs to prevent injection attacks.
  • Follow your vector database’s security best practices.

Documentation

  • Add docstrings to all public methods.
  • Document any specific configuration requirements.
  • Include examples of how to use your vector database with cognee.
That’s all! This approach keeps cognee’s architecture flexible, allowing you to swap in any vector database provider easily. If you need more advanced functionality (e.g., custom indexes, filters, or advanced search capabilities), simply implement them in your adapter class following the same patterns.

Join the Conversation!

Have questions about creating custom tasks? Join our community to discuss implementation strategies and best practices!