NEWVectors or files. Pick a path.Start →
    Infrastructure
    12 min read
    Updated 2026-08-27

    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.

    Compute Pushdown
    Object Storage
    Vector Search
    Query Engines
    S3
    Retrieval Architecture
    Latency

    The Short Answer



    Compute pushdown means running the filter, the scan, or the distance computation on the machine that already holds the bytes, instead of shipping those bytes across the network to a query engine that will throw most of them away. If a query touches a 4 GB segment and returns 40 rows, moving 4 GB to compute the answer is the expensive part. The arithmetic was never the problem.

    For search over object storage the practical version is: push metadata predicates and candidate generation down to the storage node, and pull back only the surviving candidates. A filter that eliminates 99% of a segment should eliminate 99% of the bytes you transfer, not 0%. Whether you can do that depends entirely on whether anything is running next to your data, which is why pushdown is an architecture decision rather than a query optimization.

    The thing that decides it is boring: object storage APIs return whole objects. GET gives you the object, or a byte range of it if you know the offset. Neither one evaluates a predicate. So pushdown over object storage requires either a storage service that speaks a richer protocol, or a compute layer you place next to the storage yourself.

    What Does Compute Pushdown Actually Mean?



    The term comes from query engines. A planner that receives SELECT title FROM docs WHERE year = 2026 has a choice: read every row and filter in the engine, or hand the year = 2026 predicate to the storage layer and read only matching rows. Handing it down is pushdown. Databases have done this internally for decades; the interesting recent shift is pushing past the process boundary, into the storage system itself.

    Three things commonly get pushed:

  1. Projection pushdown. Read only the columns the query asks for. Columnar formats make this cheap because columns are contiguous on disk, which is the Apache Parquet file layout doing its job.
  2. Predicate pushdown. Evaluate WHERE clauses at the storage layer. Parquet stores per-row-group min/max statistics precisely so a reader can skip a row group without decoding it.
  3. Aggregate pushdown. Compute COUNT, SUM, or a top-k at the source and return the result rather than the inputs.


  4. DuckDB's write-up on querying Parquet is the clearest worked example of the first two: the same query against the same file can read a few megabytes or the whole thing depending on whether the reader uses the statistics.

    Why Is The Network The Bottleneck And Not The Math?



    A dot product over a 768-dimensional float32 vector is roughly 768 multiply-adds. A modern core does billions of those per second. Transferring that same vector over a network is about 3 KB, and at realistic object-storage throughput the transfer costs more wall-clock than the arithmetic by orders of magnitude.

    Scale it to a shard holding ten million vectors and the asymmetry becomes the whole story. The compute to score them is seconds of CPU. The transfer is roughly 30 GB. Any architecture that moves the vectors to the compute is paying the expensive cost to avoid the cheap one.

    This is why the useful mental model is not "where is the CPU" but "how many bytes cross the wire". Pushdown is a byte-reduction technique that happens to be expressed as a placement decision.

    What Can And Cannot Be Pushed Down?



    OperationPushableWhy
    Metadata predicate (brand = "acme")YesEvaluated against a payload index at the storage node; cuts candidates before any vector is read
    Projection (return 3 fields, not 40)YesColumnar layout makes partial reads contiguous
    ANN candidate generationYesThe index structure lives with the segment; traversal is local
    Distance computationYesVectors never leave the node; only scores and ids come back
    Per-shard top-kYesEach shard returns k, the coordinator merges
    Global top-k across shardsNoRequires results from every shard; the merge is inherently central
    Cross-collection joinsPartlyOnly if both sides are colocated, which is rarely true
    Reranking with a cross-encoderNoNeeds a model the storage node does not host, and operates on the merged candidate set
    The line between the two halves is whether the operation is decomposable per shard. Anything that needs a global view has to happen after the fan-in, which is also why "push everything down" is the wrong goal.

    How Have Other Systems Solved This?



    S3 Select is the direct attempt: S3 Select lets you run SQL against an object and return only matching records, with a documented SQL subset. It works on CSV, JSON and Parquet, and the subset is narrow enough that it fits filter-and-project workloads rather than anything resembling vector search.

    Aurora pushed the redo log down into a purpose-built storage tier so the database stops shipping full pages. The VLDB paper on Aurora's storage layer is the canonical writeup, and its central claim generalizes well beyond relational workloads: the network is the constraint, so move the smallest possible representation.

    Arrow and Parquet solved the format half. The Arrow columnar specification makes it possible to read a column without decoding a row, which is the precondition for projection pushdown being cheap rather than merely possible.

    What none of them give you directly is vector search. An ANN index is not a SQL predicate, so a storage service that speaks SQL cannot traverse an HNSW graph or an IVF posting list on your behalf.

    Do I Actually Need Pushdown?



    Three questions, in order:

    1. What is your selectivity? If a typical query's filter eliminates a small fraction of the corpus, pushdown saves little, because you were going to read most of it anyway. If the filter is highly selective, the savings are close to the elimination rate. 2. Where does your latency go? Instrument the split between transfer and compute. If compute dominates, pushdown is the wrong lever and you want a better index or budget-aware retrieval. 3. How often do you re-read the same bytes? A hot working set that fits in cache makes the transfer cost disappear on repeat queries, and storage tiering is the cheaper fix. Pushdown earns its complexity on cold, wide, selective scans.

    If all three point the same way, the follow-on question is whether you control the storage layer at all. Pushdown is not something you can add to a system whose storage is an API you call.

    What This Means For Search Over Your Own Object Storage



    Running retrieval over content in your own bucket is exactly the case where this bites. The data is in S3-compatible object storage, the index derived from it is large, and the naive architecture fetches segments to a query service on every cold query.

    Mixpeek's vector store is built on the other side of that decision. Its shards are a service that owns the segment format, the payload index, and the ANN structure together, so a filter on metadata.brand and the vector traversal both execute where the bytes are, and the coordinator receives per-shard candidates rather than segments. Owning the storage layer end to end is the precondition, not a detail. That is the same reason hybrid BM25 and vector fusion can run per shard: the inverted index sits beside the vectors instead of in a separate system.

    The primitives this maps onto are the bucket holding your objects and the collection holding what was extracted from them. MVS is the standalone path if you already have embeddings, and pricing is per stored vector and per query rather than per byte scanned, which is the billing shape pushdown makes possible.

    Frequently Asked Questions



    Is compute pushdown the same as edge computing?



    No. Edge computing moves compute closer to the user to cut round-trip latency. Compute pushdown moves compute closer to the data to cut bytes transferred. They can point in opposite directions: the storage node holding your index may be nowhere near your users.

    Does S3 Select work for vector search?



    Not usefully. It evaluates a SQL subset over CSV, JSON and Parquet, which covers metadata filtering but has no notion of an ANN index. You can use it to narrow candidates by scalar predicates, then you still have to fetch vectors and score them somewhere.

    Can I add pushdown to an existing vector database?



    Only if it already colocates compute with segments. If your vector store is a service you query over the network and it fetches from object storage internally, pushdown is its architectural decision to make, not yours. What you can control is selectivity: better metadata indexes reduce the candidate set regardless of where the work runs.

    How much does pushdown actually save?



    It scales with selectivity, so there is no single number worth quoting. The useful way to estimate it is to measure the ratio of bytes read to bytes returned for a representative query. That ratio is roughly the upper bound on what pushdown can remove, and the real saving is lower because index structures and headers still have to be read.

    Does pushdown make queries cheaper or just faster?



    Both, in different currencies. Faster because less data crosses the network. Cheaper because object-storage pricing charges for requests and egress, and because the compute doing the scanning is smaller. The tradeoff is that storage nodes now need CPU and memory they did not need as a pure blob store.

    What is the main risk of relying on pushdown?



    Skew. Pushdown makes each shard do more work, so an unevenly distributed filter can leave one shard scanning while the others idle, and the query is as slow as the slowest shard. Adaptive indexing and careful partitioning are the mitigations.
    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

    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 →
    Infrastructure

    How to Merge Data Sources With Different Schemas Into One Searchable Index

    Your content lives in three systems and none of them agree on field names. One calls it headline, one calls it name, one calls it asset_title. Covers the four ways teams reconcile that for search, how to design a canonical field set you will not regret, what to do when two sources claim the same target field, how to keep lineage back to the origin record after the merge, and when merging is the wrong answer.

    Read guide →