Skip to the page
Tecyfy

S3 Vectors vs OpenSearch: cheaper vector search on AWS, and where the bill turns

Amazon S3 Vectors stores and queries embeddings with no cluster to run, for a few dollars a month at RAG scale. But every query is billed on the size of the whole index it searches, so traffic, not storage, decides when OpenSearch is the cheaper and better choice. The pricing, the limits and the ways to use both.

Tecyfy · Published · 9 min read

A bucket labelled S3 Vectors full of glowing points, a meter counting each sweep of a magnifier, beside a machine billed by the hour

Amazon S3 Vectors is a low-cost way to keep embeddings on AWS when they are queried now and then: no cluster, a few dollars a month to store millions of vectors, and nothing to pay while nobody searches. The catch is in how a query is billed. Each one pays for scanning the whole index it searches, so a busy search box over one big index can cost more than an OpenSearch collection that runs all month.

So the choice is less about features than about traffic. The rest of this page works out where that line falls for your data, and what OpenSearch gives you that S3 Vectors does not.

What S3 Vectors is

A vector bucket is a new S3 bucket type with its own API (s3vectors). Inside it you create vector indexes, each with a fixed dimension (1 to 4,096) and a distance metric (cosine or Euclidean), and you write vectors to them with a key and metadata. A query sends a vector and gets back the nearest keys, with metadata if you ask for it. AWS quotes subsecond latency for infrequent queries and as low as 100 ms for frequent ones.

There is nothing to size. An index holds up to 2 billion vectors, a bucket up to 10,000 indexes, and writes are strongly consistent: a vector is searchable as soon as PutVectors returns. Block Public Access is always on and cannot be turned off. If you are new to how a Vector DatabaseVector DatabaseA database built to store embeddings and quickly find the ones closest to a query, which is how AI apps search by meaning. finds neighbours, the concept page shows it step by step.

How a query is billed

The bill has 3 parts. In US East, on 23 October 2026:

  • Storage: $0.06 per GB-month. A vector's size is 4 bytes per dimension, plus its key and metadata.
  • Writes: $0.20 per GB uploaded, with each PutVectors call billed at least 128 KB. Send full batches of up to 500 vectors.
  • Queries: $2.50 per million requests, plus a data processed charge.

That last line is the one to understand. Data processed is the average vector size (vector data, key and filterable metadata) times the number of vectors in the index you query. It is the whole index, every query, whatever your filter matches. The rate falls as the index grows: $0.004 per TB for its first 100,000 vectors, $0.002 per TB from there to 10 million, and $0.0004 per TB beyond. Data returned is $0.01 per GB, but the first 512 KB of each response is free, so a top 10 almost never pays it.

Here is what that means for 1,024-dimension vectors with a short key and 200 bytes of filterable metadata (4,332 bytes scanned per vector):

Vectors in the index you queryCost per million queries
10,000$2.66
100,000$4.08
1 million$11.17
10 million$82.09

Storage barely moves the total. 10 million of those vectors with 1 KB of chunk text each take about 50 GB, or $2.99 a month; rewriting a sixth of them each month adds $1.66. A million queries against them as one index adds $82.09. Ten million queries add $821.

Try itWhat does a month of S3 Vectors cost?
10 million
Dimensions
1 million

about 0.39 a second on average

Storage$2.99
Writes$1.67
Queries$82.09

About $86.75 a month. Each query costs $82.09 per million because it is billed on the whole index it searches: 10 million vectors of 4.2 KB. The same money keeps 0.5 OpenSearch Serverless OCUs running all month.

US East prices, 23 Oct 2026. Each query hits one index and returns the top 10; every vector carries a 36-byte key and 200 bytes of filterable metadata, and the chunk text is non-filterable, so queries do not pay to scan it. Writes assume full batches of up to 500 vectors (a PUT is billed at least 128 KB).

Split the index, not the filter

Because a query pays for the index it searches, the biggest saving is to search a smaller index. Splitting those 10 million vectors into 100 indexes of 100,000, and sending each query to one, cuts the same million queries from $82.09 to $4.08. The total month goes from about $87 to about $9.

This fits multi-tenant RAG well, and AWS recommends it: one index per customer, with IAM or bucket policies that let each tenant reach only its own index. It also helps latency, since AWS advises dividing vectors across indexes to improve query performance.

A metadata filter does not have the same effect on the bill. The pricing page computes data processed from the whole index, so {"tenant": "acme"} on one big index narrows the results, not the charge. Use filters for relevance and splits for cost.

A few more things move the bill:

  • Keep chunk text non-filterable. Non-filterable metadata is stored and returned, but not scanned, so the text a RAG app hands to the model costs storage only. Declare those keys when you create the index; you cannot change them later.
  • Pick the dimension with the bill in mind. At 3,072 dimensions the same index costs $232.59 per million queries; at 384 dimensions, $35.05. Many embedding models let you shorten vectors; the embedding cost calculator compares the models and their vector lengths.
  • Mind rewrites. Deleted or overwritten vectors can count toward the index's size for up to a day, so a job that rewrites the same keys all day pays to scan the old copies too.

When OpenSearch is the better buy

OpenSearch Serverless bills compute by the OpenSearch Compute Unit (OCU, 6 GiB of memory with its vCPU) at $0.24 an hour in US East, separately for indexing and search, plus $0.024 per GB-month for storage. A collection group held at 2 search OCUs costs $350.40 a month before indexing and storage, and then serves as many queries as those OCUs can handle.

Set that against the table. On one 10-million-vector index, S3 Vectors passes $350 at about 4.3 million queries a month, which is under 2 queries a second on average. Past that point, a steady stream of queries is cheaper on capacity you pay for by the hour. AWS's own wording points the same way: S3 Vectors "is ideal for workloads where queries are less frequent".

The OCUs your index needs depend on its size, compression and traffic, so measure: load a sample, run your query mix and read the SearchOCU metric. OpenSearch Serverless now also lets a collection group's minimum be 0 OCUs, and its NextGen vector collections scale to zero when idle and compress indexes 32x by default. That narrows S3 Vectors' advantage for quiet workloads, at the price of a cold start when traffic returns.

Then there is what OpenSearch does that S3 Vectors does not:

S3 VectorsOpenSearch Serverless (vector search)
SearchSimilarity with metadata filtersSimilarity plus full-text, Hybrid SearchHybrid SearchRunning a keyword search (usually BM25) and a vector search for the same query and merging the 2 ranked lists, so exact terms like a product code and loose wording like "money back" are both found., aggregations, facets, geospatial and nested queries
DimensionsUp to 4,096Up to 16,000
DistanceCosine, EuclideanEuclidean, cosine, dot product
New vectors searchableAt once (strongly consistent)After the 5-second refresh (NextGen)
LatencySubsecond cold, as low as 100 ms warmMilliseconds
Throughput per indexHundreds of queries a secondScales with OCUs
Idle costStorage onlyStorage, plus the minimum OCUs you set

If your users type keywords such as product codes, error messages or names, the hybrid row alone decides it. Pure vector search misses exact terms that keyword search finds, and S3 Vectors has no keyword index.

Using both

AWS joins the two in 2 ways, and they answer different problems.

S3 Vectors as OpenSearch's storage engine. On a managed OpenSearch domain (version 2.19 or later, OpenSearch Optimized instances), you set "engine": "s3vector" on a vector field when you create the index. The vectors live in S3 Vectors, and the text and other fields stay in the cluster, so you keep hybrid queries and aggregations without paying for memory to hold every vector. It suits large, rarely queried vector fields next to an existing search workload. You can mix engines in one index, but you cannot switch a field to s3vector after the index exists. Two limits to plan for: a k-NN query on that field returns at most 100 neighbours, and indexes that use the engine are left out of snapshots, so there is no point-in-time restore or accidental-delete protection for them.

PUT support-articles
{
  "settings": { "index": { "knn": true } },
  "mappings": {
    "properties": {
      "embedding": {
        "type": "knn_vector",
        "dimension": 1024,
        "space_type": "cosinesimil",
        "method": { "engine": "s3vector" }
      },
      "title": { "type": "text" },
      "product": { "type": "keyword" }
    }
  }
}

Export to OpenSearch Serverless. From the S3 console you can copy an index into a Serverless collection for high-throughput, low-latency serving. It is a one-time, point-in-time copy: it captures data up to the start of the export, updates made during the export may not all reach OpenSearch, nothing stays in sync, and you pay for both stores while both exist. Treat it as a way to promote an index that has become busy, not as a live replica.

In a Bedrock knowledge base

Amazon Bedrock Knowledge Bases can create an S3 vector bucket for you as a knowledge base's vector store, or use a vector bucket and index you created. Know the limits before you pick it: search is semantic only (no hybrid), each vector carries at most 1 KB of custom metadata and 35 keys, only float vectors are supported, and hierarchical chunking with large chunks can overflow the metadata limit. How Bedrock Knowledge Bases work and what they cost covers the managed option, which runs the store for you.

Check your index mode

If your vector bucket was created before 30 September 2026, its indexes default to the CLASSIC mode, which checks your filter while it searches. A filter that matches only a few vectors can then return fewer results than topK, which shows up in RAG as answers built on 2 chunks instead of 10. The ENHANCED mode applies the filter first, so you get a full set from the matching vectors, and it adds $startsWith. Buckets created since then use ENHANCED and cannot use CLASSIC.

You can move an index with UpdateIndexMode, or try the behaviour on one query first:

import boto3

s3v = boto3.client("s3vectors", region_name="us-east-1")
question_embedding = embed("How do I change my invoice address?")  # 1,024 floats from your embedding model

response = s3v.query_vectors(
    vectorBucketName="support-kb",
    indexName="tenant-acme",
    queryVector={"float32": question_embedding},
    topK=10,
    filter={"product": {"$in": ["billing", "invoices"]}},
    queryMode="ENHANCED",
    returnMetadata=True,
    returnDistance=True,
)
for match in response["vectors"]:
    print(match["key"], match["distance"])

An ENHANCED filter can use up to 100 constraints, and each value in an $in list counts as one. When a user may see 300 documents, AWS's advice is to tag each vector with the group they belong to, such as a case or project id, and filter on that one key.

Which one to choose

  • Quiet or spiky queries over a lot of vectors (an internal assistant, per-customer RAG, archives searched now and then): S3 Vectors, one index per tenant.
  • A busy search box, keyword-heavy queries or facets: OpenSearch Serverless, or a managed domain.
  • An existing OpenSearch workload with a big vector field: the S3 Vectors engine inside OpenSearch.
  • Not on AWS-managed services at all: Postgres with pgvectorpgvectorA PostgreSQL extension that adds vector similarity search., Qdrant or Chroma, compared in pgvector vs Qdrant vs Chroma.

Whichever you pick, size it first: the vector database size calculator turns your documents into a vector count and the memory and disk an in-memory index needs, which is the number to compare against the bill above.

Questions

What is Amazon S3 Vectors?
S3 Vectors is a bucket type for embeddings. You create a vector bucket, add vector indexes to it, write vectors with metadata and run similarity queries through its own API, with no servers or cluster to size. AWS quotes subsecond latency for infrequent queries and as low as 100 ms for frequent ones, and each index holds up to 2 billion vectors.
How much does S3 Vectors cost?
In US East, $0.06 per GB-month of storage, $0.20 per GB written, and per query $2.50 per million requests plus a data processed charge on the size of the index searched ($0.004 per TB for its first 100,000 vectors, $0.002 per TB up to 10 million, $0.0004 per TB beyond). 10 million 1,024-dimension vectors with 1 KB of text each cost about $3 a month to store; 1 million queries against them as one index cost about $82.
Is S3 Vectors cheaper than OpenSearch Serverless?
At low query rates, by a wide margin, because while nobody queries it you pay only for storage. Per query, though, S3 Vectors charges for scanning the whole index, so a 10-million-vector index costs about $82 per million queries. Past roughly 4 million queries a month on that index, the bill is more than 2 OpenSearch Serverless OCUs running all month ($350 at $0.24 an OCU-hour). Splitting the index per tenant moves that point a long way out.
Does S3 Vectors support hybrid search?
No. S3 Vectors does similarity search with metadata filters only. For keyword plus vector (hybrid) search, aggregations or faceting, AWS points to OpenSearch, either with S3 Vectors as the storage engine of a managed OpenSearch domain or by exporting the index to OpenSearch Serverless.
Can I use S3 Vectors with Amazon Bedrock Knowledge Bases?
Yes. Choose an S3 vector bucket as the vector store, or let Bedrock create one. In a knowledge base each vector can carry up to 1 KB of custom metadata and 35 metadata keys, only float vectors are supported, and search is semantic only, not hybrid.
What is the ENHANCED index mode in S3 Vectors?
It is the mode that applies your metadata filter before the vector search, so a filter that matches few vectors still returns a full top K, and it adds the $startsWith operator. Vector buckets created on or after 30 September 2026 use ENHANCED; older buckets default to CLASSIC, where a narrow filter can return fewer results than you asked for. You can change an index's mode, or set queryMode to ENHANCED on a single query.