What is update throughput?
Update throughput is the sustained rate at which a vector database can apply inserts, updates, and deletes to both the object store and the ANN index — usually reported as objects per second under a stated concurrency, batching, and HNSW configuration.
How is update throughput different from one-shot build time?
Build time measures a bulk load from empty to ready. Update throughput measures the live pipeline: continuous or bursty mutations after (or while) the system also serves queries. A configuration that finishes an offline reindex quickly can still choke when every change must search a large graph, take locks, write a WAL, and maintain inverted indexes. Conversely, async indexing can make client-visible write rates look excellent while the vector queue lags — so “objects accepted per second” and “objects searchable in HNSW per second” diverge. Benchmarks should say which clock they used. Production capacity planning needs both: API write SLA versus when recall-sensitive search actually sees the new vectors.
HNSW makes mutations inherently more expensive than a simple row write.
Why are HNSW updates costly compared with plain storage writes?
Inserting a vector means searching for neighbors and splicing edges into multiple layers — work that grows with graph size and efConstruction. True in-place mutation of a node’s vector is awkward; practical systems often tombstone or retire the old document ID and reinsert under a new immutable ID, then clean up asynchronously. Deletes similarly mark nodes invisible immediately and repair connectivity later in batches. That design keeps queries correct without stalling on full rebuilds, but it means update throughput includes foreground linking plus background cleanup. High efConstruction and maxConnections improve eventual recall yet lower mutation rates. Mixed read/write load adds lock and cache contention that pure import benches miss.
How you feed the engine — batches, protocols, async queues — often moves the number more than tiny parameter tweaks.
What levers raise or lower measured update throughput?
Batch imports amortize per-request overhead; single-object writes pay full round-trips. Async indexing decouples object persistence from HNSW linking so clients finish sooner, at the cost of a temporary queue and briefly incomplete ANN coverage (sometimes bridged by limited brute-force over pending items). Lower efConstruction during heavy ingest trades graph quality for speed; you can lean on higher query-time ef if QPS allows. Vectorization, if done inline, can dominate wall time more than graph linking — pre-embedded payloads isolate true index throughput. Compression modes may slow or speed ingest depending on training phases and cheaper distance kernels. Machine shape matters: imports are often CPU-bound on graph construction, so cores help until memory or disk WAL bandwidth saturates.
Weaviate’s CRUD-capable HNSW stack is built around these realities.
How does Weaviate handle updates in a way that affects throughput?
Weaviate’s custom HNSW supports querying while inserting, WAL-backed durability, immutable internal IDs for updates (delete-old / insert-new), and tombstones with asynchronous cleanup so deletes do not require immediate full rewires. Configuration tips explicitly ask whether you expect many imports or updates: if yes, keep efConstruction modest so mutation throughput stays viable, and use query ef for recall when traffic allows. ASYNC_INDEXING queues vector index work (batches, and in later versions also single inserts, updates, and deletes) on a persistent queue so object-store acknowledgements are not gated on linking; monitor queue length because search freshness lags until drain completes. Relative HNSW growth sizing keeps large-scale ingest from collapsing as the graph passes tens of millions of objects. Protocol and batching choices further change client-observed rates without changing the algorithm.
Measure update throughput the way your product actually mutates data.
How should you benchmark update throughput fairly?
Define the operation mix: fraction of inserts versus updates versus deletes, batch size, and whether queries run concurrently. Report objects/sec to durable store and, separately, time until the vector queue is empty if async is on. Hold HNSW parameters fixed when comparing clients or protocols; hold clients fixed when sweeping efConstruction. Watch p95/p99 of write latency and query latency together — a “fast” update path that wrecks search tails is not a win. Re-test after the corpus grows; linking cost at 1M vectors is not the same as at 50M. Document dimensions, compression, and whether embeddings were precomputed.
Update throughput is the sustained mutation rate your HNSW deployment can absorb without lying about search freshness. Next, read “What is energy per query?” for the cost of serving search once data is flowing, then “What is the difference between a cold cache and a warm cache?” so you do not confuse first-hit update/search stalls with steady-state throughput.