Skip to content

fix(metrics): wire the Qdrant vector store, and let a build include it - #1532

Merged
wanghy73 merged 1 commit into
MemMachine:speedkickfrom
wanghy73:feat/qdrant-profiling-testbed
Aug 31, 2026
Merged

wanghy73 merged 1 commit into
MemMachine:speedkickfrom
wanghy73:feat/qdrant-profiling-testbed

Conversation

@wanghy73

@wanghy73 wanghy73 commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Follow-on to #1523, which wired three OperationTrackers that had shipped instrumented but never given a metrics factory. QdrantVectorStore is the fourth.

The defect

OperationTracker accepts metrics_factory=None and then discards every timing without an error, a warning, or a series. A component that is fully instrumented but never handed a factory looks identical to one that was never instrumented — the only way to notice is to go looking for a metric that should exist and find nothing.

That is what QdrantVectorStore was doing. QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and database_manager passes it through.

The build arg

The Dockerfile gains ARG EXTRAS="" on all four uv sync lines. Without --extra qdrant the qdrant-client package is never installed and the provider raises ModuleNotFoundError on every request — so an image intended to exercise this path could not run at all. That is not hypothetical; it is how the first Qdrant testbed deploy failed.

The test change

test_qdrant_creates_vector_store pinned the exact QdrantVectorStoreParams kwargs and had to change. It now asserts metrics_factory is not None rather than pinning a value: passing the keyword is not the property worth guarding, since None is accepted and silently discards everything. Removing the wiring fails it.

Verified

1,228 common/server tests pass; ruff check and ruff format --check clean; ty reports no diagnostics in these files.

Measured on a live deployment rather than only in tests: with this in place the Qdrant vector store reports 26 ms mean per search against a real corpus, alongside the segment store at 53 ms and the OpenAI embedder at 231 ms. Before it, that layer produced no series at all — so the question "is Qdrant the bottleneck?" was unanswerable, and the answer turns out to be an emphatic no.

Companion chart change (the deployment side of the same work): MemVerge/MemMachine-Platform#1005.

QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

The Dockerfile gains an EXTRAS build arg on all four uv sync lines. Without
--extra qdrant the qdrant-client package is never installed and the provider
raises ModuleNotFoundError on every request, so an image intended to exercise
this path could not run at all.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it; 1228 common/server tests
pass, ruff check and format are clean.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP
@wanghy73
wanghy73 merged commit b6c90ab into MemMachine:speedkick Aug 31, 2026
50 of 55 checks passed
wanghy73 added a commit that referenced this pull request Aug 31, 2026
…1556)

qdrant-client is an optional extra (packages/server/pyproject.toml:67).
#1532 gave the Dockerfile an EXTRAS build arg so a build can include it,
but the publish workflow never passed one, so every image on Docker Hub
lacks the package: the core starts cleanly and then raises
ModuleNotFoundError on the first request that uses the event backend.
The platform chart can now select that backend, so there is no tag it
can point at.

Both the CPU and GPU builds pass EXTRAS=--extra qdrant unconditionally.
The GPU sync line becomes `--extra gpu --extra qdrant`.

Verified: uv.lock already carries qdrant-client under
`marker = "extra == 'qdrant'"`, so `uv sync --frozen --extra qdrant`
resolves without relocking. Parsed the workflow with PyYAML and confirmed
build-args is exactly ['GPU=...', 'SCM_VERSION=...', 'EXTRAS=--extra qdrant']
for both jobs -- the rationale sits in a YAML comment above the key, not
inside the block scalar, where it would have reached Docker as a literal
build arg.

Not verified: no image was published from this branch. The workflow is
tag-triggered and was not dispatched, so the built image has not been
run against a Qdrant deployment.


Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
@wanghy73
wanghy73 deleted the feat/qdrant-profiling-testbed branch September 2, 2026 06:29
This was referenced Sep 17, 2026
edwinyyyu pushed a commit to edwinyyyu/MemMachine that referenced this pull request Sep 17, 2026
QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without MemMachine#1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab4070e2a5f3fb1d6c4fa2b7a7a4fd2e4ad)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
edwinyyyu pushed a commit to edwinyyyu/MemMachine that referenced this pull request Sep 17, 2026
QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without MemMachine#1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab4070e2a5f3fb1d6c4fa2b7a7a4fd2e4ad)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
edwinyyyu pushed a commit to edwinyyyu/MemMachine that referenced this pull request Sep 18, 2026
QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without MemMachine#1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
edwinyyyu pushed a commit to edwinyyyu/MemMachine that referenced this pull request Sep 18, 2026
QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without MemMachine#1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
edwinyyyu pushed a commit to edwinyyyu/MemMachine that referenced this pull request Sep 18, 2026
QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without MemMachine#1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
edwinyyyu pushed a commit to edwinyyyu/MemMachine that referenced this pull request Sep 18, 2026
QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without MemMachine#1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
edwinyyyu pushed a commit to edwinyyyu/MemMachine that referenced this pull request Sep 21, 2026
QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without MemMachine#1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
edwinyyyu pushed a commit to edwinyyyu/MemMachine that referenced this pull request Sep 21, 2026
QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without MemMachine#1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
edwinyyyu pushed a commit to edwinyyyu/MemMachine that referenced this pull request Sep 21, 2026
QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without MemMachine#1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>
edwinyyyu added a commit that referenced this pull request Sep 24, 2026
…(port of #1532) (#1682)

* fix(metrics): wire the Qdrant vector store (speedkick) (#1532)

QdrantVectorStore was the fourth component built without a metrics factory.
OperationTracker accepts metrics_factory=None and then discards every timing
without an error, so the store looked instrumented and emitted nothing - the
same defect as the Neo4j store, the episode store and the session store, which
is why no Qdrant latency was observable.

QdrantConf gains MetricsFactoryIdMixin so it can resolve one, and
database_manager passes it through.

test_qdrant_creates_vector_store pinned the exact params and had to change.
It now asserts metrics_factory is not None rather than pinning it: passing the
keyword is not the property worth guarding, since None is accepted and silently
discards everything. Removing the wiring fails it.

Ported to main without #1532's Dockerfile change (the EXTRAS build arg),
which is unrelated to the wiring; the `metrics_factory_id` key is added to
the database configuration table in the docs.

(cherry picked from commit b6c90ab)

Claude-Session: https://claude.ai/code/session_01Nr9kacmpFVTTfkZRw6esxP

Co-authored-by: Claude Opus 5 <[email protected]>

* docs(config): name Neo4j on the metrics_factory_id row, as it takes the key too

The row read "Qdrant: ...", but on main Neo4jConf carries the same mixin and
the Neo4j store receives the resolved factory the same way (#1678), with no
docs row of its own. Named inline, as the table names Milvus on its rows.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

---------

Co-authored-by: wanghy73 <[email protected]>
Co-authored-by: Claude Opus 5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants