NEWVectors or files. Pick a path.Start →
    Infrastructure
    8 min read
    Updated 2026-10-18

    Why Is the First Vector Search Query on S3 Slow? Cold, Warm and Cached Latency, Measured

    The first vector search query on S3 or GCS is slow because the index must be fetched from the bucket before anything can be ranked. Measured on Mixpeek's vector store: a cold query at 1M x 768 had a p50 of 0.697 s, a whole-partition layout read 391 MB where a range-read layout read 3.1 MB, and cached queries ran at a p50 of about 50 ms. What drives cold latency, why recall drops on large indexes, and how to make the first query faster.

    Vector Search
    Object Storage
    S3
    Benchmarks
    Latency
    Infrastructure

    Why is the first vector search query on S3 slow?



    The first query is slow because nothing is cached yet: the search service has to fetch index data from the bucket before it can rank anything, and each fetch from S3 or GCS costs tens of milliseconds before a byte arrives. How slow it gets depends on how many sequential round trips the index layout needs and how many bytes each query pulls. In our own runs at 1 million 768-dimension vectors, a first query that read whole index partitions pulled 391 MB from the store, while a layout built for ranged reads answered the same query with about 3.1 MB in four round trips. Once data is cached, the same queries run in tens of milliseconds.

    Every number on this page comes from runs we measured on Mixpeek's vector store (MVS) between July and October 2026, or from a vendor page we link. Each row says where it ran. None of it ran on a customer's production data.

    What happens during a cold query on object storage?



    A vector index on object storage keeps its data as files in a bucket. A query node with an empty cache has to read some of those files before it can answer. For a centroid-based index (IVF, the usual layout for object storage) the reads come in sequence:

    1. Read the namespace's small header or manifest. 2. Read the centroids and pick the partitions closest to the query vector (nprobe of them). 3. Read the compressed vector codes and ids for those partitions, in parallel. 4. Read the full-precision vectors of the best candidates to rerank them, in parallel.

    Each step waits for the one before it. So the store's share of a cold query is roughly the number of sequential round trips times the latency of one GET, plus however long it takes to download the bytes. A graph index such as HNSW needs many more sequential hops per query, which is why object-storage systems use centroid layouts. turbopuffer's architecture notes make the same point.

    How many bytes does a cold query read?



    This is where layouts differ most. We measured a 1M x 768 fixture on a local MinIO store with 20 ms of injected latency each way, so a small GET took 40 to 56 ms, about one same-region GCS read. The shard started with an empty disk each round.

    Step (1M x 768, cold)RequestsBytes read
    Shard boot (index, manifest, payloads)18 GET, 17 HEAD, 10 LIST76 MB
    First dense query, whole partitions17 GET391 MB
    First 1% filtered query, every partition66 GET1,580 MB
    Range-read prototype, same dense query4 round tripsabout 3.1 MB
    Reading whole partitions is simple and makes the next queries fast, but the first one pays for every byte. A filter that the index cannot apply natively is worse: the 1% filtered query read every partition. The range-read prototype fetched only the code and vector byte ranges it needed and returned recall@10 of 1.0 in 8 of 8 rounds. Its store time was about 200 ms (four round trips of about 50 ms). Its end-to-end p50 was about 820 ms, and most of that was Python on a heavily loaded test host.

    How fast is vector search on S3 once the data is cached?



    Fast enough for interactive search. Cold, warm and hot latency are three separate numbers, so ask any vendor for all three.

    MeasurementResultWhere it ran
    Cold, 1M x 768, from true zero through the APIp50 0.697 s, p99 1.311 sProof stack on GKE with MinIO, October 2026
    Recall@10, 1M x 768, 1,000 held-out queries0.9759 against exact cosine ground truthSame stack
    Resident shard, 2M x 768, unfilteredp50 50.28 ms, p95 58.79 ms, p99 63.13 msStaging, synthetic data, July 2026
    Resident shard, 2M x 768, filter at 0.2 selectivityp95 59.11 ms, recall@10 1.0 (0.9996 unfiltered)Same, nprobe 16 of 128 partitions
    Cold reads from GCS, 80.6M vectors, compressed codes onlyp50 941 ms, p99 1,352 msStaging, July 2026
    Write acknowledged in GCS, 1 writerp50 107.9 ms, p95 140.5 ms, p99 162.2 msStaging on real GCS, October 2026
    Write acknowledged in GCS, 8 writersp95 176.6 msSame
    For comparison, turbopuffer publishes p50 874 ms for the first query to a 1M-document namespace and p50 14 ms once cached (architecture page). Their test and ours differ in hardware, store and load, so read the two as the same order of magnitude and nothing finer.

    Why does recall drop on large indexes stored in S3?



    Recall drops when the number of partitions grows and the number searched does not. At 80.6M vectors in 5,724 partitions, our default probe width gave recall@10 of 0.355. Raising nprobe to 1,024 brought it to 0.960, at a warm p50 of 808 ms. On object storage every extra partition probed is more bytes and possibly another round trip, so teams quietly keep nprobe low and lose recall without noticing. Measure recall against an exact search on a sample of your own queries at your real size, and rerun it whenever the corpus grows by a large factor.

    Filters are the other recall trap. In our 1M x 768 runs, filters matching 0.1% and 1% of the data matched an exact scan on 100 and 99 of 100 queries. At 50% selectivity recall fell to 0.815, which is still open work on our side. A filter applied after the vector search can return fewer than k results or the wrong ones. Our guide to pre-, post- and in-place filtering covers the options.

    How do you make the first query faster?



  1. Read ranges, not files. Store codes and vectors so a query can fetch only the byte ranges for its candidates. In our runs this cut a cold query from 391 MB to about 3.1 MB.
  2. Keep round trips to three or four. Each sequential GET adds tens of milliseconds. Fetch everything a step needs in parallel.
  3. Warm the cache ahead of traffic. Send a cheap query when a user opens a search page, or pin namespaces that must always answer fast.
  4. Use a faster storage class for hot data. S3 Express One Zone is built for single-digit millisecond access, at a higher price per GB.
  5. Tier by access. Ethan Steininger, Mixpeek's founder, argues that at scale 60 to 80 percent of a corpus is warm or cold: data you rarely query but still need to be able to query. Tiering keeps the frequently queried part in memory or on local disk and leaves the rest in the bucket. See vector storage tiering.


  6. When should you not put the index on object storage?



    When every query must answer in under about 10 ms, including the first one, as in ad ranking or autocomplete. When writes must be visible in a few milliseconds at high rates: our measured acknowledgement for a durable write to GCS is 140 to 177 ms at p95, because each write waits for the bucket. For most search over files, archives and media, a cold first query of about a second and warm queries in tens of milliseconds are acceptable, and the storage bill is a fraction of keeping everything in RAM. Our explainer on running a vector database on S3 covers the economics.

    Where Mixpeek fits



    Mixpeek reads your files where they already live, in S3, GCS or any bucket, and turns what's in them into data your software can search, classify and moderate. Its vector store, MVS, keeps indexes in object storage with hot, warm and cold tiers, and the numbers above are its own. It fits teams searching large libraries of video, images, audio and documents who want storage priced like a bucket. It is the wrong fit if you need sub-10 ms answers on every query. Prices are on the pricing page, and the docs cover setup. If you are choosing a store, see S3-compatible object storage options and the best vector databases.

    Frequently Asked Questions



    Why is the first vector search query on S3 slow?



    Because the index has to be read from the bucket before the query can be ranked. Each GET to S3 or GCS takes tens of milliseconds, a centroid index needs three or four sequential reads, and a layout that fetches whole partitions downloads hundreds of megabytes. In our 1M x 768 runs the cold p50 through the API was 0.697 s, against tens of milliseconds once cached.

    How much slower is a cold query than a warm one?



    Between about 14 and 62 times in the figures here. Our cold query at 1M x 768 had a p50 of 0.697 s. Our resident shard at 2M x 768 answered at a p50 of 50.28 ms. turbopuffer publishes 874 ms cold and 14 ms cached at 1M documents.

    How many bytes does a vector search read from S3?



    It depends on the layout. Reading whole partitions, our first dense query at 1M x 768 read 391 MB and a 1% filtered query read 1,580 MB. A range-read layout answered the same dense query with about 3.1 MB.

    Does storing vectors in S3 hurt recall?



    Recall depends on how many partitions each query searches. On a large index with thousands of partitions, a default nprobe can search too few of them. At 80.6M vectors we measured recall@10 of 0.355 at the default and 0.960 at nprobe 1,024. Measure recall against an exact search at your real size.

    How long does a write take to become durable in object storage?



    Tens to hundreds of milliseconds, because the write is acknowledged only after the object is in the bucket. On real GCS we measured p50 107.9 ms and p95 140.5 ms for single writes from one writer, and p95 176.6 ms with eight writers.

    How do I make cold queries on S3 faster?



    Fetch byte ranges instead of whole files, keep the query to three or four sequential round trips, warm or pin namespaces that need low latency, and move hot data to a faster storage class such as S3 Express One Zone. In our runs, range reads cut a cold query's bytes from 391 MB to about 3.1 MB.

    Related Resources



  7. Can you run a vector database on S3?: the architecture and its economics
  8. Can object storage be a database's write-ahead log?: how writes stay durable on S3
  9. Vector storage tiering: hot, warm and cold tiers in practice
  10. Vector database cost comparison: what each architecture costs at scale
  11. MVS: Mixpeek's vector store on object storage
  12. Managed Mixpeek

    Put multimodal search to work

    Connect a bucket and Mixpeek runs the whole multimodal search pipeline for you: extraction, indexing, and search over your own objects. No models to wire up, nothing to host.

    Start with Managed
    MVS · bring your own

    Already have vectors?

    Keep your embeddings on your own cloud and run dense, sparse, and BM25 search directly on object storage. From $25/mo.

    Start with MVS

    Run this on your own data

    Point Mixpeek at the storage you already have and search your video, images, audio, and documents the way this guide describes. Build starts at $25/mo for up to 1M vectors.

    Search your own archiveRead Docs

    Related guides

    Infrastructure

    Compute Pushdown: Why Your Vector Search Over Object Storage Is Slow

    Searching data that lives in S3 usually means downloading it first. Compute pushdown inverts that: send the predicate to the bytes instead of the bytes to the predicate. Covers what can and cannot be pushed down, why the network is the bottleneck rather than the math, the prior art from Parquet and S3 Select to Aurora, and how to tell whether pushdown would actually help your workload.

    Read guide →
    Infrastructure

    Write-Ahead Logs on Object Storage: How S3 Becomes a Database's Durability Layer

    A write-ahead log acknowledges a write the moment it is durable, before any index work happens. Move that log onto S3 or GCS and the bucket becomes the durability layer: recovery, read replicas and change feeds all become readers of one chain of sequenced objects. Covers what a WAL is, why object storage changes the design, the two coordination problems it creates (writer fencing and garbage collection that could delete the only copy of a write), how conditional writes solve them, and the shipped write path in Mixpeek MVS.

    Read guide →
    Infrastructure

    Can You Run a Vector Database on S3? Object-Storage-Backed Vector Search, Explained

    Object-storage-backed vector search became mainstream in 2026: S3 Vectors went GA, turbopuffer and LanceDB proved the architecture, and costs dropped ~10x versus RAM-resident clusters. How it actually works (immutable segments, coarse partitioning, quantization plus rescoring, cache tiers) when it is the wrong choice, and what bring-your-own-bucket adds.

    Read guide →