{"schemaVersion":1,"id":"https://lucioduran.com/projects/vector-search-portability","url":"https://lucioduran.com/projects/vector-search-portability","title":"Vector Search Portability","description":"Real hnswlib and sqlite-vec comparison with identical vectors, filters and updates. Recall against exact search, concurrent read load and postfilter result loss.","language":"en","datePublished":"2026-10-21","dateModified":"2026-10-21","contentFormat":"text/markdown","content":"[Projects](<https://lucioduran.com/projects>) / Vector Search Portability\n\n# Vector Search Portability\n\nReal hnswlib and sqlite-vec comparison with identical vectors, filters and updates. Recall against exact search, concurrent read load and postfilter result loss.\n\nAuthor: [Lucio Durán](<https://lucioduran.com/>) · Python 3.11.13 · License: [MIT](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/LICENSE>)\n\nPage published: 2026-10-21 · Page updated: 2026-10-21\n\n[Repository](<https://github.com/lucioduran/vector-search-portability>) · [Original evidence](<https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/reference/manifest.json>) · [Release v0.1.0](<https://github.com/lucioduran/vector-search-portability/releases/tag/v0.1.0>)\n\n## Problem and relevance to agents\n\nAn engine migration can preserve result counts while changing IDs, filter costs or behavior after updates. This project defines a shared contract and measures those differences.\n\nAn agent retrieving filtered context depends on filter semantics as well as ranking. The comparison exposes IDs, distances, predicates and candidate loss before a failure is attributed to the model.\n\n## Architecture\n\n1. **Frozen input.** 5,000 float32 vectors with 64 dimensions, 40 queries and 500 vector-plus-metadata updates. The published NPZ fixes the input bytes.\n2. **Native adapters.** hnswlib 0.8.0 and sqlite-vec 0.1.6 share squared L2 distance and AND filters. Exhaustive NumPy float64 search provides an independent reference.\n3. **Processes and traces.** Three isolated repetitions per engine alternate execution order. Records cover native search and postfiltering, one- and four-client load, CPU, RSS and snapshots.\n\n- [Design and methodology](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/docs/methodology.md>)\n\n## What this demonstrates\n\n- Comparable engine contracts with explicit metrics and filter semantics.\n- Recall evaluation before and after vector and metadata changes.\n- Adapter-cost analysis with preserved original and confirmation measurements.\n\n## Published results\n\nReference results on Intel Xeon W-3223, macOS and Python 3.11.13. Load tables show medians of three trials, including medians of trial percentiles rather than pooled percentiles.\n\nEach load trial performs 400 mixed-filter searches after updates. Recall@10 compares IDs with the exact top results. Result loss measures missing items relative to min(10, eligible candidates). Postfiltering starts from 40 global neighbors.\n\n### Original read-load measurements\n\n| Engine / clients | Requests/s | p50 (ms) | p95 (ms) |\n| --- | --- | --- | --- |\n| hnswlib / 1 | 1503.6 | 0.363 | 2.295 |\n| hnswlib / 4 | 100.3 | 9.402 | 149.332 |\n| sqlite-vec / 1 | 1412.7 | 0.666 | 0.801 |\n| sqlite-vec / 4 | 2637.5 | 1.476 | 1.660 |\n\n### Filters after updates, both engines\n\n| Mode | Recall@10 | Result loss |\n| --- | --- | --- |\n| Native, nonempty groups | 1.0000 | 0.0000 |\n| Tenant postfilter | 0.4725 | 0.5275 |\n| Selective postfilter | 0.0275 | 0.9725 |\n\nBoth engines reached native recall 1.0 on this fixture. Selective postfiltering lost 97.25% of available results despite 14 eligible candidates. Four clients degraded the HNSW adapter with its Python predicate; the experiment does not isolate callback, GIL and O(N) mask contributions.\n\nThe original run retains 9,600 searches. A further run adds 9,600 after a CPU accounting fix, with the same native recall and selective loss. Table values remain the original observations. [Results and analysis](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/README.md>).\n\n## Reproduce\n\nPython 3.11, a C++ compiler for hnswlib and SQLite with loadable extensions. setup.py prepares local dependencies. No model, server or API is required.\n\nCommands use POSIX paths. Some macOS Python builds disable SQLite extensions; the README documents a compatible installation. Keep the fixed NPZ, choose a new output directory and avoid concurrent heavy measurements.\n\n### Replay saved evidence\n\n```\ngit clone https://github.com/lucioduran/vector-search-portability.git\ncd vector-search-portability\ngit checkout 691a60ceecd4cb5eaaaf8570a073b80d96b9563e\npython3 scripts/setup.py\n.venv/bin/python -m vector_portability verify --output results/reference\n.venv/bin/python -m vector_portability verify --output results/confirmation\n```\n\n### Repeat the local measurement\n\n```\nmkdir -p build\n.venv/bin/python -m vector_portability run --output build/reproduced\n.venv/bin/python -m vector_portability verify --output build/reproduced\n```\n\n## Scope and limitations\n\n- Vectors are synthetic: this evaluates geometry and adapters, not linguistic relevance or production scale.\n- Engines have different durability. SQLite ingestion includes commit; HNSW does not guarantee crash persistence.\n- Local closed-loop load without networking. RSS includes the interpreter and traces; three repetitions on one host do not establish a general winner.\n\n- [Vector databases: engines, filters and architecture decisions](<https://lucioduran.com/blog/vector-databases-pgvector-qdrant-pinecone>)\n\n## Sources and revision\n\nTables summarize the October 21, 2026 reference run. Manifests link six original and six confirmation reports with their hashes. The executed revision shown here is the reference revision; confirmation evidence identifies a416742cb7df20476b67c75dc4c13fe67c2d7ead.\n\n- Reviewed revision: [` 691a60ceecd4cb5eaaaf8570a073b80d96b9563e `](<https://github.com/lucioduran/vector-search-portability/commit/691a60ceecd4cb5eaaaf8570a073b80d96b9563e>)\n- Revision recorded by the experiment: [` 7ee57a5af5e0f5bf4b46caf7eb55f0e1abd9fcf1 `](<https://github.com/lucioduran/vector-search-portability/commit/7ee57a5af5e0f5bf4b46caf7eb55f0e1abd9fcf1>)\n- Report timestamp (UTC): 2026-10-21\n- Release published: [v0.1.0](<https://github.com/lucioduran/vector-search-portability/releases/tag/v0.1.0>) · 2026-10-21T22:16:31Z\n- Corpus SHA-256: ` 53fd9ca277d581075d2eb7df63348fbd52e92d4a0797b1e40454367ed3d409e0 `\n\n- [README and usage](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/README.md>)\n- [Original evidence](<https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/reference/manifest.json>)\n- [Confirmation evidence](<https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/confirmation/manifest.json>)\n- [Results and analysis](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/README.md>)\n- [Design and methodology](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/docs/methodology.md>)\n- [Corpus and provenance](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/data/fixed.npz>)\n- [Measured environment dependencies](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/requirements-local.lock>)\n- [MIT license](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/LICENSE>)","headings":[{"level":1,"text":"Vector Search Portability","url":"https://lucioduran.com/projects/vector-search-portability#title"},{"level":2,"text":"Problem and relevance to agents","url":"https://lucioduran.com/projects/vector-search-portability#problem"},{"level":2,"text":"Architecture","url":"https://lucioduran.com/projects/vector-search-portability#architecture"},{"level":2,"text":"What this demonstrates","url":"https://lucioduran.com/projects/vector-search-portability#demonstrates"},{"level":2,"text":"Published results","url":"https://lucioduran.com/projects/vector-search-portability#results"},{"level":3,"text":"Original read-load measurements","url":"https://lucioduran.com/projects/vector-search-portability#results-load"},{"level":3,"text":"Filters after updates, both engines","url":"https://lucioduran.com/projects/vector-search-portability#results-filters"},{"level":2,"text":"Reproduce","url":"https://lucioduran.com/projects/vector-search-portability#reproduce"},{"level":3,"text":"Replay saved evidence","url":"https://lucioduran.com/projects/vector-search-portability#reproduce-replay"},{"level":3,"text":"Repeat the local measurement","url":"https://lucioduran.com/projects/vector-search-portability#reproduce-inference"},{"level":2,"text":"Scope and limitations","url":"https://lucioduran.com/projects/vector-search-portability#scope"},{"level":2,"text":"Sources and revision","url":"https://lucioduran.com/projects/vector-search-portability#sources"}],"sections":[{"heading":"Vector Search Portability","level":1,"url":"https://lucioduran.com/projects/vector-search-portability","content":"[Projects](<https://lucioduran.com/projects>) / Vector Search Portability"},{"heading":"Vector Search Portability","level":1,"url":"https://lucioduran.com/projects/vector-search-portability#title","content":"Real hnswlib and sqlite-vec comparison with identical vectors, filters and updates. Recall against exact search, concurrent read load and postfilter result loss.\n\nAuthor: [Lucio Durán](<https://lucioduran.com/>) · Python 3.11.13 · License: [MIT](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/LICENSE>)\n\nPage published: 2026-10-21 · Page updated: 2026-10-21\n\n[Repository](<https://github.com/lucioduran/vector-search-portability>) · [Original evidence](<https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/reference/manifest.json>) · [Release v0.1.0](<https://github.com/lucioduran/vector-search-portability/releases/tag/v0.1.0>)"},{"heading":"Problem and relevance to agents","level":2,"url":"https://lucioduran.com/projects/vector-search-portability#problem","content":"An engine migration can preserve result counts while changing IDs, filter costs or behavior after updates. This project defines a shared contract and measures those differences.\n\nAn agent retrieving filtered context depends on filter semantics as well as ranking. The comparison exposes IDs, distances, predicates and candidate loss before a failure is attributed to the model."},{"heading":"Architecture","level":2,"url":"https://lucioduran.com/projects/vector-search-portability#architecture","content":"1. **Frozen input.** 5,000 float32 vectors with 64 dimensions, 40 queries and 500 vector-plus-metadata updates. The published NPZ fixes the input bytes.\n2. **Native adapters.** hnswlib 0.8.0 and sqlite-vec 0.1.6 share squared L2 distance and AND filters. Exhaustive NumPy float64 search provides an independent reference.\n3. **Processes and traces.** Three isolated repetitions per engine alternate execution order. Records cover native search and postfiltering, one- and four-client load, CPU, RSS and snapshots.\n\n- [Design and methodology](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/docs/methodology.md>)"},{"heading":"What this demonstrates","level":2,"url":"https://lucioduran.com/projects/vector-search-portability#demonstrates","content":"- Comparable engine contracts with explicit metrics and filter semantics.\n- Recall evaluation before and after vector and metadata changes.\n- Adapter-cost analysis with preserved original and confirmation measurements."},{"heading":"Published results","level":2,"url":"https://lucioduran.com/projects/vector-search-portability#results","content":"Reference results on Intel Xeon W-3223, macOS and Python 3.11.13. Load tables show medians of three trials, including medians of trial percentiles rather than pooled percentiles.\n\nEach load trial performs 400 mixed-filter searches after updates. Recall@10 compares IDs with the exact top results. Result loss measures missing items relative to min(10, eligible candidates). Postfiltering starts from 40 global neighbors."},{"heading":"Original read-load measurements","level":3,"url":"https://lucioduran.com/projects/vector-search-portability#results-load","content":"| Engine / clients | Requests/s | p50 (ms) | p95 (ms) |\n| --- | --- | --- | --- |\n| hnswlib / 1 | 1503.6 | 0.363 | 2.295 |\n| hnswlib / 4 | 100.3 | 9.402 | 149.332 |\n| sqlite-vec / 1 | 1412.7 | 0.666 | 0.801 |\n| sqlite-vec / 4 | 2637.5 | 1.476 | 1.660 |"},{"heading":"Filters after updates, both engines","level":3,"url":"https://lucioduran.com/projects/vector-search-portability#results-filters","content":"| Mode | Recall@10 | Result loss |\n| --- | --- | --- |\n| Native, nonempty groups | 1.0000 | 0.0000 |\n| Tenant postfilter | 0.4725 | 0.5275 |\n| Selective postfilter | 0.0275 | 0.9725 |\n\nBoth engines reached native recall 1.0 on this fixture. Selective postfiltering lost 97.25% of available results despite 14 eligible candidates. Four clients degraded the HNSW adapter with its Python predicate; the experiment does not isolate callback, GIL and O(N) mask contributions.\n\nThe original run retains 9,600 searches. A further run adds 9,600 after a CPU accounting fix, with the same native recall and selective loss. Table values remain the original observations. [Results and analysis](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/README.md>)."},{"heading":"Reproduce","level":2,"url":"https://lucioduran.com/projects/vector-search-portability#reproduce","content":"Python 3.11, a C++ compiler for hnswlib and SQLite with loadable extensions. setup.py prepares local dependencies. No model, server or API is required.\n\nCommands use POSIX paths. Some macOS Python builds disable SQLite extensions; the README documents a compatible installation. Keep the fixed NPZ, choose a new output directory and avoid concurrent heavy measurements."},{"heading":"Replay saved evidence","level":3,"url":"https://lucioduran.com/projects/vector-search-portability#reproduce-replay","content":"```\ngit clone https://github.com/lucioduran/vector-search-portability.git\ncd vector-search-portability\ngit checkout 691a60ceecd4cb5eaaaf8570a073b80d96b9563e\npython3 scripts/setup.py\n.venv/bin/python -m vector_portability verify --output results/reference\n.venv/bin/python -m vector_portability verify --output results/confirmation\n```"},{"heading":"Repeat the local measurement","level":3,"url":"https://lucioduran.com/projects/vector-search-portability#reproduce-inference","content":"```\nmkdir -p build\n.venv/bin/python -m vector_portability run --output build/reproduced\n.venv/bin/python -m vector_portability verify --output build/reproduced\n```"},{"heading":"Scope and limitations","level":2,"url":"https://lucioduran.com/projects/vector-search-portability#scope","content":"- Vectors are synthetic: this evaluates geometry and adapters, not linguistic relevance or production scale.\n- Engines have different durability. SQLite ingestion includes commit; HNSW does not guarantee crash persistence.\n- Local closed-loop load without networking. RSS includes the interpreter and traces; three repetitions on one host do not establish a general winner.\n\n- [Vector databases: engines, filters and architecture decisions](<https://lucioduran.com/blog/vector-databases-pgvector-qdrant-pinecone>)"},{"heading":"Sources and revision","level":2,"url":"https://lucioduran.com/projects/vector-search-portability#sources","content":"Tables summarize the October 21, 2026 reference run. Manifests link six original and six confirmation reports with their hashes. The executed revision shown here is the reference revision; confirmation evidence identifies a416742cb7df20476b67c75dc4c13fe67c2d7ead.\n\n- Reviewed revision: [` 691a60ceecd4cb5eaaaf8570a073b80d96b9563e `](<https://github.com/lucioduran/vector-search-portability/commit/691a60ceecd4cb5eaaaf8570a073b80d96b9563e>)\n- Revision recorded by the experiment: [` 7ee57a5af5e0f5bf4b46caf7eb55f0e1abd9fcf1 `](<https://github.com/lucioduran/vector-search-portability/commit/7ee57a5af5e0f5bf4b46caf7eb55f0e1abd9fcf1>)\n- Report timestamp (UTC): 2026-10-21\n- Release published: [v0.1.0](<https://github.com/lucioduran/vector-search-portability/releases/tag/v0.1.0>) · 2026-10-21T22:16:31Z\n- Corpus SHA-256: ` 53fd9ca277d581075d2eb7df63348fbd52e92d4a0797b1e40454367ed3d409e0 `\n\n- [README and usage](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/README.md>)\n- [Original evidence](<https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/reference/manifest.json>)\n- [Confirmation evidence](<https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/confirmation/manifest.json>)\n- [Results and analysis](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/README.md>)\n- [Design and methodology](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/docs/methodology.md>)\n- [Corpus and provenance](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/data/fixed.npz>)\n- [Measured environment dependencies](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/requirements-local.lock>)\n- [MIT license](<https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/LICENSE>)"}],"links":[{"text":"Projects","url":"https://lucioduran.com/projects"},{"text":"Lucio Durán","url":"https://lucioduran.com/"},{"text":"MIT","url":"https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/LICENSE"},{"text":"Repository","url":"https://github.com/lucioduran/vector-search-portability"},{"text":"Original evidence","url":"https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/reference/manifest.json"},{"text":"Release v0.1.0","url":"https://github.com/lucioduran/vector-search-portability/releases/tag/v0.1.0"},{"text":"Design and methodology","url":"https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/docs/methodology.md"},{"text":"README and usage","url":"https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/README.md"},{"text":"Results and analysis","url":"https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/README.md"},{"text":"Vector databases: engines, filters and architecture decisions","url":"https://lucioduran.com/blog/vector-databases-pgvector-qdrant-pinecone"},{"text":"691a60ceecd4cb5eaaaf8570a073b80d96b9563e","url":"https://github.com/lucioduran/vector-search-portability/commit/691a60ceecd4cb5eaaaf8570a073b80d96b9563e"},{"text":"7ee57a5af5e0f5bf4b46caf7eb55f0e1abd9fcf1","url":"https://github.com/lucioduran/vector-search-portability/commit/7ee57a5af5e0f5bf4b46caf7eb55f0e1abd9fcf1"},{"text":"v0.1.0","url":"https://github.com/lucioduran/vector-search-portability/releases/tag/v0.1.0"},{"text":"Confirmation evidence","url":"https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/confirmation/manifest.json"},{"text":"Corpus and provenance","url":"https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/data/fixed.npz"},{"text":"Measured environment dependencies","url":"https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/requirements-local.lock"},{"text":"MIT license","url":"https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/LICENSE"}],"structuredData":[{"@context":"https://schema.org","@graph":[{"@type":"WebPage","@id":"https://lucioduran.com/projects/vector-search-portability#page","url":"https://lucioduran.com/projects/vector-search-portability","name":"Vector Search Portability","description":"Real hnswlib and sqlite-vec comparison with identical vectors, filters and updates. Recall against exact search, concurrent read load and postfilter result loss.","inLanguage":"en","datePublished":"2026-10-21","dateModified":"2026-10-21","author":{"@id":"https://lucioduran.com/#person"},"mainEntity":{"@id":"https://lucioduran.com/projects/vector-search-portability#software"}},{"@type":"SoftwareSourceCode","@id":"https://lucioduran.com/projects/vector-search-portability#software","name":"Vector Search Portability","description":"Real hnswlib and sqlite-vec comparison with identical vectors, filters and updates. Recall against exact search, concurrent read load and postfilter result loss.","url":"https://lucioduran.com/projects/vector-search-portability","codeRepository":"https://github.com/lucioduran/vector-search-portability","programmingLanguage":"Python","runtimePlatform":"Python 3.11.13","license":"https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/LICENSE","version":"v0.1.0","identifier":{"@type":"PropertyValue","propertyID":"git-commit","value":"691a60ceecd4cb5eaaaf8570a073b80d96b9563e"},"author":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"isAccessibleForFree":true,"citation":["https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/README.md","https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/reference/manifest.json","https://raw.githubusercontent.com/lucioduran/vector-search-portability/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/confirmation/manifest.json","https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/results/README.md","https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/docs/methodology.md","https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/data/fixed.npz","https://github.com/lucioduran/vector-search-portability/blob/691a60ceecd4cb5eaaaf8570a073b80d96b9563e/requirements-local.lock","https://github.com/lucioduran/vector-search-portability/releases/tag/v0.1.0"]},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Projects","item":"https://lucioduran.com/projects"},{"@type":"ListItem","position":2,"name":"Vector Search Portability","item":"https://lucioduran.com/projects/vector-search-portability"}]}]}],"contentHash":"f4b5b1fe04eb94ae4204a26f38ea18b0f16b23601c6265b633920f0ccd1dc8b6","provenance":{"method":"Deterministic serialization of the server-rendered main element","source":"https://lucioduran.com/projects/vector-search-portability","hashAlgorithm":"sha256","hashScope":"JSON document fields before contentHash and provenance","sourceHTMLBytes":45709,"contentBytes":7423}}
