New in Public Preview – PostgreSQL Support and TiDB Cloud Filesystem

Most RAG stacks end up running two databases: one for the application’s transactional data, and a separate vector database for embeddings. That split adds a sync pipeline, a second system to operate, and a second place for data to drift out of consistency with the first. This guide walks through connecting LangChain to TiDB, where both the transactional data and the vector index live in the same cluster, using code that runs against LangChain’s actual current interfaces.

What is LangChain integration with TiDB?

LangChain integration with TiDB means wiring LangChain’s document loaders, embedding models, and vector store interface to a TiDB cluster, so LangChain can write embeddings to TiDB and query them back with vector search. Instead of standing up a dedicated vector database next to your existing store, TiDB serves both the vector index and the application’s row and analytical data from one cluster. That matters most for RAG and agentic applications, where the application data and the vector index need to stay in sync without a separate ETL step.

Concretely, the integration is a single LangChain vector store class, TiDBVectorStore, that speaks TiDB’s MySQL-compatible protocol under the hood. You use it the same way you’d use any other LangChain vector store: build it from a list of documents, then query it with a similarity search. The rest of this guide covers each step: installing dependencies, connecting to a TiDB cluster, loading and embedding documents, and querying the result.

Prerequisites and setup

System requirements

Before integrating LangChain with the TiDB database, confirm your system meets these requirements:

  • Operating system: Windows, macOS, or Linux
  • Python version: LangChain requires Python 3.8 or higher
  • Hardware: standard hardware works; for large datasets and complex models, allocate more CPU, memory, and storage

Install the required packages

Install the required Python packages with pip:

pip install langchain langchain-community langchain-openai pymysql tidb-vector

For an interactive development environment, also install Jupyter Notebook:

pip install notebook

You’ll also need a TiDB cluster. TiDB Cloud Starter is free to start with; TiDB Self-Managed works too, on version 8.4 or later. Either way, get your connection string from the TiDB Cloud console (or your self-managed deployment’s connection details) before continuing.

Store your connection string and API key as environment variables rather than hardcoding them:

import getpass
import os

# Prompt for and set the TiDB connection string and OpenAI API key
tidb_connection_string = getpass.getpass("TiDB Connection String:")
os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")

Load, split, and embed your documents

Open your project file (a Jupyter Notebook or a Python script) and import the components you’ll need:

from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import TiDBVectorStore
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter

Load a document and split it into chunks:

loader = TextLoader("path/to/your/document.txt")
documents = loader.load()

text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

Next, generate embeddings for those chunks with OpenAI’s embedding model:

embeddings = OpenAIEmbeddings()

This embeddings object is what you’ll pass to TiDB’s vector store in the next step. It’s the same object LangChain uses internally to embed both your stored documents and any query you run against them later.

Store and query vectors with TiDBVectorStore

This is the step where the live version of this guide went wrong: it called methods like vector_store.add_vector() and embeddings.embed(), neither of which exists in LangChain’s actual interfaces. Here’s the real pattern, taken directly from TiDB’s own LangChain integration docs.

Build the vector store from your split documents:

vector_store = TiDBVectorStore.from_documents(
    documents=docs,
    embedding=embeddings,
    table_name="embedded_documents",
    connection_string=tidb_connection_string,
    distance_strategy="cosine",  # default; "l2" is also supported
)

This single call creates a table in TiDB optimized for vector search and loads your embedded chunks into it. To query it, use similarity_search_with_relevance_scores, which returns the top-k most relevant documents along with a relevance score:

query = "your search query text"
results = vector_store.similarity_search_with_relevance_scores(query, k=2)

for doc, score in results:


    print(f"Score: {score}")
    print(doc.page_content)

Higher scores mean a closer match. No separate vector database, no custom add_vector method to maintain: TiDBVectorStore is a standard LangChain vector store, so it works with any LangChain chain or agent that expects one.

How TiDB’s HTAP architecture solves the RAG data-silo problem

The two-database problem raised in the intro comes from a structural mismatch: most databases are built for either transactional workloads or analytical ones, not both, so teams end up running a separate vector store to cover the gap. TiDB is built as an HTAP (hybrid transactional/analytical processing) system specifically to avoid that split. TiKV handles row-level transactional reads and writes, while TiFlash runs as a columnar replica for analytical and vector queries, kept in sync with TiKV automatically. A LangChain application reading and writing through TiDB gets its transactional data and its vector index from the same cluster, with no CDC pipeline connecting two separate systems.

That matters concretely for a RAG pipeline: when your application writes a new record, the embedding you generate from it can land in the same cluster as the record itself, queryable through the same connection string you already configured. There’s one system to monitor, one system to back up, and one consistency model to reason about.

Compare that to the common alternative: an application database plus a dedicated vector database, connected by a change-data-capture job that copies new or updated rows over to be re-embedded. That job is one more thing to build, one more thing to monitor for lag, and one more place where a failed run leaves your vector index out of date with the data it’s supposed to represent. Running both workloads against TiKV and TiFlash in the same TiDB cluster removes that job entirely, at the cost of tying your vector storage to your primary database’s availability and scaling characteristics, which is worth weighing if your vector workload’s scaling needs diverge sharply from your transactional workload’s.

Testing your integration

Test the pieces of your integration separately before relying on them together. Start with the basics: confirm that document loading and text splitting behave as expected.

def test_document_loading():
    loader = TextLoader("path/to/test/document.txt")
    documents = loader.load()
    assert len(documents) > 0, "Document loading failed"

def test_text_splitting():
    splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
    chunks = splitter.split_text("Sample text to split.")
    assert len(chunks) > 0, "Text splitting failed"

Then confirm the round trip through TiDB itself: store a document and search for it.

def test_vector_store_roundtrip():
    results = vector_store.similarity_search_with_relevance_scores("test query", k=1)
    assert len(results) > 0, "Vector store returned no results"

Run these with pytest, and wire them into your CI pipeline so a broken connection string or a schema change surfaces before it reaches production.

FAQ

What package do I need to connect LangChain to TiDB?

  • langchain-community provides the TiDBVectorStore class
  • tidb-vector handles the underlying vector operations
  • pymysql connects to TiDB’s MySQL-compatible protocol
  • langchain-openai is needed if you’re using OpenAI’s embedding models

Does TiDB support both transactional and vector workloads in the same cluster?

  • Yes. TiKV handles transactional reads and writes
  • TiFlash runs as a columnar replica for analytical and vector queries
  • Both stay in sync automatically, without a separate CDC pipeline

Which distance metric does TiDB’s vector store use by default?

  • Cosine distance is the default strategy
  • Euclidean distance (l2) is also supported, set via the distance_strategy parameter

Can I use TiDB Cloud’s free tier for this integration?

  • Yes, TiDB Cloud Starter is free to start with and works for this guide
  • TiDB Self-Managed v8.4 or later also supports vector search, if you’d rather self-host

Start building with a working integration

LangChain and TiDB connect through a standard vector store interface: TiDBVectorStore.from_documents() to write, similarity_search_with_relevance_scores() to query, and no custom methods to maintain in between. The part worth remembering is architectural, not just the API: TiDB keeps your transactional data and your vector index in one cluster, so your RAG pipeline doesn’t need a second database to stay in sync.

Sign up for TiDB Cloud Starter to try this integration against a live cluster, or read TiDB’s LangChain integration docs for the full walkthrough this guide is based on. For a deeper look at building agentic applications on TiDB, see building agentic AI on TiDB.


Last updated October 12, 2026

💬 Let’s Build Better Experiences — Together

Join our Discord to ask questions, share wins, and shape what’s next.

Join Now