A service that simulates DynamoDB with inconsistent reads, throughput limits, and partial batch get/write operations.
Based on the AWS documentation, here are key limitations of DynamoDB Local that baddb can simulate for better testing:
- DynamoDB Local: Ignores provisioned throughput settings, no throttling
- baddb: Simulates ProvisionedThroughputExceededException and throughput limits to verify system behavior under traffic that exceeds provisioned throughput.
- DynamoDB Local: All reads are technically strongly consistent
- baddb: Configurable eventual consistency delays via metadata table to verify system behavior when reading stale data.
- DynamoDB Local: Doesn't simulate partial batch failures
- baddb: Can simulate unprocessed items in batch operations to verify system behavior with partial results.
While baddb is frequently tested against DynamoDB Local to ensure behavioral accuracy, it may still exhibit differences from actual AWS DynamoDB behavior. Key considerations:
- Behavioral Differences: Despite extensive testing, some edge cases may behave differently than AWS DynamoDB
- Active Development: Behavior may change between versions
- Limited Coverage: Not all DynamoDB features are implemented (see below for current status)
Recommendation: Always validate your application against actual AWS DynamoDB before production deployment. Use baddb primarily for controlled testing scenarios where you need to simulate specific failure conditions that DynamoDB Local cannot provide.
Feedback Welcome: If you discover behavioral differences, please report them as issues to help improve accuracy.
go install github.com/ocowchun/baddb/cli/baddb# run baddb server on port 9527, if not specified, the default port is 9527
baddb --port 9527aws dynamodb create-table \
--table-name MusicCollection\
--attribute-definitions AttributeName=Artist,AttributeType=S AttributeName=SongTitle,AttributeType=S \
--key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--endpoint-url http://localhost:9527
# configure delay time as 60 seconds
# tableDelaySeconds for get-item and query
# gsiDelaySeconds for query GSI
aws dynamodb put-item \
--table-name baddb_table_metadata \
--item '{"tableName": {"S": "MusicCollection"}, "tableDelaySeconds": {"N": "60"}, "gsiDelaySeconds": {"N": "60"}}' \
--endpoint-url http://localhost:9527
aws dynamodb put-item \
--table-name MusicCollection \
--item '{"Artist": {"S": "the Jimi Hendrix Experience"}, "SongTitle": {"S": "Little Wing"}, "AlbumTitle": {"S": "Axis: Bold as Love"}}' \
--endpoint-url http://localhost:9527
# see nothing if consistent-read is false and the command is called within 60 seconds after above command
aws dynamodb get-item \
--table-name MusicCollection \
--key '{"Artist": {"S": "the Jimi Hendrix Experience"}, "SongTitle": {"S": "Little Wing"}}' \
--no-consistent-read \
--endpoint-url http://localhost:9527
# see item immediately
aws dynamodb get-item \
--table-name MusicCollection \
--key '{"Artist": {"S": "No One You Know"}, "SongTitle": {"S": "Call Me Today"}}' \
--consistent-read \
--endpoint-url http://localhost:9527aws dynamodb create-table \
--table-name MusicCollection\
--attribute-definitions AttributeName=Artist,AttributeType=S AttributeName=SongTitle,AttributeType=S \
--key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--endpoint-url http://localhost:9527
# the next 5 get/put/update/delete will failed
# if the batchGet/batchWrite has 6 requests, the first 5 request will return in unprocessed
# you also need to consider retry, do the math yourself
aws dynamodb put-item \
--table-name baddb_table_metadata \
--item '{"tableName": {"S": "MusicCollection"}, "unprocessedRequests": {"N": "5"}}' \
--endpoint-url http://localhost:9527
#
aws dynamodb batch-write-item \
--request-items '{ "MusicCollection": [{"PutRequest": {"Item": {"Artist": {"S": "the Jimi Hendrix Experience"}, "SongTitle": {"S": "Little Wing"}}}}] }' \
--endpoint-url http://localhost:9527
baddb uses float64 to represent number, which is not compatible with DynamoDB's number type. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes.Number
- AttributesToGet
- ConsistentRead
- ProjectionExpression
- ReturnConsumedCapacity
- DeleteRequest
- PutRequest
- ReturnConsumedCapacity
- ReturnItemCollectionMetrics
- AttributeDefinitions
- BillingMode
- DeletionProtectionEnabled
- GlobalSecondaryIndexes
- KeySchema
- LocalSecondaryIndexes
- OnDemandThroughput
- ProvisionedThroughput
- ResourcePolicy
- SSESpecification
- StreamSpecification
- TableClass
- TableName
- Tags
- WarmThroughput
- ConditionalOperator
- ConditionExpression
- Expected
- ExpressionAttributeNames
- ExpressionAttributeValues
- Key
- ReturnConsumedCapacity
- ReturnItemCollectionMetrics
- ReturnValues
- ReturnValuesOnConditionCheckFailure
- TableName
- TableName
- TableName
- AttributesToGet
- ConsistentRead
- ExpressionAttributeNames
- Keys
- ProjectionExpression
- ReturnConsumedCapacity
- TableName
TBD
- ConditionalOperator
- ConditionExpression
- Expected
- ExpressionAttributeNames
- ExpressionAttributeValues
- Item
- ReturnConsumedCapacity
- ReturnItemCollectionMetrics
- ReturnValues
- ReturnValuesOnConditionCheckFailure
- TableName
- AttributesToGet
- ConditionalOperator
- ConsistentRead
- ExclusiveStartKey
- ExpressionAttributeNames
- ExpressionAttributeValues
- FilterExpression
- IndexName
- KeyConditionExpression
- KeyConditions
- Limit
- ProjectionExpression
- QueryFilter
- ReturnConsumedCapacity
- ScanIndexForward
- Select
- TableName
- AttributesToGet
- ConditionalOperator
- ConsistentRead
- ExclusiveStartKey
- ExpressionAttributeNames
- ExpressionAttributeValues
- FilterExpression
- IndexName
- Limit
- ProjectionExpression
- ReturnConsumedCapacity
- ReturnConsumedCapacity
- ScanFilter
- Segment
- Select
- TableName
- TotalSegments
TBD
- ClientRequestToken
- ReturnConsumedCapacity
- ReturnItemCollectionMetrics
- TransactItems
- TableName
- AttributeDefinitions
- BillingMode
- DeletionProtectionEnabled
- GlobalSecondaryIndexUpdates
- GlobalTableWitnessUpdates
- MultiRegionConsistency
- OnDemandThroughput
- ProvisionedThroughput
- ReplicaUpdates
- SSESpecification
- StreamSpecification
- TableClass
- WarmThroughput
TBD