DynamoDB Now Does Vector Search
DEV Community

DynamoDB Now Does Vector Search

Originally published on Build With AWS. Subscribe for weekly AWS builds. On August 5, 2026, AWS made vector search generally available in Amazon DynamoDB. The headline promises single-digit millisecond searches, 99%+ recall, and a design that reaches trillions of vectors. The reaction across engineering forums split in two within hours. One group read it as the end of a product category, with variations on “so I don’t need S3 Vector buckets anymore?” and “MongoDB is finished.” Another group opened the service quotas page and came back with a much narrower reading, pointing out that the documented way to hold latency down and scale search throughput as your index grows is to keep each query scoped to a manageable partition. Both readings are defensible from the announcement alone. The documentation settles it, and it also contains three things the announcement never mentions: a hard requirement that rules out many existing tables, a security warning that matters enormously for multi-tenant applications, and a pricing example where vector writes cost far more than searches. Before any of that makes sense, we need to talk about what a vector actually is, because the rest follows from it. What a Vector Actually Is Imagine you run a bookstore and you want to arrange books so that similar ones sit near each other. You could sort alphabetically, but then a cookbook lands beside a book on cosmology. Instead, suppose you give every book a set of coordinates, the way a city gives every building a street address. One coordinate might loosely capture “how technical is this,” another “how much does this concern food,” another “how narrative is this.” Books about pasta end up clustered in one corner of the room. Books about black holes end up in a different corner. An embedding is exactly that: a list of numbers that acts as an address describing the meaning of a piece of text. A machine learning model reads your text and produces the address. Two pieces of text that mean similar things get addresses that sit close together. That closeness is the whole trick, and it is why the technique works for search: you convert the shopper’s phrase “lightweight running shoes for summer” into an address, then look for products whose addresses are nearby. You never match keywords. You match meaning. That is why people call it semantic search, and it is why a search for “footwear for hot weather” can surface a product whose description never uses either word. The number of coordinates is called the number of dimensions. Our bookstore used three. Real models use hundreds or thousands, because meaning is complicated and three numbers cannot capture it. DynamoDB accepts up to 4,096 dimensions. Because there are many ways to measure “near,” you have to pick one, called the distance function. Picture each address as an arrow drawn from the middle of the room out to that point. You now have two arrows, one for the shopper’s query and one for a product, and three sensible ways to compare them. Cosine distance only cares about the angle between the arrows, ignoring their length. It asks “are these pointing the same way,” which for text means “are these about the same thing,” while ignoring how emphatically each one says it. Euclidean distance is the tape-measure answer: how far apart are the two arrowheads in a straight line. Length matters here, so a long arrow and a short arrow pointing identically still count as far apart. Dot product is the one worth slowing down for, because everyone repeats the phrase “it considers direction and magnitude” without saying what it does. Think of two people pushing a shopping cart. If both push in the same direction, the work they get done depends on the direction and on how hard each pushes: two people shoving hard in agreement moves the cart much further than two people nudging it gently. If one pushes sideways, their effort barely contributes. If one pushes backwards, they actively subtract. The dot product is that number, agreement scaled by effort, which is precisely why dot product scores can come out negative when the two arrows point opposite ways. AWS calls Cosine the safe default when you are unsure, and otherwise recommends matching whatever measure your embedding model’s own documentation specifies. Dot product then comes with a choice worth understanding rather than following blindly. AWS recommends normalizing your embeddings to unit length, which means rescaling every arrow to exactly the same length so only direction can differ. Do that and dot product ranks results identically to Cosine, because you have removed the “how hard each person pushes” part and left only “do they agree.” Skip normalization only when you want length to carry meaning. The documentation’s example is a recommendation system that stretches each product’s arrow in proportion to its popularity score, so popular products push harder and rank higher. One trap here has caught people in every vector database that offers a choice. For Cosine and Euclidean, a lower score means a closer match, with zero meaning identical. For Dot product, higher means closer. The comparison flips depending on a setting you chose weeks earlier, and nothing stops you from sorting the wrong way. Two related details are easy to get wrong: Cosine distance here runs from 0 for identical direction up to 2 for opposite directions, not 0 to 1, and Dot product scores can be negative for vectors pointing the opposite way. If you write a relevance threshold assuming scores never go below zero, it will behave strangely on exactly the results you meant to exclude. What DynamoDB shipped is not a new data type for any of this. You store the embedding in the ordinary List type, where each element is a Number holding one coordinate, and you write it with a normal PutItem or UpdateItem call. No new data type and no change to your item schema is required, though as the next section covers, you may still need to change one setting on the table itself. What is new is a new kind of index. An index is a second, reorganized copy of your data that DynamoDB maintains for you, kept in a shape that makes one particular question fast, the way a library keeps a card catalog sorted by author alongside shelves sorted by subject. You declare a vector index on the attribute holding your embeddings, then query it through a new SearchVectors call that takes a query address, a count of how many neighbors you want (up to 100, called top-K), and optional filters. Two words from that setup will recur, so here they are up front. The SearchSchema is simply the bundle of settings you declare when creating the index, holding the grouping attribute and the attributes you want to filter on. It is the form you fill in when you order the card catalog. The projection is your choice of which of the item’s other attributes get copied onto the index entry alongside the vector, the way a catalog card carries the title and author but not the book’s full text. Copy little and the card is cheap but you have to go fetch the book to read anything else. Copy everything and the card is self-sufficient but expensive, in ways the pricing section gets specific about. Almost every design choice about that index is fixed the moment you create it. You cannot change the number of dimensions or the distance function. The SearchSchema is fixed at creation, and the documentation is explicit that you cannot add, remove, or change the partition key afterward. Projection choices are fixed too: with an INCLUDE projection you cannot later change which attributes are included. Changing any of these means creating a second index and migrating to it, which AWS documents as a four-step dance: create the new index under a different name, wait for it to finish backfilling, cut your application over, then delete the old one to stop paying for its storage. Backfilling is what happens when you point an index at a table that already holds data: DynamoDB walks every existing item and builds the index entry for it, because an index created today knows nothing about items written last year. It is the clerk who has to sit down and type up a catalog card for every book already on the shelves before the catalog is any use to anyone. Your base table is never affected, because DynamoDB re-derives the index from your items. But it does mean the design work happens up front, and this is the reason the rest of this post exists. Finally, the 99%+ recall figure in the announcement is the most informative number in it. Recall means: of the genuinely closest neighbors, what fraction did the search actually find? A figure below 100% tells you this is approximate nearest neighbor search, and AWS documents it as such. Rather than comparing your query against every stored vector, which would be like reading every book in the building, the system uses a structure that walks it quickly to the right neighborhood and looks around there. It usually finds the true nearest neighbors and occasionally misses one. At large scale, production vector systems generally work this way, because the exact version does not survive contact with a billion items. What matters practically is that AWS states a recall figure and gives you no knob to tune it. You get 99%+ or you use something else. Two Requirements That Decide Whether You Can Use This At All Before evaluating anything else, check two facts about your table, because either one can end the conversation. The first is not mentioned in the announcement at all. DynamoDB bills capacity in two modes. Provisioned mode means you tell AWS in advance how much traffic to reserve, like booking a fixed number of restaurant tables for the evening. On-demand mode means you pay per request and AWS handles the scaling, like walking in and being seated. Vector indexes are supported only on tables using on-demand capacity mode, and are not supported on provisioned capacity tables. If your production table runs provisioned capaci

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.