Skip to content

feat: DynamoDB vector index support - #175

Draft
hicksy wants to merge 5 commits into
mainfrom
feat/vector-indexes
Draft

feat: DynamoDB vector index support#175
hicksy wants to merge 5 commits into
mainfrom
feat/vector-indexes

Conversation

@hicksy

@hicksy hicksy commented Aug 12, 2026

Copy link
Copy Markdown
Member

What this changes

First slice of DynamoDB vector index support (#174): CreateTable accepts VectorIndexes, definitions persist with a schema migration on both backends, DescribeTable reports them, and DeleteTable cleans up the per-index shadow tables. Error messages are pinned to strings captured from real DynamoDB. SearchVectors, the UpdateTable path, write-path maintenance, capacity accounting, the WASM surface, and MCP parity land as further commits on this branch.

Checklist

DynamoDB compatibility note

Vector indexes go ACTIVE immediately: CREATING in the create response, ACTIVE in DescribeTable, matching the existing GSI posture. The backfilling window real AWS reports on the UpdateTable path is therefore unreachable here; the compatibility docs entry lands with the docs commit on this branch.

Adds the vector index request and description types, validation with
error messages captured from real DynamoDB, metadata storage with a
schema migration on both backends, a per-index shadow table, DescribeTable
reporting, and DeleteTable cleanup. SearchVectors itself is not yet
implemented; this is the first slice of #174.
@github-actions

Copy link
Copy Markdown
Contributor

Criterion Benchmark Results

Baseline is the per-benchmark median of the last 5 stored runs, so one unusually fast or slow runner cannot skew the comparison. The range column is the spread across those runs.

Benchmark Baseline (ns/iter) Range Current Change
batch_get_item_100 1,389,601 814,524 - 1,451,464 1,435,305 +3.3%
batch_write_item_25 1,119,577 533,898 - 1,182,554 932,500 -16.7%
delete_item 51,384 26,334 - 53,068 46,941 -8.6%
get_item 14,455 8,000 - 15,127 14,641 +1.3%
put_item/put_item/large 269,725 115,520 - 280,567 282,677 +4.8%
put_item/put_item/medium 44,503 19,445 - 46,845 34,942 -21.5%
put_item/put_item/small 25,143 10,759 - 26,885 19,987 -20.5%
query_base_table 1,093,125 666,833 - 1,164,732 1,146,581 +4.9%
query_gsi 25,592 12,359 - 26,517 21,818 -14.7%
scan_with_filter 8,217,608 5,182,664 - 8,785,317 8,891,803 +8.2%
transact_write_items_4 257,350 112,673 - 267,776 216,488 -15.9%
update_item 163,483 85,461 - 185,342 178,125 +9.0%

All benchmarks within 50% of the 5-run median.

Runs in the baseline
  • runs/2026-06-26-e066fc0
  • runs/2026-07-05-7d5fd8a
  • runs/2026-07-24-f7e7d96
  • runs/2026-07-30-bc2a16c
  • runs/2026-07-30T220642Z-be8bfbc

Empty VectorIndexes lists are rejected, fractional dimensions truncate,
and oversized values reuse the captured bounds message instead of leaking
serde text. Adds the captured SearchSchema rules (single HASH, no
duplicate attributes, vector attribute not in AttributeDefinitions),
rejects cross-family duplicate index names, reports real positions in
validation errors, recreates shadow tables cleanly over orphans, and
moves the request types to types.rs beside their GSI and LSI siblings.
@github-actions

Copy link
Copy Markdown
Contributor

Criterion Benchmark Results

❌ The comparison could not be made (exit 1), so this
run says nothing about performance either way.

no criterion results parsed, nothing to compare

VectorIndexUpdates supports Create and Delete, with a synchronous
backfill that sparse-skips values a live write would reject. Vector,
GSI, and LSI names share one namespace on this path, a GSI can no
longer key on a live vector attribute, billing mode cannot leave
PAY_PER_REQUEST while vector indexes exist, and SearchSchema
attributes survive AttributeDefinitions reconciliation. Error strings
and request-model paths are pinned to captured DynamoDB behaviour.
@github-actions

Copy link
Copy Markdown
Contributor

Criterion Benchmark Results

❌ The comparison could not be made (exit 1), so this
run says nothing about performance either way.

no criterion results parsed, nothing to compare

The rust-cache restore can carry a partial target/criterion from an
earlier run, and Criterion's failed baseline reads then interleave
errors into the bencher output, breaking the comparison parser. The
comparison uses the benchmark-data branch, not Criterion's own
baselines, so the run should start from a clean criterion directory.
@github-actions

Copy link
Copy Markdown
Contributor

Criterion Benchmark Results

Baseline is the per-benchmark median of the last 5 stored runs, so one unusually fast or slow runner cannot skew the comparison. The range column is the spread across those runs.

Benchmark Baseline (ns/iter) Range Current Change
batch_get_item_100 1,389,601 814,524 - 1,451,464 1,479,249 +6.5%
batch_write_item_25 1,119,577 533,898 - 1,182,554 1,154,558 +3.1%
delete_item 51,384 26,334 - 53,068 53,583 +4.3%
get_item 14,455 8,000 - 15,127 15,446 +6.9%
put_item/put_item/large 269,725 115,520 - 280,567 256,366 -5.0%
put_item/put_item/medium 44,503 19,445 - 46,845 46,037 +3.4%
put_item/put_item/small 25,143 10,759 - 26,885 25,910 +3.1%
query_base_table 1,093,125 666,833 - 1,164,732 1,120,596 +2.5%
query_gsi 25,592 12,359 - 26,517 25,926 +1.3%
scan_with_filter 8,217,608 5,182,664 - 8,785,317 8,531,382 +3.8%
transact_write_items_4 257,350 112,673 - 267,776 268,313 +4.3%
update_item 163,483 85,461 - 185,342 192,439 +17.7%

All benchmarks within 50% of the 5-run median.

Runs in the baseline
  • runs/2026-06-26-e066fc0
  • runs/2026-07-05-7d5fd8a
  • runs/2026-07-24-f7e7d96
  • runs/2026-07-30-bc2a16c
  • runs/2026-07-30T220642Z-be8bfbc

Every write surface now keeps vector shadow tables current: PutItem,
UpdateItem, DeleteItem, batch and transactional writes, PartiQL, the
TTL sweep, and imports. Writes validate vector values and SearchSchema
attributes with error messages captured from real DynamoDB, storing
f32 index copies while the base table keeps full precision. Imports
sparse-skip invalid values the way backfill does, and batch writes
parse index definitions once per table.
@github-actions

Copy link
Copy Markdown
Contributor

Criterion Benchmark Results

Baseline is the per-benchmark median of the last 5 stored runs, so one unusually fast or slow runner cannot skew the comparison. The range column is the spread across those runs.

Benchmark Baseline (ns/iter) Range Current Change
batch_get_item_100 1,389,601 814,524 - 1,451,464 1,512,714 +8.9%
batch_write_item_25 1,119,577 533,898 - 1,182,554 1,132,683 +1.2%
delete_item 51,384 26,334 - 53,068 54,909 +6.9%
get_item 14,455 8,000 - 15,127 15,878 +9.8%
put_item/put_item/large 269,725 115,520 - 280,567 260,321 -3.5%
put_item/put_item/medium 44,503 19,445 - 46,845 45,879 +3.1%
put_item/put_item/small 25,143 10,759 - 26,885 25,927 +3.1%
query_base_table 1,093,125 666,833 - 1,164,732 1,131,772 +3.5%
query_gsi 25,592 12,359 - 26,517 26,814 +4.8%
scan_with_filter 8,217,608 5,182,664 - 8,785,317 8,704,276 +5.9%
transact_write_items_4 257,350 112,673 - 267,776 268,212 +4.2%
update_item 163,483 85,461 - 185,342 191,553 +17.2%

All benchmarks within 50% of the 5-run median.

Runs in the baseline
  • runs/2026-06-26-e066fc0
  • runs/2026-07-05-7d5fd8a
  • runs/2026-07-24-f7e7d96
  • runs/2026-07-30-bc2a16c
  • runs/2026-07-30T220642Z-be8bfbc

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.

1 participant