Skip to content

TurboVec on Snowpark Container Services (SPCS) #95

Description

@navnitshukla

GitHub Issue: TurboVec on Snowpark Container Services (SPCS)

Title

Deployment: TurboVec on Snowpark Container Services (Snowflake) — tested at 100K with perfect recall

Body

What

I deployed TurboVec as a containerized vector search service on Snowpark Container Services (SPCS) — Snowflake's container runtime. This enables running TurboVec inside a cloud data platform where data never leaves the governance boundary.

Why this matters

  • Enterprises using Snowflake for RAG currently have two options: brute-force VECTOR_COSINE_SIMILARITY (exact but slow) or Cortex Search (managed, opinionated). TurboVec on SPCS gives them a third: fast quantized search with bring-your-own-embeddings.
  • Data stays inside Snowflake's governance perimeter — no external vector DB egress.
  • Multi-tenant filtered search via allowlists maps perfectly to enterprise tenant isolation patterns.

What I built

A FastAPI service wrapping TurboVec's IdMapIndex with:

  • /add — ingest vectors with optional tenant assignment
  • /search — query with optional tenant_id for kernel-level filtering
  • /sf/add, /sf/search — wrapper endpoints handling SPCS service function data format ({"data": [[row_idx, payload]]})
  • /health — readiness probe
  • /telemetry — per-query cost attribution records

Docker image: python:3.11-slim + turbovec==0.7.0 + fastapi + uvicorn (~180MB)
Compute: CPU_X64_S (2 vCPU, 4GB RAM) — no GPU needed

Benchmark results (verified on Snowflake account)

Dataset: Qdrant/dbpedia-entities-openai3-text-embedding-3-large-1536-1M (public, 100K vectors, d=1536)

Method Recall@5 Latency Memory
TurboVec 4-bit (SPCS) 1.000 13ms 73.6 MB
Snowflake Native FP32 1.000 ~500ms 585.9 MB

TurboVec returns identical top-5 results to exact brute-force search with 8x compression and ~40x lower latency.

Key learnings

  1. SPCS service functions send POST with {"data": [[row_idx, payload]]} format — need wrapper endpoints to unwrap this before passing to Pydantic models.
  2. Payload size limit: ~100 vectors per service function call at d=1536. Batch loading via a SQL stored procedure works well.
  3. snow spcs image-registry login is required for Docker push when MFA is enabled (direct docker login fails).
  4. Filtered search is faster than unfiltered on SPCS — the kernel skips blocks with no allowed slots, reducing effective scan volume.

Artifacts

Contribution interest

I'd be happy to contribute:

  • A docs/deployment/spcs.md guide for the turbovec repo
  • A Snowflake integration module (turbovec[snowflake]) wrapping the SPCS service pattern
  • Additional benchmarks at scale (I have 100K loaded on a live SPCS instance)

Can I get contributor access? Happy to follow the one-logical-change-per-PR convention and reference this issue with Closes #N.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions