Skip to content
Mark Lauter edited this page Jun 2, 2026 · 2 revisions

FAQ

Short answers to recurring questions. For depth, follow the link in each answer.

Comparisons

How does this compare to DynamoDB Local?

Same shape, no container. DynamoDB Local runs a Java process with a JAR; DynamoDbLite runs in-process inside your .NET host. No container start-up cost on cold tests, no docker dependency in CI, and the database lifetime is tied to the DynamoDbClient instance rather than a sidecar.

The trade-off is parity. DynamoDB Local emulates the AWS service exhaustively; DynamoDbLite covers the surface in API Parity and stops there.

Can I run my existing test suite without changes?

Mostly. The supported IAmazonDynamoDB surface — table management, item CRUD, query, scan, batch, transactions, secondary indexes, TTL, tags, export/import — works the same way. Behavioral differences (synchronous deletion, instant TTL filtering, no consumed-capacity tracking, post-retrieval parallel-scan partitioning) are listed in API Parity.

If your tests use AWS SDK's DynamoDBContext (POCO mapping), it works against DynamoDbClient unchanged.

Setup and configuration

Why is Cache=Shared required for in-memory mode?

DynamoDbLite opens a fresh SQLite connection per operation. Without Cache=Shared, each connection sees a private, empty in-memory database — every operation looks like the first. With Cache=Shared, all connections that name the same Data Source see the same database for the lifetime of the process.

Why does my test see another test's data?

The Data Source name keys SQLite's shared cache. Two clients in the same process that use the same name share one database — including test classes constructed with the wiki's old fixed Data Source=DynamoDbLite literal. For test isolation, suffix the name with a unique value:

$"Data Source=app_{Guid.NewGuid():N};Mode=Memory;Cache=Shared"

See Getting Started for the full guidance and Recipe: xUnit per-test isolation.

When should I prefer file-based over in-memory?

Persistence across process restart, mobile apps that need offline storage, and integration tests that want to inspect the database from outside the test process. Otherwise prefer in-memory — it has no cleanup story to get wrong.

File-based stores opt into WAL mode by setting UseWriteAheadLog = true on DynamoDbLiteOptions (or calling WithWriteAheadLog() on the builder). WAL is off by default; see DI and Configuration for the contract.

Behavior and limits

Why does ConsistentRead = true throw on a GSI?

Matches DynamoDB. Strongly consistent reads are not supported on global secondary indexes; the AWS service rejects the request, and DynamoDbLite throws AmazonDynamoDBException with the same message. See Secondary Indexes.

Does parallel scan actually parallelize work?

No. TotalSegments and Segment are honored — each segment returns disjoint items, partitioned by an FNV-1a hash of the partition key — but the segmentation is applied after retrieval. Each call still does the full scan; only the result set is filtered down. Limit applies to the pre-segmentation row count.

If you fan out N parallel scan calls expecting roughly 1/N work each, you instead get N times the total work. Use parallel scan for result partitioning, not throughput.

Do I need a lock around concurrent writes?

No. SQLite serializes writers with its single-writer lock, and Microsoft.Data.Sqlite makes a blocked writer wait and retry rather than fail — an application-level lock is redundant. How long a contender waits is governed by CommandTimeout for in-memory stores and busy_timeout for file-backed stores. See Concurrency.

Why does IDisposable not have an async counterpart?

SQLite cleanup is synchronous. Adding IAsyncDisposable would wrap a synchronous call in a ValueTask for no actual async work. Use using var, not await using.

Operational

On Windows, why does File.Delete fail after my test runs?

SQLite holds an exclusive handle on the database file until the connection is disposed. If a test fixture tries to delete the .db file before disposing the DynamoDbClient, Windows reports the file as in use.

Order: dispose the client, then delete the file. The test fixtures in DynamoDbLite.Tests/Fixtures/FileBasedTestHelper.cs show the pattern.

What is MSL.DynamoDbLite versus DynamoDbLite?

DynamoDbLite is the assembly name and the namespace you using. MSL.DynamoDbLite is the NuGet package id — the prefix is the publisher's. Once published, you install MSL.DynamoDbLite; you reference types from DynamoDbLite. Until then, the wiki examples use a ProjectReference against the source repo.

Next steps

Clone this wiki locally