accesspatterns.dev
← All models

user-data

Account & Settings

Two entity types under one key, told apart by the sort key.

A user's account record and their settings always travel together, so they share a partition and are separated by a sort-key label rather than living in two tables. One Query returns both; a GetItem still fetches either on its own.

The model

Account

The account record: who the user is.

pk
USER#<userId>
sk
ACCOUNT

Attributes: email (S), displayName (S), createdAt (N)

Settings

The user's preferences, read on almost every page.

pk
USER#<userId>
sk
SETTINGS

Attributes: theme (S), locale (S), emailDigest (S)

Access patterns

  • QueryLoad an account with its settings

    Both records for a user, in one read.

  • GetItemLoad an account

    Just the account record.

Design notes

The sort key is a label, not a sequencewhy

ACCOUNT and SETTINGS are not ordered, they are named. Compare Feature Flags, where one partition holds many items of a single type and the sort key picks which one; here a partition holds one item of each of two types, and the sort key says what each is. That distinction - many-of-one versus one-of-each - is the idea every later model builds on.

Co-located because they are read togetherwhy

Splitting settings into their own table would mean two round trips on every page that needs both. They share a partition because the access pattern pairs them, not because they are conceptually similar.

The over-fetch is not where you would expecttrade-off

Reading both items rather than one costs no extra read capacity here: capacity is charged in 4 KB blocks, and an account plus its settings sit well inside one. What the extra item does cost is bytes on the wire and work in the caller. The habit worth keeping is the one that pays at scale - fetch what the caller uses - but the meter beside this table will not reward it on rows this small, and pretending otherwise teaches a rule the numbers contradict.

Taught in the course

account-settings
Try an example

Both records for a user, in one read.

PK(pk)
SK(sk)
createdAt
displayName
email
emailDigest
locale
theme
USER#u-ada
ACCOUNTS
1750377600N
AdaS
ada@example.comS
USER#u-ada
SETTINGSS
weeklyS
en-GBS
darkS
USER#u-raj
ACCOUNTS
1771113600N
RajS
raj@example.comS
USER#u-raj
SETTINGSS
offS
en-GBS
lightS
USER#u-mei
ACCOUNTS
1784073600N
MeiS
mei@example.comS
USER#u-mei
SETTINGSS
dailyS
zh-CNS
systemS

Run an operation to see the raw engine response.

table account-settingskeys PK / SKitems 6

The in-browser engine is a preview build. Transactions, vector search, streams, tags and TTL are among the operations it doesn't implement yet.