Skip to content

Two read paths, one item

The same items answer "what happened last" and "what is relevant", through two different reads.

Why

An assistant needs two different things from its history. It needs the last few messages, in order, every single turn. And occasionally it needs the one thing the user said three weeks ago that bears on what they just asked. Those are different questions, and they want different reads.

The first is a Query on the session partition, read backwards with a Limit. It is the cheapest read in the course: the key decides what to read, nothing is scanned and thrown away, and the order is exact.

The second is a vector search, and the decision that makes it work is what the index is partitioned by. The SearchSchema here declares userId as its HASH, not sessionId. Partition by session and relevance can only ever reach inside the conversation you are already in, which is the one place recency has already covered. Partition by user and it reaches across every conversation they have ever had. That is the entire reason for keeping this in DynamoDB beside the items rather than in a separate vector database.

There is no join and no synchronisation between the two. The index is maintained as part of the base write, so a message is searchable the moment it is written. Merging the two result sets is your application's job, and there is no ranking that combines a sort order with a similarity score for you. That is a judgement about your product, and DynamoDB is right not to guess at it.

A vector index is a second read path over the same items; partition it by the axis relevance needs to cross, which is usually not the one recency already covers.

Try it. Then change it.

Predict what each request will do. Run it, inspect the response, then change a value in the workbench and try again.

  1. The recency window: one session's partition, read backwards, capped at six. Cheap, exactly ordered, and completely blind to anything said in an earlier session.

  2. "How did we decide to do the kubernetes rollout", scoped to one user rather than one session. The answers come from a conversation nearly a month old, which the recency window above would never have reached.

  3. Fetch one of those search hits straight from the table. Same keys, same text, plus the embedding the search results left out. The index is a second read path over your items, not a second copy of them.

Built on this

AgentMemoryDynamoDB workbench
Ready to run
Explore an access patternSelect to load & run

The recency window: one session's partition, read backwards, capped at six. Cheap, exactly ordered, and completely blind to anything said in an earlier session.

Request
Execute against the local Dynoxide engine
ReturnedFiltered outChanged
pk(pk)
sk(sk)
userId
text
embedding
SESSION#s-101
TS#2026-08-27T00:00:00ZS
u-adaS
We should roll the API out to Kubernetes rather than the old VM fleetS
[-0.0109, 0.033, 0.0473, … 384]L
SESSION#s-101
TS#2026-08-27T00:15:00ZS
u-adaS
The rollout needs a readiness probe or traffic hits pods that aren't upS
[0.0838, -0.0244, 0.0637, … 384]L
SESSION#s-101
TS#2026-08-27T00:30:00ZS
u-adaS
Let's cap the rollout at 25 percent surge so a bad image can't take everything downS
[-0.0119, 0.0706, 0.0364, … 384]L
SESSION#s-101
TS#2026-08-27T00:45:00ZS
u-adaS
I've written the deployment manifest with resource requests and limitsS
[0.0373, 0.0088, 0.0379, … 384]L
SESSION#s-101
TS#2026-08-27T01:00:00ZS
u-adaS
Remember the cluster autoscaler won't scale down while a pod has no disruption budgetS
[0.0645, 0.0004, -0.0028, … 384]L
SESSION#s-101
TS#2026-08-27T01:15:00ZS
u-adaS
Rollback is a single command once the previous replica set is still aroundS
[-0.0499, 0.0065, 0.017, … 384]L
SESSION#s-102
TS#2026-09-10T00:00:00ZS
u-adaS
The invoice totals are off by a penny on multi-currency accountsS
[-0.0236, 0.0043, 0.0024, … 384]L
SESSION#s-102
TS#2026-09-10T00:15:00ZS
u-adaS
It's a rounding bug: we round each line rather than the sumS
[-0.058, 0.0524, 0.0121, … 384]L
SESSION#s-102
TS#2026-09-10T00:30:00ZS
u-adaS
Store amounts in minor units as integers and the whole class of bug goes awayS
[0.0164, 0.0939, -0.0558, … 384]L
SESSION#s-102
TS#2026-09-10T00:45:00ZS
u-adaS
I'll add a test that a three-line invoice in euros sums exactlyS
[-0.0708, -0.0262, -0.0698, … 384]L
SESSION#s-102
TS#2026-09-10T01:00:00ZS
u-adaS
Refunds have the same problem on partial amountsS
[-0.0382, 0.0442, 0.0863, … 384]L
SESSION#s-102
TS#2026-09-10T01:15:00ZS
u-adaS
Ship the integer change first, then backfill the historic rowsS
[-0.018, 0.0572, -0.0528, … 384]L
SESSION#s-103
TS#2026-09-21T00:00:00ZS
u-adaS
The settings page collapses to one column below 640 pixelsS
[0.0331, 0.0595, -0.0309, … 384]L
SESSION#s-103
TS#2026-09-21T00:15:00ZS
u-adaS
That's the grid falling back rather than a media query firingS
[0.0501, -0.021, -0.0199, … 384]L
SESSION#s-103
TS#2026-09-21T00:30:00ZS
u-adaS
Use a minmax track so it reflows instead of snappingS
[-0.0204, -0.0325, 0.0066, … 384]L
SESSION#s-103
TS#2026-09-21T00:45:00ZS
u-adaS
The sidebar still overlaps the content at exactly 641 pixelsS
[0.0259, 0.0453, 0.0465, … 384]L
SESSION#s-103
TS#2026-09-21T01:00:00ZS
u-adaS
Give the sidebar its own container query and stop guessing at breakpointsS
[0.011, 0.0554, 0.0946, … 384]L
SESSION#s-103
TS#2026-09-21T01:15:00ZS
u-adaS
Looks right on a narrow phone nowS
[-0.0193, 0.0517, 0.0483, … 384]L
SESSION#s-201
TS#2026-09-18T00:00:00ZS
u-linusS
Can you summarise last quarter's support volume by product areaS
[0.0539, -0.0202, -0.0069, … 384]L
SESSION#s-201
TS#2026-09-18T00:15:00ZS
u-linusS
Sign-in problems are the single biggest bucket by some distanceS
[0.061, 0.0376, 0.0279, … 384]L
SESSION#s-201
TS#2026-09-18T00:30:00ZS
u-linusS
Most of those are expired magic links rather than forgotten passwordsS
[-0.066, -0.0664, -0.0514, … 384]L
SESSION#s-201
TS#2026-09-18T00:45:00ZS
u-linusS
Worth shortening the link copy before we touch the auth flow itselfS
[-0.1121, 0.0116, 0.019, … 384]L
Awaiting request
Your next query starts here.

Choose an access pattern above, or build your own request. See what comes back and what it costs.

Powered by DynoxideWASMStarts on your first run · Runs locally in your browser