Skip to content
AWS aws databases 6 min read

What is DynamoDB?

Amazon DynamoDB is a fully managed, serverless NoSQL database. NoSQL means “not only SQL” — it is a database that does not use the traditional table-and-relationship model of SQL databases. “Serverless” means you never launch, patch, or size a server; AWS runs all the infrastructure for you. DynamoDB delivers single-digit-millisecond response times (under 10 milliseconds) no matter how much data you store or how many requests you send, which makes it a popular choice for high-traffic apps like games, shopping carts, IoT (Internet of Things — internet-connected devices), and user session stores.

Why DynamoDB exists

Traditional relational databases (the kind you query with SQL) slow down and become hard to scale once you have huge amounts of traffic. You eventually have to add bigger servers, manage read replicas, and tune queries. DynamoDB takes a different approach: it spreads your data across many servers automatically and keeps performance flat as you grow from one user to millions. You do not provision or manage any servers, and there is nothing to patch.

When to use DynamoDB (and when not to)

Use DynamoDB whenAvoid DynamoDB when
You know your access patterns up front (how you will read the data)You need flexible, ad-hoc queries and joins across many tables
You need predictable low latency at any scaleYou have complex reporting or analytics needs
Your workload is key-based lookups (e.g. “get user by ID”)You rely heavily on SQL transactions across many entities
You want zero server managementYour team only knows relational modeling and has no time to learn NoSQL design

For relational workloads, look at Amazon RDS or Amazon Aurora instead. See Choosing a database for a full comparison.

Core concepts: tables, items, attributes, and keys

DynamoDB has a small vocabulary. Learn these four words and you understand the model.

  • Table — a collection of data, like Users or Orders. Unlike SQL, a table has no fixed columns.
  • Item — a single record in a table, like one user. It is similar to a row in SQL. Each item can be up to 400 KB.
  • Attribute — a single field on an item, like email or age. It is similar to a column. Two items in the same table can have completely different attributes.
  • Primary key — the unique identifier for each item. This is the one piece you MUST define when you create the table, and it drives everything.

Primary keys

DynamoDB supports two kinds of primary key:

Key typeMade ofExampleUse it when
Partition key (simple)One attributeUserIdEach item is found by a single unique value
Partition key + sort key (composite)Two attributesUserId + OrderDateYou store many related items under one partition and want them sorted

The partition key decides which physical server (partition) stores the item. The sort key lets you keep many items under the same partition key and query them as a range (for example, “all orders for user 42 from January”).

The #1 gotcha: design around your access patterns first

This is the single most important thing to understand, and it trips up nearly everyone coming from SQL.

Warning: In a relational database you model your entities first (users, orders, products) and then write whatever queries you want later. In DynamoDB you do the OPPOSITE: you list every query your application will ever run FIRST, then design your table and keys to serve those queries. Skipping this step is the #1 source of DynamoDB regret.

DynamoDB does not do efficient ad-hoc queries or joins. If you did not plan a query in your key design, your only option is a Scan — which reads the entire table and is slow and expensive at scale. Many advanced applications use single-table design, where multiple entity types (users, orders, products) all live in one table, packed together using carefully crafted partition and sort keys so that a single fast query returns related data. This feels strange at first, but it is what makes DynamoDB fast and cheap.

The practical rule: write down your access patterns on paper before you create a single table.

Creating your first table

Say we want a Users table keyed by a simple UserId partition key.

Using the AWS Management Console

  1. Sign in to the AWS Management Console and open the DynamoDB service.
  2. In the left menu, choose Tables, then click Create table.
  3. For Table name, enter Users.
  4. For Partition key, enter UserId and choose type String.
  5. Leave Sort key empty for this simple example.
  6. Under Table settings, keep Default settings (this uses on-demand capacity, which scales automatically).
  7. Click Create table. It is ready in a few seconds.

Using the AWS CLI

aws dynamodb create-table \
  --table-name Users \
  --attribute-definitions AttributeName=UserId,AttributeType=S \
  --key-schema AttributeName=UserId,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST

KeyType=HASH means partition key. PAY_PER_REQUEST is on-demand billing — you pay per request with no capacity to manage.

Output:

{
    "TableDescription": {
        "TableName": "Users",
        "TableStatus": "CREATING",
        "TableArn": "arn:aws:dynamodb:us-east-1:123456789012:table/Users",
        "BillingModeSummary": {
            "BillingMode": "PAY_PER_REQUEST"
        }
    }
}

Writing and reading an item

# Write one user
aws dynamodb put-item \
  --table-name Users \
  --item '{"UserId": {"S": "u-1001"}, "email": {"S": "[email protected]"}, "age": {"N": "36"}}'

# Read it back by its key
aws dynamodb get-item \
  --table-name Users \
  --key '{"UserId": {"S": "u-1001"}}'

Notice each value is tagged with its type: S for string, N for number. The number is written as a quoted string in JSON but stored as a real number.

Output:

{
    "Item": {
        "UserId": {"S": "u-1001"},
        "email": {"S": "[email protected]"},
        "age": {"N": "36"}
    }
}

Defining a table as code (CloudFormation)

Resources:
  UsersTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Users
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: UserId
          AttributeType: S
      KeySchema:
        - AttributeName: UserId
          KeyType: HASH

A note on cost

With on-demand (PAY_PER_REQUEST) billing in 2026, you pay roughly $1.25 per million write requests and $0.25 per million read requests, plus about $0.25 per GB-month of storage. A small app doing a few thousand requests a day costs cents per month. The first 25 GB of storage is free under the AWS Free Tier. The expensive mistake is running frequent table Scans — that bills you for reading every item every time, so design keys that let you use targeted queries instead.

Best practices

  • Write down ALL your access patterns before designing the table — this is the most important DynamoDB habit.
  • Prefer Query (which uses keys) over Scan (which reads everything); a Scan on a large table is slow and costly.
  • Start with on-demand (PAY_PER_REQUEST) billing; switch to provisioned capacity only once your traffic is predictable.
  • Use a composite primary key (partition + sort) when you store many related items, so you can query ranges efficiently.
  • Add secondary indexes for query patterns your primary key cannot serve — but only the ones you actually need.
  • Keep items small (well under the 400 KB limit) and store large blobs in Amazon S3, saving just the S3 link in DynamoDB.
  • Enable point-in-time recovery for any table holding important data.
Last updated June 15, 2026
Was this helpful?