Was this page helpful?
Vector Search with Alternator¶
Alternator is ScyllaDB’s DynamoDB-compatible API. In addition to the CQL interface, you can use Vector Search through Alternator, which lets DynamoDB applications store embeddings, build a vector index, and run Approximate Nearest Neighbor (ANN) similarity queries without switching to CQL.
This page explains how Vector Search works through Alternator, which features are available compared to CQL, and how to run a complete example in Python.
Note
Vector Search is a ScyllaDB feature. It is not available on Amazon DynamoDB itself.
Version Support¶
Vector Search through Alternator is available on clusters running ScyllaDB 2026.2.x, where embeddings are stored as a list of numbers.
In versions later than 2026.2, a more compact native vector type is available for Alternator, along with a configurable similarity function and similarity scores.
This page applies to the 2026.2.x series.
Feature Availability in Alternator¶
The core Vector Search workflow — storing embeddings, building a vector index, and running ANN queries — is available through Alternator. Some capabilities that exist in CQL are not yet available through Alternator in the 2026.2.x series, as summarized below.
Capability |
CQL |
Alternator (2026.2.x) |
|---|---|---|
Store embedding vectors |
Yes ( |
Yes (attribute holding a list of numbers) |
Create a vector index |
Yes |
Yes |
ANN similarity search (top-k) |
Yes |
Yes |
Configurable similarity function ( |
Yes |
No — the default (cosine) function is always used |
Retrieve similarity scores |
Yes |
No |
Filtering by metadata (global and local indexes) |
Yes |
No |
Tune HNSW parameters ( |
Yes |
No |
Quantization and rescoring |
Yes |
No |
Return indexed non-key attributes directly from the query |
Yes |
No — the index projects only the key; read the full item separately |
Caution
In the 2026.2.x series, a vector query through Alternator always uses the
default similarity function and does not return similarity scores. Requests
that set a SimilarityFunction or ReturnScores are accepted but have
no effect. Metadata filtering (a KeyConditionExpression combined with a
vector search) is not supported and is rejected.
Prerequisites¶
A cluster running ScyllaDB 2026.2.0 or later with both Vector Search and the Alternator (DynamoDB) API enabled. See Vector Search Deployments.
Python 3.9 or later.
The alternator-client load-balancing driver, which wraps
boto3and adds ScyllaDB node discovery.Note
Vector Search support is currently available on the
alternator-clientmainbranch. Install it directly from the repository:pip install "alternator-client @ git+https://github.com/scylladb/alternator-client-python.git@main"
Connecting to the Cluster¶
Alternator exposes a DynamoDB-compatible endpoint (port 8000 by default).
Create a Config with your node addresses and open an AlternatorResource,
which provides the table-oriented DynamoDB resource interface:
from alternator import Auth, Config, AlternatorResource
config = Config(
seed_hosts=["node-0.your-cluster.cloud.scylladb.com"],
port=8000,
scheme="https",
)
auth = Auth.static_credentials(
"YOUR_ALTERNATOR_ACCESS_KEY",
"YOUR_ALTERNATOR_SECRET_KEY",
)
with AlternatorResource(config, auth=auth) as resource:
client = resource.meta.client
# ... create a table, insert data, build an index, and query ...
Note
To try Vector Search against a local single-node deployment (for example, the ScyllaDB Alternator + Vector Store Docker Compose setup in the vector-store repository), connect over plain HTTP without authentication:
config = Config(seed_hosts=["127.0.0.1"], port=8000)
with AlternatorResource(config) as resource:
client = resource.meta.client
The rest of this page assumes an open resource and its client, as shown
above.
Workflow¶
The Alternator workflow mirrors the CQL workflow:
Create a table.
Insert items whose vector attribute is a list of numbers.
Create a vector index on the vector attribute.
Run a similarity search with
VectorSearchto find the nearest items.
The examples below use the same data as the Quick Start Guide so you can compare the CQL and Alternator versions side by side.
Create a Table¶
In CQL, the vector is a typed column. In Alternator, ScyllaDB (like DynamoDB) is schemaless apart from the key attributes, so you define only the primary key when creating the table; the vector is supplied later as an item attribute.
CREATE KEYSPACE IF NOT EXISTS myapp;
CREATE TABLE IF NOT EXISTS myapp.comments (
id text PRIMARY KEY,
commenter text,
comment text,
comment_vector vector<float, 5>
);
resource.create_table(
TableName="comments",
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[
{"AttributeName": "id", "AttributeType": "S"}
],
BillingMode="PAY_PER_REQUEST",
)
table = resource.Table("comments")
table.wait_until_exists()
Insert Vector Data¶
Insert the embedding as a list of numeric values matching the dimension you will use for the index.
Note
The DynamoDB resource interface represents numbers as Decimal. Convert
each vector element with Decimal(str(x)) so the values are stored
exactly.
INSERT INTO myapp.comments (id, commenter, comment, comment_vector)
VALUES ('1', 'Alice', 'I like vector search in ScyllaDB.',
[0.12, 0.34, 0.56, 0.78, 0.91]);
INSERT INTO myapp.comments (id, commenter, comment, comment_vector)
VALUES ('2', 'Bob', 'I like ScyllaDB!',
[0.11, 0.35, 0.55, 0.77, 0.92]);
INSERT INTO myapp.comments (id, commenter, comment, comment_vector)
VALUES ('3', 'Charlie', 'Can somebody recommend a good restaurant in Paris?',
[0.55, 0.08, 0.44, 0.19, 0.77]);
INSERT INTO myapp.comments (id, commenter, comment, comment_vector)
VALUES ('4', 'Diana', 'Vector databases are the future',
[0.12, 0.33, 0.57, 0.79, 0.90]);
INSERT INTO myapp.comments (id, commenter, comment, comment_vector)
VALUES ('5', 'Eve', 'Testing similarity search queries in ScyllaDB',
[0.13, 0.36, 0.59, 0.76, 0.88]);
from decimal import Decimal
comments = [
("1", "Alice", "I like vector search in ScyllaDB.",
[0.12, 0.34, 0.56, 0.78, 0.91]),
("2", "Bob", "I like ScyllaDB!",
[0.11, 0.35, 0.55, 0.77, 0.92]),
("3", "Charlie", "Can somebody recommend a good restaurant in Paris?",
[0.55, 0.08, 0.44, 0.19, 0.77]),
("4", "Diana", "Vector databases are the future",
[0.12, 0.33, 0.57, 0.79, 0.90]),
("5", "Eve", "Testing similarity search queries in ScyllaDB",
[0.13, 0.36, 0.59, 0.76, 0.88]),
]
for cid, commenter, comment, vector in comments:
table.put_item(
Item={
"id": cid,
"commenter": commenter,
"comment": comment,
"comment_vector": [Decimal(str(x)) for x in vector],
}
)
Create a Vector Index¶
Create a vector index over the vector attribute to enable ANN queries. In
Alternator, add the index with an UpdateTable call, specifying the vector
attribute name and its dimension.
CREATE CUSTOM INDEX IF NOT EXISTS comment_ann_index
ON myapp.comments(comment_vector)
USING 'vector_index';
client.update_table(
TableName="comments",
VectorIndexUpdates=[
{
"Create": {
"IndexName": "comment_ann_index",
"VectorAttribute": {
"AttributeName": "comment_vector",
"Dimensions": 5,
},
}
}
],
)
You can also create the index at table-creation time by passing a
VectorIndexes list to create_table.
The vector index builds asynchronously. Wait until it becomes ACTIVE before
querying so that all existing rows are indexed:
The index is populated in the background. Newly inserted vectors are typically searchable within about a second. See Write-to-Query Latency.
import time
while True:
indexes = client.describe_table(TableName="comments")["Table"].get(
"VectorIndexes", []
)
if indexes and indexes[0]["IndexStatus"] == "ACTIVE":
break
time.sleep(1)
Run a Similarity Search¶
Query the index with a vector to retrieve the most similar items. In
Alternator, pass the query vector in the VectorSearch parameter and use
Limit to set the number of nearest neighbors (k) to return.
Caution
In the 2026.2.x series, the Alternator vector index projects only the key
attributes. The query returns the matching keys; read each full item
separately (for example, with get_item) to retrieve its other
attributes.
SELECT commenter, comment
FROM myapp.comments
ORDER BY comment_vector ANN OF [0.12, 0.34, 0.56, 0.78, 0.91]
LIMIT 3;
from decimal import Decimal
query_vector = [Decimal(str(x)) for x in (0.12, 0.34, 0.56, 0.78, 0.91)]
response = table.query(
IndexName="comment_ann_index",
VectorSearch={"QueryVector": query_vector},
Limit=3,
)
# The index projects only the key, so read the full item for each match.
for match in response["Items"]:
item = table.get_item(Key={"id": match["id"]})["Item"]
print(f"{item['commenter']}: {item['comment']}")
Because the query vector is identical to Alice’s, her comment is the closest match, followed by the next two most similar comments:
Alice: I like vector search in ScyllaDB.
Diana: Vector databases are the future
Bob: I like ScyllaDB!
Complete Example¶
A complete, runnable version of this example — including the local Docker Compose setup for ScyllaDB Alternator and Vector Store — is available in the vector-store repository.
Key Differences from CQL¶
When moving between the CQL and Alternator versions of Vector Search, keep the following differences in mind:
Vector storage — CQL uses the typed
vector<float, N>column, while Alternator stores the embedding as a list of numbers in an item attribute. The index dimension must match the length of the stored vectors.Index projection — In 2026.2.x, the Alternator vector index projects only the key attributes. Retrieve non-key attributes by reading the full item after the query, rather than selecting them directly as you would in CQL.
Similarity function and scores — Choosing a similarity function and returning similarity scores are CQL-only in 2026.2.x. Alternator uses the default (cosine) function and does not return scores.
Filtering — Combining a similarity search with metadata constraints (filtering) is CQL-only in 2026.2.x.
Index tuning and quantization — HNSW tuning parameters and quantization are configured through CQL index options and are not exposed through Alternator in 2026.2.x.
What’s Next¶
Quick Start Guide — the CQL walkthrough this page mirrors.
Reference — CQL syntax and the Alternator API operations for Vector Search.