EdgeQuake product limits

July 24, 2026 · View on GitHub

Who this is for: operators sizing a deployment
Rule: Do not promise a capacity number unless it appears below with evidence.
Claim gates (lab): make ceiling-proof / make product-limits-check — not day-2 sizing.

Related: FAQ · Performance tuning · SPEC-066 · SPEC-067 · SPEC-068 · SPEC-069 dedicated · SPEC-072 DiskANN Pareto · SPEC-074 storage P0 · SPEC-075 filtered recall · SPEC-076 precision · SPEC-077 binary quantize · SPEC-078 Filtered-DiskANN · SPEC-079 mid-scale tips · SPEC-080 tiny-slice · SPEC-081 serving view · SPEC-082 push-scale


Status words (read this first)

WordMeaning
ProvenMeasured under production-style stress (latency + concurrency as claimed)
SupportedFull claim gate green (filtered ANN Q1-d ∧ recall@20 ∧ concurrent) — safe to promise with the recipe below
Opt-inSupported only with an explicit non-default recipe — no silent flip
Not promotedLab saw latency or partial wins; do not sell as a floor

Vectors ≠ documents. Example: 50 000 chunks at ~100 chunks/doc ≈ ~500 documents, not 50k docs.

Promote metric: filtered recall@20 under a workspace filter (make filtered-recall-gate / SPEC-075). Never promote from unfiltered-only demos.


TL;DR — What you can promise

PromiseVectors @1536StatusRequires
Comfortable default / laptop50kProvenHost ≥16 GB; shared_buffers ≥2 GB
Product default filtered ANN100kSupportedWave-2 + residency (see below)
Larger dedicated ANN250kSupported opt-inDiskANN recipe list≥800 (not default)
Wave-2 above 100k250k+Not promotedMid-scale wall (SPEC-068); single-spot ≠ concurrent floor

Also proven separately: community Louvain gated at 50k graph nodes; graph G1 degrees path at 100k nodes (not a vector floor).


Pick your size

GoalVectors @1536Host RAMPostgres residencyRecipeStatus
Laptop / default50k16 GBshared_buffers2 GBdefaults OKProven
Filtered ANN @100k100k32 GB preferred2 GB (+ shm ≥4g in harness)Wave-2Supported (default)
Dedicated DiskANN @250k250k32 GB preferred2 GB (+ shm ≥4g)Opt-in DiskANN (list≥800)Supported opt-in (SPEC-082)
Wave-2 beyond 100k250k+lab-class4 GB classWave-2 HNSWNot promoted
Graph entities (degrees)G1 100k nodes proven (separate)

Ceiling evidence (authors / support)

FieldValueArtifact
highest_green_N (Wave-2 default)100 000Shared+partial Wave-2 (SPEC-064/068)
highest_green_N (DiskANN opt-in)250 000Dedicated DiskANN q_list≥800 + HQ build (SPEC-082); 150 000 still green @q≥400 (SPEC-072)
first_fail_N (Wave-2 HNSW)250 000Mid-scale wall (SPEC-068/069) — concurrent; single-spot @150k is not a floor raise
Dedicated HNSW concurrentclients=16 fails from 100kSPEC-069
DiskANN opt-inFull-gate @250k (list≥800, HQ build); @150k list≥400 still greenSPEC-082 · SPEC-072
L2 500 000Latency green on HNSW; recall cliff — not promotedSPEC-066 L2
Graph G1100 000 nodes; degrees p95 ~12 msAGE 1.8 remasure

Validate: make product-limits-check · claim gates: make ceiling-proof / make recall-pareto / make diskann-recall-pareto · turnkey: make wave2-greenfield-env


What to set (copy-paste)

1) Default (≤50k) — Proven

No special vector flags. Keep the working set resident (shared_buffers ≥2 GB).

2) 100k Wave-2 — Supported default (greenfield only)

# Required for the supported 100k filtered-ANN shape — do NOT silent-flip existing DBs
export EDGEQUAKE_VECTOR_STORAGE=halfvec
export EDGEQUAKE_HNSW_PARTIAL_BY_WORKSPACE=1

Turnkey greenfield (SPEC-071) — same flags, plus helper + warmup:

eval "$(make -s wave2-greenfield-env)"
# or: WAVE2_GREENFIELD=1 make backend-bg
./scripts/wave2_warmup.sh <workspace_uuid>
# or: POST /api/v1/admin/ann/warmup  {"workspace_ids":["<uuid>"]}

/ready with Wave-2 on checks catalog ANN presence (empty DB is ready; tables without HNSW → 503). It is not a plan-shape check. First filtered query also warms if warmup is skipped.

Dedicated *_ws_* tables = embedding dimension isolation only (SPEC-069) — not the turnkey 100k path.

3) Opt-in DiskANN @250k — Supported opt-in (not default)

Clears dedicated concurrent + recall full-gate @250k when diskann.query_search_list_size ≥ 800, diskann.query_rescore ≈ list/2 (e.g. 400), and a higher-quality DiskANN build (SPEC-082: num_neighbors=64, search_list_size=200). 150 000 still clears the full-gate at list≥400 / rescore≈200 on the default SBQ build (SPEC-072). Helper: diskann_optin_recipe_statements() (ops/harness SET LOCAL only — not a silent boot default).

# Image (once): make postgres-image-build-pg18-vectorscale
# Runtime: EQ_POSTGRES_PROFILE=pg18-vectorscale  +  CREATE EXTENSION vectorscale CASCADE
# Index on dedicated *_ws_* table (vector, not halfvec):
#   CREATE INDEX … USING diskann (embedding vector_cosine_ops)
#     WITH (storage_layout='memory_optimized', num_neighbors=64, search_list_size=200);
# Query tip (required for 250k recall gate) — both GUCs:
#   SET diskann.query_search_list_size = 800;   -- ≥800 @250k; ≥400 still OK @150k
#   SET diskann.query_rescore = 400;            -- ≈ list/2
FindingResult
Wave-2 defaultStill supported 100k shared+partial
DiskANN opt-in floorhighest_green_N=250000 (dedicated; SPEC-082)
150k q_list≥400Full-gate green (SPEC-072)
250k q_list≥800 + HQ buildFull-gate green (SPEC-082)
Silent flipForbidden — vectorscale/DiskANN remain opt-in

Claim gates: make diskann-recall-pareto · make push-scale-ladder · recipe smoke: make diskann-rescore-smoke (SPEC-074).

Mid-scale wall (SPEC-068)

make recall-pareto measured Wave-2 at 150k/200k/250k × ef∈{80,160,240,400} plus a rebuild arm. No concurrent full-gate green above 100k. SPEC-082 Wave-2 filtered single spot @150k can look green — that does not raise the Wave-2 default floor. Do not promise mid-scale from latency-only / single-query cells.

Postgres residency (ops-real floors):

CorpusMin shared_buffersNotes
50k / Mix≥2 GBSPEC-061/065
100k Wave-2≥2 GB (+ shm ≥4g in Docker)Cold thrash at ~128 MB buffers
Lab L2 500k≥4 GB, maintenance_work_mem ≥2–8 GBClaim gate only

Shared+partial vs dedicated tables (SPEC-069)

ShapeWhat it isConcurrent @100k (clients=16)Use for
Shared + Wave-2 partial HNSWMulti-WS table + WHERE workspace_id=… partialSupported floor (SPEC-064/068)Proven filtered ANN @100k
Dedicated *_ws_* tableOne table per workspace; global HNSW on that tableWorse under stress (~3 s p95 @100k)Per-WS embedding dimension isolation

make dedicated-midscale: recall can look fine on dedicated HNSW, but concurrent fails from 100k@clients=16. Do not promise 150k from dedicated HNSW.

Mix / hybrid honesty

Hybrid Mix (FTS+ANN) prod seed scales are still the ANN ladder (~5k vs 50k–100k). Mix is not a 100k/150k ANN floor.


Optional tips (do not raise floors)

These improve quality or headroom. They are not required to claim the Supported floors above, and they do not unlock 250k+.

TipEnv / settingDefaultWhen to use
Concurrent headroom @100kEDGEQUAKE_HNSW_EF_SEARCH=240unsetConcurrent p95 skirts 500 ms (SPEC-068)
Filtered iterative_scanEDGEQUAKE_HNSW_ITERATIVE_SCANrelaxed_order on filteredUnderfill; unfiltered path leaves iterative_scan off
Bound iterative workEDGEQUAKE_HNSW_MAX_SCAN_TUPLES20000Extreme selectivity
Memory for iterative scanEDGEQUAKE_HNSW_SCAN_MEM_MULTIPLIER1If raising max_scan_tuples alone does not restore recall
ANN → exact reorderEDGEQUAKE_ANN_EXACT_REORDER=1OFFStricter order on candidate set (SPEC-076)
Reorder candidate poolEDGEQUAKE_ANN_REORDER_CANDIDATE_K50With exact reorder; ≥ final top_k
Sparse FTS+ANN RRFEDGEQUAKE_SPARSE_FUSION=rrfweightedCodes / names (SPEC-076); Mix/RRF ≠ ANN floor
Binary quantize + rerankEDGEQUAKE_BINARY_QUANTIZE=1OFFStudy only (SPEC-077); Hamming candidates → exact reorder — not promoted
Filtered-DiskANN labelsEDGEQUAKE_FILTERED_DISKANN_LABELS=1OFFStudy only (SPEC-078); labels smallint[] + &&not promoted
Tiny-slice exact (skip ANN bias)EDGEQUAKE_ANN_EXACT_MAX_ROWS2000SPEC-080: skip Wave-2 enable_seqscan=off when workspace rows ≤ threshold

Filtered recall + iterative_scan (SPEC-075): claim gate make filtered-recall-gate (soft-fails product floors; hang cliff hard-fails). 100k evidence: SPEC-068.

Precision tips (SPEC-076): claim gate make precision-layers-gate (contracts; EQ_PRECISION_SMOKE=1 for DB smoke).

Binary quantize bake-off (SPEC-077): make binary-quantize-bakeoff — archives filtered recall vs Wave-2; does not raise floors or flip defaults.

Filtered-DiskANN labels (SPEC-078): make filtered-diskann-labels-bakeoff — archives Wave-2 vs post-filter DiskANN vs labels; does not raise floors or flip defaults.

Mid-scale tip archive (SPEC-079): make midscale-quantize-labels — B2+A6 @50k/100k; default decision Not promoted (no silent flip).

Tiny-slice exact (SPEC-080): make tiny-slice-exact-gate — planner honesty on small workspaces.

Serving view (SPEC-081): make serving-view-checkeq_serving_chunk_presence admin/debug; not RAG ANN SSOT.

Push-scale ladder (SPEC-082): make push-scale-ladder — A6 @150k/250k + Wave-2 filtered spot @150k + DiskANN primary full-gate @250k. Decision: DiskANN opt-in highest_green_N→250000; Wave-2 default stays 100k; A6 tip not default; silent flip forbidden.

Binary quantize study (SPEC-077) — not default

pgvector binary_quantize + bit_hamming_ops HNSW with exact halfvec/vector rerank. Helpers: build_binary_hnsw_index_sql / build_binary_rerank_select_sql. Env: EDGEQUAKE_BINARY_QUANTIZE (off), EDGEQUAKE_BINARY_CANDIDATE_K (default 200). Wave-2 remains Supported @100k.

Filtered-DiskANN labels study (SPEC-078) — not default

pgvectorscale Filtered-DiskANN: labels smallint[] in the DiskANN index + labels && ARRAY[$ws]::smallint[]. Helpers: WorkspaceLabelMap, build_diskann_labels_index_sql, build_filtered_diskann_label_select_sql. Env: EDGEQUAKE_FILTERED_DISKANN_LABELS (off). No product labels migration. Wave-2 @100k unchanged; dedicated DiskANN opt-in floor is 250k (SPEC-082) — A6 tip still not default (soft-fail @250k labels).

Tiny-slice exact (SPEC-080)

When filtered workspace row count ≤ EDGEQUAKE_ANN_EXACT_MAX_ROWS (default 2000), skip Wave-2 planner bias (enable_seqscan=off) so pgvector’s cost model can prefer exact search. Does not disable HNSW; floors unchanged.

Serving view (SPEC-081) — admin/debug only

eq_serving_chunk_presence(workspace_id) lists relational chunks + embedding_id link. Optional eq_serving_vector_presence(workspace_id, vectors_regclass) joins a namespace vectors table. Serving view ≠ RAG ANN SSOT — do not route queries here; do not silent-unify stores.


If queries are slow

SymptomLikely causeWhat to do
Cold ~1.5 s @100k, warm ~50–70 msDefault btree→exact on ~20% rows (cold cliff)Wave-2 + residency; not “HNSW broken”
Concurrent p95 >500 ms (Sort path)Planner skipped partial HNSWWave-2 + SPEC-067 planner bias; raise buffers
Concurrent skirts 500 ms @100k (HNSW path)Default ef depth under stressOps tip EDGEQUAKE_HNSW_EF_SEARCH=240 (SPEC-068); not a floor raise
Concurrent multi-second on dedicated WS tableHot-set isolation ≠ concurrent scalePrefer Wave-2 shared+partial for 100k; see SPEC-069
Latency green @250k but poor answersHNSW recall cliff vs high-efStay ≤100k; rebuild arm did not unlock promotion
Filtered top-k underfill / low recallPost-filter ANN + low selectivityWave-2 + iterative_scan; raise EDGEQUAKE_HNSW_MAX_SCAN_TUPLES / SCAN_MEM_MULTIPLIER (SPEC-075)
First query after deploy slowPartial HNSW created on first hot queryWarm with a filtered query; /ready checks ANN catalog when Wave-2 on
Upload rejected with quota exceededWorkspace max_documents hitRaise quota or delete docs

Hard caps (code)

CapDefaultSource
Upload / body50 MiBEDGEQUAKE_MAX_UPLOAD_BYTES
Community / full-graph scan50 000 nodesDEFAULT_GRAPH_SCAN_THRESHOLD_NODES
Graph API response500 nodesMAX_GRAPH_NODES
Graph depth5MAX_GRAPH_DEPTH
Page size100MAX_PAGE_SIZE
Query chars10 000MAX_QUERY_CHARS
HNSW dimvector ≤2000, halfvec ≤4000capabilities.rs
Workspace max_documentsFail-closed at upload / new PDF mint (committed + staging)document_quota

No workspace storage-GB quota.


Do not

  • Promise documents ≈ vectors without chunks-per-doc math.
  • Treat cold ~1.5 s @100k default path as an ANN bug.
  • Silent-flip existing databases to halfvec.
  • Claim 500k / L2 from latency-only JSONL (recall can cliff).
  • Claim 150k+ from dedicated HNSW single-query latency (SPEC-069 concurrent wall).
  • Silent-flip to DiskANN / vectorscale / pg18-vectorscale on existing DBs.
  • Treat Mix/hybrid seed scales as equal to the ANN ladder (Mix≪ANN today).
  • Size from FAQ “8+ GB boots” alone — that is minimum to start, not proven 50k / supported 100k.
  • Raise ef_construction expecting warm indexes to change without REINDEX.
  • Run DiskANN @150k with default query_search_list_size=100 or default query_rescore=50 (recall fails — use list≥400 and rescore≈list/2).

Glossary

TermMeaning
Wave-2halfvec + workspace partial HNSW + column filters (100k shape)
Turnkey greenfieldSPEC-071: make wave2-greenfield-env / WAVE2_GREENFIELD=1 + ANN warmup (opt-in; no silent flip)
Dedicated WS tablePer-workspace *_ws_* vector table (HNSW: dimension isolation only; DiskANN opt-in: concurrent @150k)
Opt-in DiskANNpg18-vectorscale + USING diskann + query_search_list_size≥400 + query_rescore≈list/2 (SPEC-072/074; not default)
Q1-dFiltered ANN p95 <500 ms SLO
Cold cliffbtree filter → exact distance; cold latency spike without residency/Wave-2
ResidencyHot index pages fit in shared_buffers + OS page cache
highest_green_N / first_fail_NCeiling ladder fields (authors); operators: “supported up to / fails at”
exact reorderSPEC-076 opt-in ANN→exact distance re-rank on a candidate set