Skip to main content

Customer-owned face search with Supabase pgvector

Use this pattern when you want scalable face search, but you do not want deepface.dev to host your face database. The flow is:
  1. Send an image to POST /represent.
  2. Store the returned embedding in your own Supabase pgvector table.
  3. For a new query image, call POST /represent again.
  4. Search your own Supabase table for the closest embeddings.
deepface.dev still processes the images and embeddings you submit so it can return API results. The difference is that your enrolled face database, person IDs, labels, and search index stay in your Supabase project. Open-Source DeepFace now includes database-backed register, search, and build_index functions for stateless face recognition pipelines. In that model, register stores embeddings in a backend database and search queries that database. deepface.dev does not expose hosted /register or /search endpoints today. Instead, use POST /represent for the compute step and keep registration, storage, indexing, and search in your own database. References:

Create the Supabase table

This example uses Facenet, which returns 128-dimensional embeddings. If you choose another model, confirm its embedding length and change vector(128) to match.
For production, add RLS policies that match your app’s account model. If you use a service-role key in a backend job, keep it server-side only and never expose it in browser code.

Query nearest faces

Use cosine distance (<=>) to match deepface.dev’s default cosine comparison metric. Smaller distances are closer matches. Create a database function so Postgres can order by vector distance directly:

JavaScript example

Install the Supabase client in your backend project:
Then generate, store, and search embeddings from a server-side script or API route:

When to use this pattern

Use customer-owned search when you need:
  • face search across many enrolled identities;
  • control over where biometric data and metadata are stored;
  • your own RLS, audit, retention, and deletion rules;
  • database-level ANN search as your dataset grows.
For small request-time comparisons, POST /compare can still compare one image or vector against vectors you include in the request. For larger datasets, keep the database search in Supabase and use deepface.dev only for embedding generation.