Compatibility and limitations
Conformance answers "does Dynoxide behave like DynamoDB on the things it implements". This page answers the other half: what it implements, what it doesn't, and where it knowingly differs.
What's implemented
Every DynamoDB operation with a meaningful local equivalent: item CRUD, Query and Scan, batch reads and writes, transactions, table management, PartiQL, streams, TTL, and resource tags. GSIs and LSIs are both supported, including UpdateTable adding or removing a GSI with existing rows backfilled into it.
All ten attribute types work (S, N, B, BOOL, NULL, SS, NS, BS, L, M), and the full expression syntax is supported: condition, filter, key-condition, projection and update expressions, with attribute_exists, attribute_not_exists, attribute_type, begins_with, contains and size.
That's 27 of the 27 applicable operations. The compatibility summary has the operation-by-operation table, and the live capability matrix compares every emulator feature by feature.
What's not implemented, and why
Thirty-nine DynamoDB operations are absent on purpose. They're cloud-infrastructure features with nothing to emulate locally: backup and point-in-time restore, global tables, Kinesis streaming destinations, table import and export, reserved capacity and account limits, contributor insights, resource policies, and table replicas.
These are "not applicable" rather than "not implemented". There's no partial version of a global table on your laptop. Call one and you get an UnknownOperationException.
Behavioural differences
Four things behave differently from real DynamoDB. All four are visible from your test code, so they're worth knowing before you write assertions against them.
ConsistentRead is accepted but changes nothing. SQLite is strongly consistent, so every read already is. You can't reproduce an eventually-consistent read locally, which means a bug that only shows up under eventual consistency won't surface here.
Streams expose a single shard. DescribeStream returns one shard, and ExclusiveStartShardId and Limit are accepted but ignored. Code that walks a multi-shard topology or handles shard splits has no local equivalent to exercise. See Streams.
Transaction-contention errors aren't emulated. TransactionConflictException and TransactionInProgressException never fire, because there's no concurrent contention in a single process. If your retry logic keys off them, it won't be exercised locally.
Number arithmetic uses rust_decimal. It's arbitrary-precision and matches DynamoDB across the ranges that matter, but DynamoDB's implementation is proprietary and the two may diverge at extreme edges.
Legacy pre-2015 parameters
The pre-expression API has partial support. Only AttributeUpdates is actually processed:
| Parameter | Status |
|---|---|
AttributeUpdates (UpdateItem) |
Partial - PUT, ADD and DELETE actions work, used when UpdateExpression is absent |
Expected |
Accepted, ignored - use ConditionExpression |
ScanFilter / QueryFilter |
Accepted, ignored - use FilterExpression |
KeyConditions (Query) |
Accepted, ignored - use KeyConditionExpression |
AttributesToGet |
Accepted, ignored - use ProjectionExpression |
ConditionalOperator |
Accepted, ignored - use ConditionExpression with AND/OR |
"Accepted, ignored" is the trap: a request using one of these succeeds, and the filter simply doesn't apply. Prefer the expression-based API throughout.
Error codes
Errors carry DynamoDB-compatible codes with the com.amazonaws.dynamodb.v20120810# prefix: ResourceNotFoundException, ResourceInUseException, ValidationException, ConditionalCheckFailedException (with the item attached where DynamoDB attaches it), TransactionCanceledException, ItemCollectionSizeLimitExceededException, ProvisionedThroughputExceededException, LimitExceededException, DuplicateItemException, and InternalServerError.
Message text is matched to real DynamoDB wherever the conformance suite covers it, including the 1 validation error detected: envelope on the request-validation families that carry it and bare messages on the families that don't.
Not a production database
Dynoxide is built for local development, testing, and CI. It doesn't emulate capacity management, throttling, replication, or IAM, and it isn't a hosted database. If you need any of that, you need real DynamoDB.