Using vector indexes in DynamoDB
Vector indexes are a type of index in Amazon DynamoDB that enable similarity search on vector
embeddings stored in your table items. Unlike global secondary indexes and local secondary indexes, which support exact-match
and range queries using Query and Scan operations, vector indexes
use approximate nearest neighbor (ANN) search to find items whose vectors are most similar
to a query vector that you provide. You perform these similarity searches by calling the
SearchVectors API, which returns the most similar items ranked by a
similarity score.
With vector indexes, you can store vector embeddings alongside your operational data in DynamoDB and perform similarity searches without needing a separate vector database. This eliminates the need for complex data replication pipelines between DynamoDB and external vector stores.
Vector indexes are managed through the same CreateTable and
UpdateTable APIs that you already use, with the
VectorIndexes parameter (for CreateTable) and the
VectorIndexUpdates parameter (for UpdateTable).
Topics
Use cases for vector indexes
Vector indexes support a variety of use cases that involve finding similar items based on vector representations:
-
Semantic search – Build search engines that understand the meaning of queries rather than matching keywords. Store text embeddings generated by machine learning models and find semantically similar content.
-
Retrieval Augmented Generation (RAG) – Connect large language models (LLMs) with relevant knowledge bases. Store document embeddings in DynamoDB and retrieve the most relevant context for LLM prompts.
-
Recommendation systems – Find similar products, content, or users based on vector representations of their features or behavior.
-
AI agent memory – Store conversation embeddings to maintain context between sessions and improve AI agent performance.
-
Anomaly and fraud detection – Compare new events against embeddings of known-normal behavior to flag outliers, such as unusual transactions or fraudulent activity.
Comparing vector indexes with secondary indexes
The following table compares vector indexes with global secondary indexes and local secondary indexes.
| Feature | Vector index | Global secondary index | Local secondary index |
|---|---|---|---|
| Query type | Similarity search | Exact match and range | Exact match and range |
| Read API | SearchVectors |
Query, Scan |
Query, Scan |
| Schema | Vector attribute, plus optional SearchSchema (partition key, inline filters) | Partition key(s) and optional sort key(s) | Same partition key, different sort key |
| Maximum per table | 5 | 20 | 5 |
| Capacity mode | On-demand only | On-demand or provisioned | On-demand or provisioned |
Distance functions
When you create a vector index, you choose a distance function. The distance function determines how DynamoDB measures similarity between vectors. Your choice affects ranking quality and search accuracy. Amazon DynamoDB supports three distance functions.
| Distance function | Score interpretation | Best match |
|---|---|---|
COSINE |
Lower scores indicate greater similarity. Measures the cosine distance (1 minus cosine similarity) between two vectors. Values range from 0 (identical direction) to 2 (opposite direction). | Smallest scores |
DOT_PRODUCT |
Higher scores indicate greater similarity. Measures the dot product between two vectors. | Highest scores |
EUCLIDEAN |
Lower scores indicate greater similarity. Measures the straight-line distance between two vectors. | Smallest scores |
To compare how distance functions rank the same query vector, see How distance functions rank results.
The following guidance helps you choose the right distance function for your workload.
COSINE-
Compares direction and ignores magnitude. Use
COSINEfor semantic similarity with text embedding models. These models encode meaning in direction, and vector length can vary. Examples include Amazon Titan Text Embeddings and Cohere Embed.COSINEis well suited for the following use cases:-
Semantic search over product descriptions or documents
-
Retrieval Augmented Generation (RAG)
-
FAQ matching
COSINEis the safe default when you are unsure which function to use. -
DOT_PRODUCT-
DOT_PRODUCTis sensitive to both direction and magnitude (the length of a vector). ChooseDOT_PRODUCTwhen your embedding model's documentation recommends dot product as the similarity measure, or when you want vector length to influence ranking.DOT_PRODUCTis well suited for the following use cases:-
Recommendation systems that use popularity or confidence scores to scale embeddings and influence ranking
-
Models whose documentation specifically recommends dot product as the similarity measure
-
Magnitude-sensitive ranking where vector length carries meaningful signal
We recommend normalizing your embeddings to unit length. When normalized,
DOT_PRODUCTranks results the same way asCOSINE. Skip normalization only if you want magnitude to affect ranking.Example use case: a product recommendation system where you scale each product embedding by its popularity score. More popular products get longer vectors and rank higher in search results.
-
EUCLIDEAN-
Measures straight-line distance between two vectors.
EUCLIDEANis sensitive to magnitude. Use it when absolute position in the embedding space matters.EUCLIDEANis well suited for the following use cases:-
Image or audio embeddings where spatial distance matters
-
Near-duplicate detection
-
Clustering and anomaly detection
Example use case: finding near-duplicate images from image embeddings.
-
Choose a distance function that matches your embedding model
If you are unsure which function to use, check your embedding model's documentation. Validate your choice against a representative dataset. You cannot change the distance function after index creation. For more information, see Match the distance function to your embeddings.
How distance functions rank results
The distance function you choose when you create the index determines both the
Score value and the sort order of results. The same query can rank the
same items differently under different distance functions. The following example uses
the query vector [1, 0, 0, 0] against four stored vectors.
| Stored vector | COSINE (lower is more similar) |
EUCLIDEAN (lower is more similar) |
DOT_PRODUCT (higher is more similar) |
|---|---|---|---|
[1, 0, 0, 0] |
0.0 | 0.0 | 1.0 |
[10, 0, 0, 0] |
0.0 | 9.0 | 10.0 |
[0.7071, 0.7071, 0, 0] |
0.29 | 0.77 | 0.71 |
[-1, 0, 0, 0] |
2.0 | 2.0 | -1.0 |
Two behaviors are worth noting:
-
COSINEignores magnitude. It scores[1, 0, 0, 0]and[10, 0, 0, 0]identically (both0.0) because they point in the same direction.EUCLIDEANranks[10, 0, 0, 0]last for the same query because it measures absolute distance, which increases with a vector's magnitude. -
DOT_PRODUCTscores can be negative. A vector pointing in the opposite direction ([-1, 0, 0, 0]) scores-1.0. Do not assume scores are always non-negative when you sort or apply thresholds to results.
SearchSchema
When you create a vector index, you can optionally define a SearchSchema that specifies vector index partition keys and inline filter attributes.
HASH(vector index partition key)-
A vector index partition key partitions your index data for independent scaling. When you specify a vector index partition key, items with the same partition key value are stored together, which enables the system to search only the relevant data. At high scale, this lowers search latency because the search examines only a subset of the vector space instead of the entire index. Use attributes with low-to-medium cardinality, such as
CategoryorCountry. You can specify at most one vector index partition key.If you define a vector index partition key in the SearchSchema, you must provide its value in the
SearchConditionExpressionwhen you callSearchVectors.Use a partition key to scale search throughput
Define a vector index partition key when you expect a large index or high search volume. Because each
SearchVectorscall is scoped to a single partition key value, distributing your data across many partition key values lets you run more search operations per second and reduces the amount of data each search examines. See Choose a partition key that matches your query patterns. INLINE_FILTER-
Inline filter attributes are projected into the vector index so that DynamoDB can filter during search at the storage layer.
Inline filters support the equality operator (
=) inSearchConditionExpression. Comparison, range, and set-membership operators (<>,<,<=,>,>=,IN) are not yet available. Unlike vector index partition keys, inline filters are optional during search.
You can create a vector index without defining a partition key in the SearchSchema.
In this case, every SearchVectors call searches the entire index. This
is simpler because you don't need a SearchConditionExpression, but it
does not scale horizontally. As your index grows, each search examines more data,
increasing latency and cost. If your workload requires high throughput or your index
contains a large number of vectors, define a partition key to distribute data across
partitions and scale independently. See
Choose a partition key that matches your query patterns.
Projections
Like global secondary indexes, vector indexes support projections that control which attributes from the base table are copied into the index. You specify the projection when you create the vector index.
-
KEYS_ONLY— Only the base table primary key attributes, the vector attribute, and any inline filter attributes defined in the SearchSchema are projected into the index. -
INCLUDE— In addition toKEYS_ONLYattributes, you specify additional non-key attributes to project. You cannot change the set of included attributes after the vector index is created. To project a different set of attributes, delete the index and re-create it with the projection you want. -
ALL— All attributes from the base table are projected into the index.
Projection limits what SearchVectors can return
Attributes that are not projected into the vector index cannot be returned in
SearchVectors responses. If you need specific attributes in search
results, include them in the projection or use ALL.
Using vector indexes with other DynamoDB features
- DynamoDB Streams
-
You can enable DynamoDB Streams on a table that has a vector index, either with the
StreamSpecificationparameter when you create the table or throughUpdateTable. The stream captures item-level changes to the base table, and operates independently of the vector index. - Global tables
-
You can add a vector index to a global table, and you can convert a table that has a vector index into a global table by adding a replica with
UpdateTable. The vector index definition, including its dimensions, distance function, SearchSchema, and projection, is replicated automatically to each new replica Region. You do not create the vector index separately in the replica Region.Items that you write in any replica Region are replicated to the other Regions and indexed there. After replication completes,
SearchVectorsin each Region searches the same set of vectors. Because vector search uses approximate nearest neighbor (ANN), separate searches in different Regions might return slightly different results or ordering for the same query, even over identical data. Replication and indexing of vectors in the other Regions are asynchronous, even for multi-Region strong consistency (MRSC) global tables. A vector that you just wrote in one Region might not yet appear inSearchVectorsresults in another Region until the change has propagated.On-demand capacity required
Vector indexes require on-demand capacity mode, which global tables also support. Create the vector index and the replica on a table that already uses on-demand capacity.
- Point-in-time recovery (PITR) and backups
-
When you restore a table from a point-in-time recovery or an on-demand backup, DynamoDB restores the base table data and the vector index definition. As with global secondary indexes, DynamoDB rebuilds the vector index from the restored base table data rather than copying it byte-for-byte, so the index goes through backfilling before it is ready for search. Wait until
IndexStatusisACTIVEandBackfillingisfalseon the restored index before you runSearchVectors. - Time to Live (TTL)
-
You can use DynamoDB TTL on a table that has a vector index. When TTL deletes an expired item from the base table, DynamoDB removes the corresponding entry from the vector index, the same way a manual delete does. Expired items therefore stop appearing in
SearchVectorsresults after the deletion propagates to the index. - Importing and exporting table data
-
You can export a table that has a vector index to Amazon S3; the export contains the base table items, including the vector attributes stored on them. When you import data from Amazon S3 into a new table, define the vector index in the import request the same way you would with
CreateTable. DynamoDB indexes the imported items as they are written, and the vector index becomes available after the import completes. - DAX
-
DynamoDB Accelerator (DAX) does not support the
SearchVectorsoperation. SendSearchVectorsrequests directly to DynamoDB, even when your application uses DAX for other read operations. DAX caching of base table reads is unaffected by the presence of a vector index.