How to Query DynamoDB Locally - Complete Development Guide
Developing against DynamoDB Local eliminates AWS costs, speeds up iteration, and enables offline development. This guide shows you how to set up DynamoDB locally and query it efficiently using DocKit.
Why Query DynamoDB Locally?
💰 Zero AWS Costs
Cloud DynamoDB Costs:
- Read/Write Capacity Units: $0.25-1.25 per million requests
- Storage: $0.25 per GB-month
- Data Transfer: $0.09 per GB
Development Team Impact:
5 developers × 1,000 queries/day × 30 days = 150,000 requests/month
Cost: ~$20-50/month (just for development!)DynamoDB Local:
- $0 - Completely free
⚡ Faster Development Cycle
| Operation | AWS DynamoDB | DynamoDB Local |
|---|---|---|
| Query Latency | 10-50ms | < 5ms |
| Table Creation | ~30s | < 1s |
| Schema Changes | Slow (production risk) | Instant |
| Reset Data | Manual deletion | Docker restart |
🔒 No AWS Credentials Required
- No IAM setup needed for local development
- No credential rotation
- No accidental production access
- Junior developers can test safely
✈️ Offline Development
Work anywhere:
- Flights and travel
- Remote locations
- Network outages
- Restricted environments
Quick Start: DynamoDB Local Setup
Option 1: Docker (Recommended)
Step 1: Run DynamoDB Local
docker run -d \
--name dynamodb-local \
-p 8000:8000 \
amazon/dynamodb-localStep 2: Verify it's running
curl http://localhost:8000
# Should return: "healthy"Step 3: Connect with DocKit
- Open DocKit
- Add Connection → DynamoDB
- Select "DynamoDB Local"
- Endpoint:
http://localhost:8000 - Region:
us-east-1(any region works locally) - Access Key:
fakekey(any value works) - Secret Key:
fakesecret(any value works)
✅ You're ready to query!
Option 2: JAR File (No Docker)
Step 1: Download DynamoDB Local
# Create directory
mkdir ~/dynamodb-local
cd ~/dynamodb-local
# Download (1.21.0 as of 2026)
wget https://d1ni2b6xgvw0s0.cloudfront.net/v2.x/dynamodb_local_latest.tar.gz
# Extract
tar -xvzf dynamodb_local_latest.tar.gzStep 2: Run DynamoDB Local
java -Djava.library.path=./DynamoDBLocal_lib \
-jar DynamoDBLocal.jar \
-sharedDbStep 3: Connect with DocKit (same as Docker option above)
Option 3: npm (For Node.js Projects)
Step 1: Install as dev dependency
npm install --save-dev dynamodb-localStep 2: Add to package.json
{
"scripts": {
"dynamodb": "dynamodb-local",
"test": "npm run dynamodb & sleep 2 && jest"
}
}Step 3: Start and connect
npm run dynamodb
# Then connect DocKit to localhost:8000Creating Your First Local Table
Using DocKit GUI
- Connect to DynamoDB Local (see Quick Start above)
- Create Table:
- Click "Create Table" button
- Table Name:
Users - Partition Key:
userId(String) - (Optional) Sort Key:
email(String) - Read/Write Capacity: Any values (ignored locally)
- Click "Create"
Table created in < 1 second!
Using AWS CLI
aws dynamodb create-table \
--endpoint-url http://localhost:8000 \
--table-name Users \
--attribute-definitions \
AttributeName=userId,AttributeType=S \
--key-schema \
AttributeName=userId,KeyType=HASH \
--billing-mode PAY_PER_REQUESTNote: Always use --endpoint-url http://localhost:8000 for local commands.
Querying DynamoDB Local with DocKit
Visual Query Builder
1. Insert Sample Data
Click "Insert Item" in DocKit:
{
"userId": "user-001",
"email": "[email protected]",
"name": "Alice Smith",
"createdAt": "2026-01-28T10:00:00Z"
}2. Query Using Visual Builder
- Table:
Users - Operation:
Query - Partition Key:
userId = "user-001" - Execute (Cmd/Ctrl + Enter)
Result:
{
"Items": [
{
"userId": "user-001",
"email": "[email protected]",
"name": "Alice Smith",
"createdAt": "2026-01-28T10:00:00Z"
}
],
"Count": 1
}PartiQL Editor
DocKit's PartiQL editor works identically with local and cloud DynamoDB:
Select:
SELECT * FROM Users WHERE userId = 'user-001'Insert:
INSERT INTO Users VALUE {
'userId': 'user-002',
'email': '[email protected]',
'name': 'Bob Johnson'
}Update:
UPDATE Users
SET email = '[email protected]'
WHERE userId = 'user-001'Delete:
DELETE FROM Users WHERE userId = 'user-002'Advanced Local Development Patterns
1. Reset Data Between Tests
Docker:
# Stop and remove container (deletes all data)
docker stop dynamodb-local
docker rm dynamodb-local
# Start fresh instance
docker run -d --name dynamodb-local -p 8000:8000 amazon/dynamodb-localJAR with Persistence:
# Run with data directory
java -Djava.library.path=./DynamoDBLocal_lib \
-jar DynamoDBLocal.jar \
-sharedDb \
-dbPath ./data
# Reset data
rm -rf ./data2. Seed Data Script
Node.js Example:
// seed-local-dynamodb.js
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
const { DynamoDBDocumentClient, PutCommand } = require('@aws-sdk/lib-dynamodb');
const client = new DynamoDBClient({
endpoint: 'http://localhost:8000',
region: 'us-east-1',
credentials: {
accessKeyId: 'fakekey',
secretAccessKey: 'fakesecret'
}
});
const docClient = DynamoDBDocumentClient.from(client);
const users = [
{ userId: 'user-001', name: 'Alice', email: '[email protected]' },
{ userId: 'user-002', name: 'Bob', email: '[email protected]' },
{ userId: 'user-003', name: 'Charlie', email: '[email protected]' }
];
async function seed() {
for (const user of users) {
await docClient.send(new PutCommand({
TableName: 'Users',
Item: user
}));
}
console.log('Seeded', users.length, 'users');
}
seed();Run:
node seed-local-dynamodb.js
# Then query in DocKit3. Docker Compose for Team Consistency
docker-compose.yml:
version: '3.8'
services:
dynamodb-local:
image: amazon/dynamodb-local
container_name: dynamodb
ports:
- "8000:8000"
command: "-jar DynamoDBLocal.jar -sharedDb"
volumes:
- ./dynamodb-data:/home/dynamodblocal/dataUsage:
# Start
docker-compose up -d
# Stop (preserve data)
docker-compose down
# Reset data
rm -rf ./dynamodb-data
docker-compose up -dCI/CD Integration
GitHub Actions Example
name: Test with DynamoDB Local
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
dynamodb:
image: amazon/dynamodb-local
ports:
- 8000:8000
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Create test tables
run: npm run create-tables
env:
DYNAMODB_ENDPOINT: http://localhost:8000
- name: Run tests
run: npm testJest Testing
jest.config.js:
module.exports = {
setupFilesAfterEnv: ['./test-setup.js'],
testEnvironment: 'node'
};test-setup.js:
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
const { CreateTableCommand } = require('@aws-sdk/client-dynamodb');
const client = new DynamoDBClient({
endpoint: process.env.DYNAMODB_ENDPOINT || 'http://localhost:8000',
region: 'us-east-1',
credentials: { accessKeyId: 'test', secretAccessKey: 'test' }
});
beforeAll(async () => {
// Create test table
await client.send(new CreateTableCommand({
TableName: 'Users',
KeySchema: [{ AttributeName: 'userId', KeyType: 'HASH' }],
AttributeDefinitions: [{ AttributeName: 'userId', AttributeType: 'S' }],
BillingMode: 'PAY_PER_REQUEST'
}));
});Differences: Local vs. Cloud DynamoDB
Features NOT Available Locally
❌ DynamoDB Streams: No stream processing ❌ Global Tables: Multi-region replication ❌ Point-in-Time Recovery: Backups ❌ Auto Scaling: Capacity management ❌ CloudWatch Metrics: Monitoring ❌ IAM Authentication: Always uses fake credentials
Behavior Differences
⚠️ Eventual Consistency: Local is always strongly consistent ⚠️ Capacity Units: Ignored (no throttling) ⚠️ Data Persistence: Depends on configuration (in-memory vs. file)
Recommendation: Use local for 99% of development, test production behavior in staging.
Best Practices
1. Use Environment Variables
const DYNAMODB_CONFIG = {
endpoint: process.env.DYNAMODB_ENDPOINT,
region: process.env.AWS_REGION || 'us-east-1',
credentials: process.env.DYNAMODB_ENDPOINT ? {
accessKeyId: 'local',
secretAccessKey: 'local'
} : undefined // Use default AWS credentials in production
};.env.development:
DYNAMODB_ENDPOINT=http://localhost:8000.env.production:
# DYNAMODB_ENDPOINT not set = use AWS2. Shared Database vs. Per-Table Files
Shared Database (recommended):
java -jar DynamoDBLocal.jar -sharedDb- One file for all tables
- Faster
- Simpler
Per-Table Files:
java -jar DynamoDBLocal.jar- Separate file per table
- Better isolation
- Easier to debug
3. Version Pin
Specify exact DynamoDB Local version:
Docker:
# Instead of `latest`, use specific version
image: amazon/dynamodb-local:2.0.0npm:
{
"devDependencies": {
"dynamodb-local": "2.0.0"
}
}Prevents unexpected behavior changes.
Debugging Local Queries
Enable Verbose Logging
JAR:
java -Djava.library.path=./DynamoDBLocal_lib \
-jar DynamoDBLocal.jar \
-sharedDb \
-inMemory \
-port 8000 \
-cors "*"Docker:
docker logs dynamodb-localCommon Issues
Problem: Connection Refused
Error: connect ECONNREFUSED 127.0.0.1:8000Solution:
# Check if running
docker ps | grep dynamodb
# Start if not running
docker start dynamodb-localProblem: InvalidSignatureException
InvalidSignatureException: The request signature we calculated does not matchSolution: Use any credentials (they're not validated locally):
credentials: {
accessKeyId: 'test',
secretAccessKey: 'test'
}Problem: Table Already Exists
ResourceInUseException: Table already existsSolution:
# Delete table first
aws dynamodb delete-table \
--endpoint-url http://localhost:8000 \
--table-name Users
# Or reset entire database (Docker)
docker restart dynamodb-localDocKit Features for Local Development
1. Connection Profiles
Save multiple local setups:
- Local (in-memory):
http://localhost:8000 - Local (persistent):
http://localhost:8001(different port) - Docker Compose:
http://localhost:8002
Switch instantly with dropdown.
2. Query Templates
Save reusable local queries:
Create Test User:
INSERT INTO Users VALUE {
'userId': 'test-{{timestamp}}',
'email': '[email protected]',
'createdAt': '{{now}}'
}DocKit replaces placeholders automatically.
3. Export/Import Data
Export from Local:
- Query:
SELECT * FROM Users - Export → JSON
- Save as
users-fixture.json
Import to Local:
- Import → Select
users-fixture.json - Table:
Users - Batch import
Perfect for test fixtures!
Migration from Local to Production
1. Test Data Cleanup
Never deploy test data:
# WRONG - test data in production
aws dynamodb put-item --table-name Users --item '{...}'
# RIGHT - seed only in local
if [ "$ENV" = "development" ]; then
npm run seed-local-data
fi2. Schema Migration
Use Infrastructure as Code (IaC):
Terraform:
resource "aws_dynamodb_table" "users" {
name = "Users"
billing_mode = "PAY_PER_REQUEST"
hash_key = "userId"
attribute {
name = "userId"
type = "S"
}
}Deploy same schema locally and in production.
3. Endpoint Configuration
const getDynamoDBClient = () => {
const config = {
region: process.env.AWS_REGION || 'us-east-1'
};
if (process.env.NODE_ENV === 'development') {
config.endpoint = 'http://localhost:8000';
config.credentials = {
accessKeyId: 'local',
secretAccessKey: 'local'
};
}
return new DynamoDBClient(config);
};Learn More
- DynamoDB GUI Client - DocKit DynamoDB features
- DynamoDB PartiQL Editor - PartiQL syntax guide
- Best DynamoDB GUI Clients - Tool comparison
- Download DocKit - Get started free
Quick Reference Commands
Docker:
# Start
docker run -d -p 8000:8000 --name dynamodb-local amazon/dynamodb-local
# Stop
docker stop dynamodb-local
# Restart (clear data)
docker rm dynamodb-local && docker run -d -p 8000:8000 --name dynamodb-local amazon/dynamodb-localAWS CLI:
# List tables
aws dynamodb list-tables --endpoint-url http://localhost:8000
# Describe table
aws dynamodb describe-table --table-name Users --endpoint-url http://localhost:8000
# Delete table
aws dynamodb delete-table --table-name Users --endpoint-url http://localhost:8000DocKit Connection:
Endpoint: http://localhost:8000
Region: us-east-1
Access Key: (any value)
Secret Key: (any value)Last updated: January 2026