ポイント
- KDB.AI now runs as a native service inside KDB-X, bringing vector search and time-series analytics into a single platform.
- By eliminating the need for a separate vector database, teams can reduce data movement, operational complexity, and infrastructure overhead.
- Developers can access KDB.AI through Python, REST, or q APIs, enabling seamless integration with existing KDB-X workflows.
- The platform supports multiple vector indexing options, including in-memory, on-disk, and GPU-accelerated indexes for different scale and performance requirements.
- Combining embeddings and time-series data in one engine simplifies the development of RAG, recommendation, anomaly detection, and semantic search applications.
For a while now, building an AI retrieval system on top of time-series data meant running two databases. Your market data, your sensor history, your event logs sat in kdb+. Your embeddings sat in a separate vector store you stood up, secured, and scaled on its own. Every query that needed both, “find me the documents semantically close to this one, but only from the trading sessions where volatility spiked,” had to cross the boundary between those two systems.
That boundary is where the time goes. You write glue to move vectors across, you keep two sets of credentials, you reconcile two scaling stories, and your metadata filters live in one place while the vectors they filter live in another.
So here’s the hook: the full functionality of KDB.AI, the vector database that started life as a standalone product, now runs as a service directly inside KDB-X. Same vector search, same hybrid retrieval, same temporal similarity, but sitting in the same engine as your time-series data. Let’s walk through what that means and how to stand it up.
Why does using separate vector databases and time-series databases create complexity?
When your vector database and your time-series database are separate products, you pay for the separation in three specific ways:
- Data movement. Embeddings and the structured data they describe live in different stores, so you build and maintain pipelines to keep them in sync. That glue is code you have to own.
- Two operational surfaces. Two things to deploy, monitor, secure, and scale, each with its own failure modes and its own upgrade cadence.
- Split context. The metadata you want to filter on often already exists in KDB-X. When the vector store is elsewhere, you either duplicate that metadata or you do filtering in application code after the fact.
None of these are exotic problems. They’re the steady, low-grade tax you pay for stitching two systems together, and it adds up.
What changed: KDB.AI as a KDB-X service
KDB.AI is now a high-performance vector database service built on top of KDB-X. It extends the real-time time-series engine with semantic and similarity search, which means you can build RAG pipelines, recommendation systems, and anomaly detection workflows inside one unified platform rather than across two.
The practical shape of that is four things:
One engine for vectors and time-series. The vector workloads execute against the same historical database that holds your structured data.
Three ways in, including q. A Python client, a REST API, and a q API that speaks IPC directly from q processes inside KDB-X.
The full index lineup. In-memory, on-disk, and GPU-resident indexes, so you’re not forced to fit everything in RAM.
The full search surface. Dense similarity, hybrid dense-plus-sparse, temporal similarity, dynamic time warping, and reranking, all carried over from the standalone product.
The headline isn’t any single one of those. It’s that none of them require a second database anymore.
The Architecture: How does KDB.AI work inside KDB-X?
The service is three layers, deployed as configurable multi-instance processes and reached by clients over REST or IPC.
The REST Services tier runs one or more parallel instances and handles incoming HTTP requests. The Gateway is the central routing layer over IPC; it coordinates with the REST tier and dispatches work to the Workers. The Workers tier, also one to N instances, executes the queries and vector operations against the HDB and reads and writes the persisted data.
The detail that matters for production is that the REST Services and Worker tiers scale independently. You can add front-end capacity for an ingestion spike without touching query-side resources, and the other way around. That separation of client-facing I/O from query execution is the thing a service buys you that an in-process library can’t.
Step 1: Start the server
KDB.AI Server ships as a Docker image. Once you’ve installed the free KDB-X Community Edition, worked through the prerequisites, and pulled the container image, you run the kdbai-db image:
export KDB_LICENSE_B64=$(base64 -w0 $HOME/.kx/kc.lic)
docker run -it \
-p 8081:8081 \
-p 8082:8082 \
-e KDB_LICENSE_B64=$KDB_LICENSE_B64 \
-v "$PWD/vdbdata":/tmp/kx/data \
portal.dl.kx.com/kdbai-db
Two ports matter here: 8081 for REST and 8082 for IPC. Both are container ports that must stay fixed; you can map them to whatever host ports you like. The KDB-X Community Edition license limits KDB.AI Server to a single worker process and a single REST service. Commercial editions support multiple workers and REST services for horizontal scaling within a deployment. See the licensing FAQ for more information.
Step 2: Connect
The Python client installs from PyPI and supports Python 3.9 through 3.13:
pip install kdbai-client
Connecting is where you choose your protocol. Open a qIPC session on 8082, the default if you omit mode, or a REST session on 8081:
import kdbai_client as kdbai
# qIPC session
session = kdbai.Session(host='localhost', port=8082, mode='qipc')
# or REST session
# session = kdbai.Session(endpoint='http://localhost:8081', mode='rest')
database = session.database('default')
The default database is always there; you don’t have to create one to start working.
Step 3: Define a schema and an index
In KDB.AI, the schema and the indexes are two separate lists. The schema names your columns and their types; the index points at a vector column and configures how it’s searched.
schema = [
{"name": "id", "type": "str"},
{"name": "vectors", "type": "float32s"},
]
index = [
{
"name": "flat_index",
"type": "flat",
"column": "vectors",
"params": {"dims": 8, "metric": "L2"},
}
]
table = database.create_table(table="quickstart", schema=schema, indexes=index)
dims is fixed at table creation and has to match whatever embedding model you’re using. metric is your distance function: L2 for Euclidean, CS for cosine, IP for inner product. Keeping the index config out of the schema and in its own list is the pattern people most often get backwards, so it’s worth saying plainly: two lists, not one.
Step 4: Insert and search
Insert is a Pandas DataFrame whose columns line up with the schema:
import numpy as np
import pandas as pd
ids = ['h', 'e', 'l', 'l', 'o']
vectors = np.random.rand(40).astype(np.float32).reshape(5, 8)
df = pd.DataFrame({"id": ids, "vectors": list(vectors)})
table.insert(df)
And a similarity search is a dict keyed by the index name, not the column name:
query_vector = np.random.rand(8).astype(np.float32)
results = table.search(vectors={"flat_index": [query_vector.tolist()]}, n=3)
That {“flat_index”: […]} shape trips people up the first time, so notice it: the key is the name you gave the index in Step 3.
Step 5: Drive it from q
Here’s the part that’s genuinely new for KDB-X users, and the clearest expression of why putting KDB.AI in the same engine matters. A q process that already holds your data can drive the vector database over IPC, in the same session, with no Python in the loop.
The q API uses the standard kdb+ idiom: open a handle to the gateway, then call named functions through it.
gw set hopen 8082;
gw(`createDatabase; enlist[`database]!enlist `myDatabaseName)
The function vocabulary is the full set you’d expect: createDatabase, getDatabase, listDatabases, and deleteDatabase for databases; create, get, list, and delete for tables; and insert, train, query, search, update, and delete for data, plus index and access-control management. If your time-series already lives in KDB-X/q, your vectors are now one hopen away.
Picking the right index
The index lineup is where the unified engine earns its keep, because different workloads want different trade-offs and they’re all available in the one place.
- [‘flat’] / [‘qFlat’]: exact search. [‘flat’] is in-memory; [‘qFlat’] is a q native version of the flat index, it is on-disk and removes the memory ceiling.
- [‘hnsw’] / [‘qHnsw’]: high-accuracy approximate nearest-neighbor at scale. [‘qHnsw’] is the q native variant that supports both in-memory and on-disk.
- [‘ivf’] / [‘ivfpq’]: very large datasets where moderate recall is acceptable, with [‘ivfpq’] adding compression.
- [‘cagra’]: a GPU-resident index, built through the NVIDIA cuVS integration.
There’s one trade-off worth pulling out, because it decides whether an index suits live data. Row-level create, update, and delete is supported on flat, qFlat, hnsw, and qHnsw. It is not supported on ivf and ivfpq, which require a training step before they serve queries and aren’t suited to real-time ingest without periodic re-indexing. If you’re feeding a dynamic embedding set that mutates constantly, the hnsw family is your path; the ivf family pushes you back toward a rebuild cycle.
Considerations
The honest caveats, so you walk in with eyes open:
- Dimensionality is fixed per table. Set at creation, tied to your embedding model. Changing it means dropping and recreating the table.
- Similarity search is single-table. There are no cross-table joins inside a vector query; you combine results from multiple tables in application code or in KDB-X post-processing.
- Partitioning is single-column. You can partition a table on one metadata column, not several.
- IVF/IVFPQ need training and don’t do row-level edits. Covered above, but it’s the constraint most likely to bite a real-time design.
Wrapping up
It’s tempting to read this as “KDB.AI got a new deployment target,” but I think that undersells it. The interesting thing isn’t where the vector database runs. It’s that the wall between vector search and time-series analytics, two capabilities that grew up as separate database categories, isn’t there anymore for KX users. The embeddings and the structured history they describe sit in one engine, reachable from one q session, scaled as one system.
That collapses the part of these projects that was never the interesting part: the plumbing between two stores. What’s left is the actual retrieval problem, which is where you wanted to spend your time in the first place.
If you work with KDB-X and you’ve been running a separate vector store alongside it, this is the version where you get to stop doing that.
Get started
- Deploy and configure: KDB.AI Server Setup
- Run your first search: Quickstart
- Worked scenarios: RAG, anomaly detection, recommendation: kdbai-samples
- API references: Python, q, REST
- Connect it to your stack: Integrations for LangChain, LlamaIndex, OpenAI, and more
