Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

🐦 Vinkra

Vinkra Logo

Vector Incremental Nano Kit — Reconfigurated Automatically

“Vector DB that self-organizes. Auto-switch, auto-tune, auto-scale.”

Python Version PyPI CodeFactor Coverage Status Stability Tests License: MIT

[!WARNING] This project is currently in pre-alpha.


🤔 Vinkra? What's that?

Most vector databases force a trade-off: over-engineer for small datasets or hit a performance cliff as you scale. You're left tuning parameters by hand, managing indices, and hoping your hardware keeps up.

Vinkra eliminates the guesswork. It automatically switches from Exact Search (for 100% precision) to ANN (for massive scale with IVF-PQ) based on dataset size and runtime latency. Vinkra adapts its strategy to your hardware and data, whether on a mobile device or a server.

It uses a Power Law model (y = a * x^b) to predict search latency based on the number of vectors in the index. Initial calibration measures raw BLAS performance, then online tuning refines parameters with actual runtime measurements.

Feature Description
Incremental Inserts Add vectors anytime. Your index grows with your data, not against it.
📟 Hardware-Aware Auto-Switch Automatically switches to ANN when latency exceeds your threshold.
⚙️ Self-Tuning Engine Background reconfiguration adapts clusters as your data evolves.
🎯 Production-Ready Search Filtered searches, soft deletes, compact, dual-metric (Euclidean + cosine).
💾 Explicit Storage Disk or memory — you control where your data lives.

Unlike enterprise solutions (Milvus, Pinecone) that require complex Docker or cloud setup, Vinkra runs entirely local with no dependencies beyond pip install.


📦 Installation

First ensure that you have the necessary system dependencies installed.

  • Linux only: Required for building rii

    # Debian/Ubuntu
    sudo apt-get install python3-dev
    
    # RedHat/Fedora/CentOS
    sudo dnf install python3-devel -y
    
    # CentOS 7 and older
    sudo yum install python3-devel
    
  • Android/Termux:

    pkg install -y tur-repo
    pkg install python-scipy
    

The Quick & Easy Way

The simplest way to get started is with pip:

pip install vinkra

[!TIP] Termux (Android)

No Rust toolchain? Install pydantic-core pre-built wheels first, then retry:

pip install typing-extensions
pip install pydantic-core --index-url https://termux-user-repository.github.io/pypi/
pip install "pydantic>=2.12.4,<2.13"

The From-Source Way

Prefer building from source? You can clone and install manually for full control:

git clone https://github.com/speedyk-005/vinkra.git
cd vinkra
pip install -e .

✅ Proof It Works

Run the demo to see auto-switch in action:

# Install and run anywhere
curl -O https://raw.githubusercontent.com/speedyk-005/vinkra/main/demo_poc.py
python demo_poc.py

The demo uses:

  • switch_latency_ms=120 inside AnnConfig to trigger the switch sooner
  • dim=128
  • Batches of 10,000 vectors

The switch happens when latency exceeds switch_latency_ms.

Example output:

┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ Vectors ┃      Strategy      ┃ Avg Query (ms) ┃ Insert Time (s) ┃     Status     ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ 10,000  │    exact_search    │     32.486     │      0.806      │  Exact Search  │
│ 20,000  │    exact_search    │     79.690     │      0.729      │  Exact Search  │
│ 30,000  │    exact_search    │    107.419     │      0.720      │  Exact Search  │
│ 40,000  │    exact_search    │    188.063     │      0.771      │  ⚙ Building ANN │
│ 50,000  │ approximate_search │     0.000      │     10.051      │  ✓ ANN Active  │
│ 60,000  │ approximate_search │    155.239     │      1.323      │  ✓ ANN Active  │
└─────────┴────────────────────┴────────────────┴─────────────────┴────────────────┘

✓ ANN switch successfully triggered!

[!NOTE] Results vary by hardware and system load. Faster machines switch later, and running other programs will affect timing.


🚀 Usage

Initialization (VinkraDB API)

from vinkra import VinkraDB

# Create a database with 128-dimensional vectors
db = VinkraDB(dim=128, dir_path="./data")

# Or use volatile in-memory mode (omit dir_path)
# db = VinkraDB(dim=128)

# Full configuration capabilities
db = VinkraDB(
    dim=384,
    dir_path="./data",
    metric="euclidean",         # or "cosine" (default: euclidean)
    force_exact=False,          # Set to True to completely lock it out of ANN mode
    ann_config=None,            # Provide custom AnnConfig instance (default: auto-generated)
    embedding_callback=None,    # Optional function to generate vectors from raw content text
    overwrite=False,            # Blow away existing directory index if True
    verbose=False               # Enable internal runtime diagnostic logs
)

Context Manager (Recommended)

VinkraDB fully implements Python's context manager interface. Using a with block guarantees your in-flight buffers flush cleanly to disk and the underlying SQLite engine closes its connections safely without dangling file locks, even if your code raises unhandled exceptions.

from vinkra import VinkraDB

with VinkraDB(dim=384, dir_path="./data") as db:
    db.add([{"content": "Seamless storage context"}])

# The database saves and shuts down gracefully right here

AnnConfig (API)

For custom ANN tuning, configure AnnConfig and pass it to VinkraDB:

from vinkra import AnnConfig, VinkraDB

config = AnnConfig(
    num_subspaces=16,          # number of sub-vectors (default: 32)
    quantizer="pq",            # "pq" or "opq" (default: pq)
    codebook_size=128,         # centroids per subspace (default: 256)
    switch_latency_ms=150      # Runtime latency milestone to trigger ANN switch (default: 300)
    reconfig_threshold=100_000 # Inserts before reconfiguring the index on search performance (default: 100k)
)
db = VinkraDB(dim=384, dir_path="./data", ann_config=config)

# Print all available technical constraints and options:
AnnConfig.help()

Add (API)

Records accept the following:

  • content (required): text payload to track
  • embedding (required if no callback configured): list of floats or 1D/2D numpy array
  • id (optional): string representation of a valid UUIDv7
  • metadata (optional): dictionary containing scalar filtering targets

Without callback

db.add([
    {"content": "Hello world", "embedding": [0.1] * 384, "metadata": {"source": "doc1"}},
    {"content": "Another text", "embedding": [0.2] * 384}
])

With embedding callback

db = VinkraDB(dim=384, dir_path="./data", embedding_callback=my_embedding_fn)

# Omit 'embedding' keys; generated entirely under the hood
db.add([
    {"content": "Hello world", "metadata": {"source": "doc1"}},
    {"content": "Another text"},
])

Search (API)

Results include:

  • id: vector ID
  • content: text content
  • distance: similarity score (lower is closer for euclidean)
  • metadata: key-value pairs
  • embedding: (only if include_vectors=True)

Without filters

results = db.search(query_vec=[0.1] * 384, top_k=5)

# Include source embeddings in output mapping
results = db.search(query_vec=[0.1] * 384, include_vectors=True)

With filters

Filters are checked before similarity metrics hit vectors. Operators support ==, !=, >, <, >=, <= matching against string, numeric, and boolean literals.

results = db.search(
    query_vec=[0.1] * 384,
    top_k=10,
    filters=["source == 'doc1'", "score >= 50", "new == True"]
)

Persistence & Index Maintenance

Save

If you manage resources manually instead of using the context manager, write the index to disk:

db.save()

Close

Saves state to disk and closes the SQLite connection cleanly. Registered via atexit, so it runs automatically on normal interpreter exit.

db.close()

Soft deletion (API)

Marks vectors as deleted without rebuilding the index:

db.soft_delete(["0192a5b4-7f3c-7d6e-9a1b-2c3d4e5f6a7b"])

Compaction (API)

Removes soft-deleted vectors and rebuilds the index:

db.compact()

[!WARNING] Compaction on an active approximate_search index can block queries for 20-200+ seconds while it rebuilds the codebook. Run during maintenance windows.

Stats (API)

# Check which search strategy is currently active
db.strategy  # "exact_search" or "approximate_search"

# Whether the ANN index is currently being built in the background
db.is_ann_building

# Count vectors
active = db.count()      # same as db.count("active") (default)
deleted = db.count("deleted")
total = db.count("all")

stats = db.stats()
# {
#     "version": "...",
#     "dim": 384,
#     "metric": "euclidean",
#     "strategy": "exact_search",
#     "is_ann_building": false,
#     "last_saved_at": "...",
#     "last_deleted_at": "...",
#     "active_count": 1000,
#     "deleted_count": 5
# }

🗺 Features & Roadmap

  • Incremental Inserts
  • Hardware-Aware Auto-Switch
  • Soft deletes + compact
  • Save/Load + Context Manager
  • Filter DSL
    • basic filters: Quick Comparison
    • Complex Filters: Content Matching, Null Checks, date/time literals, ...
  • Recovery: recover soft-deleted vectors
  • REST API: HTTP API for remote vector operations
  • Integrations: LangChain, LlamaIndex, and other integrations

🔧 Core Dependencies

riinanopqscipynumpySQLite


🤝 Contributing

Bug fixes, features, docs — all welcome. Check out CONTRIBUTING.md for the full details.


📜 License

Check out the LICENSE file for all the details.

MIT License — use freely, modify, and credit accordingly.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vinkra-0.2.0a1.tar.gz (42.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vinkra-0.2.0a1-py3-none-any.whl (36.7 kB view details)

Uploaded Python 3

File details

Details for the file vinkra-0.2.0a1.tar.gz.

File metadata

  • Download URL: vinkra-0.2.0a1.tar.gz
  • Upload date:
  • Size: 42.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for vinkra-0.2.0a1.tar.gz
Algorithm Hash digest
SHA256 6900234fc118f8e5c58fbda5df3683270ec08d343bbc742e6ddd7ccdea756dda
MD5 c923816e0b2a08fa034934c759c6d44d
BLAKE2b-256 c74bca2b593f1d963dc8c1fbd11b1a8aa6676b7cc3608379e8e1254a878c0e50

See more details on using hashes here.

File details

Details for the file vinkra-0.2.0a1-py3-none-any.whl.

File metadata

  • Download URL: vinkra-0.2.0a1-py3-none-any.whl
  • Upload date:
  • Size: 36.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for vinkra-0.2.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 f480641109e70dfa0682477578f338881cd1e5353b25e84758dbd76f64e23fae
MD5 2ed6b5194857b64438956cec3325807f
BLAKE2b-256 8916e2239893b0ff3a8a537dcd3e7bb9eeefe55b68049787dc05d9e4a5812146

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0a1 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page