> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensor9.com/llms.txt
> Use this file to discover all available pages before exploring further.

# DynamoDB

> DynamoDB APIs with Cloud Adapter.

This page describes how DynamoDB maps to services in the environment where the application runs, including backend choices, supported operations and service-specific behavior.

## Supported environments

* Akamai
* Azure
* DigitalOcean
* Google Cloud
* OCI
* Private Kubernetes
* Scaleway

Check the operation and capability tables for the behavior your application depends on. A supported environment does not imply that every operation of the origin service is available.

## How the backends compare

Each row compares a capability of DynamoDB with its adaptation on each backend.
A dash means this profile does not state the capability for that backend.

### Cloud Adapter

| Capability | DynamoDB | Akamai, DigitalOcean, Private Kubernetes, and Scaleway | Azure · Azure Cosmos DB (provisioned) | Azure · Azure Cosmos DB (serverless) | Google Cloud · Firestore | Google Cloud · Cloud Spanner | Google Cloud · Cloud Bigtable | Google Cloud · Cloud SQL for PostgreSQL | OCI |
| - | - | - | - | - | - | - | - | - | - |
| Numeric precision · accepted values | up to 38 significant digits | the same value, stored exactly | at most 15 significant digits | at most 15 significant digits | - | - | - | the same value, stored exactly | - |
| Read consistency · per-read control | per-request ConsistentRead | always strong (flag-independent) | strong base-table and LSI reads; GSI visibility is eventual | strong base-table and LSI reads; managed GSIs require provisioned Cosmos | always strong (flag-independent) | - | - | always strong (flag-independent) | - |
| Secondary indexes · index types | GSI / LSI | PostgreSQL indexes updated with the item | - | - | - | - | base-table access only | - | - |
| Cross-partition transactions · multi-item writes | Yes | Partial - serializable transactions; stream-enabled tables are excluded | - | - | - | - | - | - | - |
| DynamoDB Streams | Yes | Partial - change records commit with writes; one writer per streamed table | Partial - one writing instance per streamed table | Partial - one writing instance per streamed table | - | No - stream-enabled writes are rejected | No - no atomic DynamoDB change log | - | - |
| Per-item TTL | Yes | Yes - expired items remain readable until background deletion | - | - | - | - | - | - | No - the source epoch attribute is not translated; emitted default has no automatic expiry |
| Capacity | managed on-demand or provisioned capacity | database and storage resources allocated to the Cloud Adapter deployment | - | - | - | - | - | Cloud SQL instance size, storage and connection limits | - |
| API coverage | full | high (PostgreSQL-backed DynamoDB table semantics, subject to the selected database image/version, DynamoDB SIP revision, schema and coupled control/table configuration. Registry version 1.0.0 is not an engine version. No exact installed version or generic Kubernetes readiness is established here; SQS qualification on PostgreSQL does not qualify this service.) | partial | partial | high | high | partial | high | minimal |
| Secondary indexes · index types | GSI (eventually consistent) / LSI (strongly consistent) | - | Azure-maintained GSI container / native LSI index | LSI only (a GSI needs the provisioned backend) | Firestore composite indexes over the item's own fields, written with the item | Spanner secondary index / interleaved index, both written with the row | - | Postgres indexes updated in the same transaction as the item | - |
| Autoscale · capacity model | provisioned / on-demand | - | dedicated autoscaling range of request units (RUs) | consumption billing without a dedicated RU band | - | - | - | - | - |
| Item size · enforcement | 400 KiB | - | 400 KiB enforced | 400 KiB enforced | - | - | - | - | - |
| Per-item TTL | Yes - absolute epoch attribute | - | Yes - per-item ttl tag, relative to the last write | Yes - per-item ttl tag, relative to the last write | - | - | - | - | - |
| Cost · capacity model | request-based or provisioned capacity | - | dedicated autoscaling range of request units (RUs) | consumption billing without a dedicated RU band | - | - | - | - | - |
| Conditional writes | Yes - native | - | Yes - stored procedure, conditional PATCH or etag guard | Yes - stored procedure, conditional PATCH or etag guard | - | - | - | - | - |
| Transactions | Yes | - | No - DynamoDB multi-item transaction APIs are rejected | No - DynamoDB multi-item transaction APIs are rejected | - | - | - | - | - |
| Write path · latency tradeoff | managed item writes and transactions | - | - | - | limited direct writes; guarded read-modify-write for other requests | replicated commits; eligible updates avoid a pre-image read | direct row mutations or guarded read-modify-write | one keyed upsert, or a row-locked read-modify-write | - |
| Item size · optional relaxed size check | 400 KiB per item | - | - | - | 400 KiB by default; opt-in blind patches may exceed it | - | - | - | - |
| Per-item TTL | Yes - epoch attribute; lazy delete | - | - | - | Yes - native TTL field policy; asynchronous delete | Yes - generated column plus a row-deletion policy | - | - | - |
| Read consistency · default + on request | eventually consistent, ConsistentRead on request | - | - | - | - | strong reads, including ConsistentRead=false | - | - | - |
| Cross-partition transactions · multi-item writes | Yes - serializable, up to 100 actions | - | - | - | - | Yes - external consistency, spans tables | - | - | - |
| Cost vs DynamoDB · billing model | on-demand requests plus storage | - | - | - | - | provisioned compute plus storage | provisioned nodes plus storage | - | - |
| Item size · enforcement | 400 KiB per item | - | - | - | - | 400 KiB enforced, plus DynamoDB's 4 MiB transaction aggregate | - | 400 KiB enforced, including the attributes a local index copies | - |
| Scaling · capacity and concurrency | on-demand or provisioned capacity | - | - | - | - | instance processing units and request concurrency | cluster nodes, row distribution and connection pool | - | - |
| Read consistency · default + on request | eventual by default; strong on request | - | - | - | - | - | strong through one cluster | - | - |
| Cross-partition transactions · multi-item writes | Yes - up to 100 items across tables | - | - | - | - | - | No - one item row is the atomic unit | Partial - native Postgres transaction at SERIALIZABLE isolation; stream-enabled tables are excluded | - |
| Per-item TTL | Yes - epoch attribute set per item; lazy delete | - | - | - | - | - | No - DynamoDB TTL attributes are rejected | - | - |
| Item size · update size validation | 400 KiB per item | - | - | - | - | - | blind SET/REMOVE may exceed 400 KiB | - | - |
| DynamoDB Streams · change capture | Yes - 24-hour retention | - | - | - | - | - | - | Partial - outbox co-committed with the write; one writer per streamed table | - |
| Per-item TTL · expiry | Yes - epoch attribute set per item; lazy delete | - | - | - | - | - | - | Yes - expression index plus a leader-elected reaper | - |
| Conditional writes · atomicity | Yes - native | - | - | - | - | - | - | Yes - row-locked read-modify-write inside one transaction | - |
| Adaptation mechanism | DynamoDB infrastructure and runtime API | - | - | - | - | - | - | - | infrastructure mapping to native OCI NoSQL |
| Item layout | partition key, optional sort key and typed attributes | - | - | - | - | - | - | - | typed primary-key columns plus value JSON |
| Capacity | on-demand or provisioned; storage grows with use | - | - | - | - | - | - | - | OCI capacity mode, read/write units and explicit storage cap |
| DynamoDB runtime API | Yes | - | - | - | - | - | - | - | No - applications use OCI NoSQL APIs in this mapping |
| Declared DynamoDB secondary indexes | Yes | - | - | - | - | - | - | - | No - configure native OCI indexes and adapt queries separately |

## On Akamai, DigitalOcean, Private Kubernetes, and Scaleway

### PostgreSQL

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| DescribeContinuousBackups | Backups | Out of scope | Full surface | use PostgreSQL backup and point-in-time recovery; the DynamoDB PITR API is not implemented |
| On-demand backups (CreateBackup / RestoreTableFromBackup / …) | Backups | Out of scope | Full surface | use PostgreSQL backups and restore procedures; DynamoDB backup APIs are not implemented |
| UpdateContinuousBackups | Backups | Out of scope | Full surface | use PostgreSQL backup and point-in-time recovery; the DynamoDB PITR API is not implemented |
| ConditionExpression | Conditional writes | Supported | Common | evaluated against the live item under a row-level lock; commits atomically |
| Global tables (CreateGlobalTable / UpdateGlobalTable / …) | Global | Out of scope | Full surface | use PostgreSQL replication and failover procedures; DynamoDB global-table APIs are not implemented |
| DescribeStream | Indexes + streams | Supported | Full surface | shard list + stream ARN |
| GetRecords | Indexes + streams | Supported | Full surface | DynamoDB Streams served from an in-transaction outbox co-committed with each write |
| GetShardIterator | Indexes + streams | Supported | Full surface | - |
| ListStreams | Indexes + streams | Supported | Full surface | the streamed-table registry |
| Query (GSI / LSI) | Indexes + streams | Supported | Most usage | indexes declared before deployment and maintained in the item transaction; queries use the index |
| S3 import/export + Kinesis streaming + ContributorInsights + ResourcePolicy | Out of scope | Out of scope | Full surface | these AWS integrations are outside the PostgreSQL adapter mapping |
| BatchExecuteStatement | PartiQL | Partial | Most usage | statements run independently; mixed reads and writes and repeated writes to one item are rejected |
| ExecuteStatement | PartiQL | Partial | Most usage | supported PartiQL statements are lowered to typed item operations; some language forms are unavailable |
| ExecuteTransaction | PartiQL | Partial | Most usage | supported transactional statements use one atomic PostgreSQL transaction or read snapshot |
| BatchGetItem | Reads | Supported | Most usage | executes each item read and reports its result; the batch is not one atomic snapshot |
| BatchWriteItem | Reads | Supported | Most usage | executes each item write and reports its result; the batch is not atomic |
| Query | Reads | Supported | Common | ordering, filters and pagination honored |
| Scan | Reads | Supported | Common | streamed page by page; index-scoped scans are supported |
| DeleteItem | Single item | Supported | Common | - |
| GetItem | Single item | Supported | Common | - |
| PutItem | Single item | Supported | Common | items kept in native shape; numbers at exact decimal precision |
| UpdateItem | Single item | Supported | Common | update expressions evaluated by the adapter |
| DescribeTimeToLive | TTL | Supported | Most usage | returns the table's configured TTL attribute and status |
| UpdateTimeToLive | TTL | Supported | Most usage | configures the TTL attribute and PostgreSQL expiry index; a background reaper deletes expired items |
| CreateTable | Table control plane | Supported | Most usage | creates a PostgreSQL relation, declared indexes and a durable registry entry |
| DeleteTable | Table control plane | Supported | Most usage | drops the PostgreSQL relation and its registry entry |
| DescribeEndpoints | Table control plane | Out of scope | Full surface | the adapter does not serve this DynamoDB API |
| DescribeLimits | Table control plane | Out of scope | Full surface | the adapter does not serve this DynamoDB API |
| DescribeTable | Table control plane | Supported | Most usage | returns the registered table schema and status |
| ListTables | Table control plane | Supported | Most usage | - |
| UpdateTable | Table control plane | Supported | Most usage | records DynamoDB billing metadata; does not resize PostgreSQL or change deployed indexes and streams |
| ListTagsOfResource | Tags | Supported | Full surface | returns tags held in the durable table registry |
| TagResource | Tags | Supported | Full surface | updates table tags in the durable registry |
| UntagResource | Tags | Supported | Full surface | removes table tags from the durable registry |
| TransactGetItems | Transactions | Supported | Most usage | reads all requested items in one PostgreSQL REPEATABLE READ snapshot |
| TransactWriteItems | Transactions | Supported | Most usage | one serializable PostgreSQL transaction across tables; at most 100 actions and one operation per item; ClientRequestToken idempotency; stream-enabled tables excluded |

#### PostgreSQL in the Cloud Adapter deployment

Tensor9 deploys and operates the PostgreSQL store with the customer Cloud Adapter deployment, including disconnected deployments. Application requests use the same Rust DynamoDB-to-PostgreSQL implementation as the managed PostgreSQL backend. Database access uses the configured connection credentials; Cloud SQL IAM authentication is specific to the Google-managed backend. The customer supplies the infrastructure, and the deployment's storage, backup and recovery configuration determines availability.

#### How it works

Your application keeps its AWS SDK and code. Tensor9 runs a DynamoDB adapter beside it in the customer's environment and sets `AWS_ENDPOINT_URL_DYNAMODB`, so the SDK sends its requests to the adapter over the local network. The adapter accepts DynamoDB requests and data types, returns DynamoDB responses and errors, and stores the data in PostgreSQL. Unsupported requests return errors.

DynamoDB's 38-digit numbers, typed sets, conditional writes, secondary indexes and atomic transactions are implemented with PostgreSQL storage and transactions. PostgreSQL adds multi-table transactions and indexes that update with each write, but has different concurrency, capacity and naming limits, described below.

For a base-table `Query` or `Scan`, supported filters run in PostgreSQL as part of the SQL `WHERE` clause, and numbers compare as exact decimals. Results are fetched in batches until the request's `Limit` or 1 MiB of item data is reached. Filters SQL cannot express run in the adapter over the rows PostgreSQL returns. Secondary-index queries work differently, as described below.

![Before: on AWS, the application's DynamoDB SDK calls Amazon DynamoDB. After: on the target cloud, the same application and SDK call a Tensor9 adapter, which stores the data in PostgreSQL.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUywgdGhlIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IG9uIHRoZSB0YXJnZXQgY2xvdWQsIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggc3RvcmVzIHRoZSBkYXRhIGluIFBvc3RncmVTUUwuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhaDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0NiIgd2lkdGg9IjM1OCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIzMCIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjgwIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjkwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iOTAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkR5bmFtb0RCIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4LjVweCI+RHluYW1vREI8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iODAiIHdpZHRoPSIxNDgiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjg4IiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTEuNXB4Ij5BbWF6b24gRHluYW1vREI8L3RleHQ+Cjx0ZXh0IHg9IjI4OCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+QVdTLW1hbmFnZWQ8L3RleHQ+CjxsaW5lIHgxPSI0MTgiIHkxPSI0MCIgeDI9IjQxOCIgeTI9IjE2MCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6I2NiZDVlMSIvPgo8cmVjdCB4PSI0NjIiIHk9IjQ2IiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ3NiIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPk9OIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ3NCIgeT0iODAiIHdpZHRoPSI5MiIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1MjAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNTIwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c2FtZSBTREs8L3RleHQ+CjxsaW5lIHgxPSI1NjYiIHkxPSIxMTMiIHgyPSI1OTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNTk0IiB5PSI3NiIgd2lkdGg9IjExMCIgaGVpZ2h0PSI3NCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI2NDkiIHk9IjEwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMnB4Ij5UZW5zb3I5PC90ZXh0Pgo8dGV4dCB4PSI2NDkiIHk9IjExNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c2VydmljZTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmFkYXB0ZXI8L3RleHQ+CjxsaW5lIHgxPSI3MDQiIHkxPSIxMTMiIHgyPSI3MjgiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNzMyIiB5PSI4MCIgd2lkdGg9Ijg0IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTA4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjExcHgiPlBvc3RncmVTUUw8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cmVsYXRpb25hbDwvdGV4dD4KPC9zdmc+)

![Before: on AWS, the application's DynamoDB SDK calls Amazon DynamoDB. After: on the target cloud, the same application and SDK call a Tensor9 adapter, which stores the data in PostgreSQL.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUywgdGhlIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IG9uIHRoZSB0YXJnZXQgY2xvdWQsIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggc3RvcmVzIHRoZSBkYXRhIGluIFBvc3RncmVTUUwuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhaDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0NiIgd2lkdGg9IjM1OCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIzMCIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjgwIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjkwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iOTAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkR5bmFtb0RCIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZvbnQtc2l6ZTo4LjVweCI+RHluYW1vREI8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iODAiIHdpZHRoPSIxNDgiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjg4IiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTEuNXB4Ij5BbWF6b24gRHluYW1vREI8L3RleHQ+Cjx0ZXh0IHg9IjI4OCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+QVdTLW1hbmFnZWQ8L3RleHQ+CjxsaW5lIHgxPSI0MTgiIHkxPSI0MCIgeDI9IjQxOCIgeTI9IjE2MCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6IzQ3NTU2OSIvPgo8cmVjdCB4PSI0NjIiIHk9IjQ2IiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ3NiIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPk9OIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ3NCIgeT0iODAiIHdpZHRoPSI5MiIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1MjAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNTIwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c2FtZSBTREs8L3RleHQ+CjxsaW5lIHgxPSI1NjYiIHkxPSIxMTMiIHgyPSI1OTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNTk0IiB5PSI3NiIgd2lkdGg9IjExMCIgaGVpZ2h0PSI3NCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI2NDkiIHk9IjEwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMnB4Ij5UZW5zb3I5PC90ZXh0Pgo8dGV4dCB4PSI2NDkiIHk9IjExNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c2VydmljZTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmFkYXB0ZXI8L3RleHQ+CjxsaW5lIHgxPSI3MDQiIHkxPSIxMTMiIHgyPSI3MjgiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNzMyIiB5PSI4MCIgd2lkdGg9Ijg0IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTA4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjExcHgiPlBvc3RncmVTUUw8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cmVsYXRpb25hbDwvdGV4dD4KPC9zdmc+)

Your application keeps its DynamoDB SDK; an adapter in the target environment stores the data in PostgreSQL.

#### Architecture

The adapter parses DynamoDB requests and expressions, runs the matching PostgreSQL statements and returns DynamoDB responses. It connects through a connection pool with the customer's credentials. All data stays in PostgreSQL, so adapter instances can restart or scale out without sharing local state; tables with Streams enabled have the single-writer limit described below.

Each DynamoDB table is a PostgreSQL table named `ddb_<name>` in one database. The `ddb_tables` registry records each table's PostgreSQL name, key schema, billing mode, time-to-live (TTL) settings, global secondary indexes (GSIs) and stream settings. A write or query for a table missing from the registry returns `ResourceNotFoundException`; writes never create tables. `CreateTable` at run time creates a PostgreSQL index for each declared GSI, and each table with Streams enabled also gets a `_strm` table that stores its change records.

![Your app's DynamoDB SDK calls the Tensor9 adapter, which keeps no data of its own. PostgreSQL holds everything in one database: a table for each DynamoDB table, the ddb\_tables registry, an index for each declared GSI, and a change-record table for each table with Streams enabled.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJZb3VyIGFwcCdzIER5bmFtb0RCIFNESyBjYWxscyB0aGUgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBrZWVwcyBubyBkYXRhIG9mIGl0cyBvd24uIFBvc3RncmVTUUwgaG9sZHMgZXZlcnl0aGluZyBpbiBvbmUgZGF0YWJhc2U6IGEgdGFibGUgZm9yIGVhY2ggRHluYW1vREIgdGFibGUsIHRoZSBkZGJfdGFibGVzIHJlZ2lzdHJ5LCBhbiBpbmRleCBmb3IgZWFjaCBkZWNsYXJlZCBHU0ksIGFuZCBhIGNoYW5nZS1yZWNvcmQgdGFibGUgZm9yIGVhY2ggdGFibGUgd2l0aCBTdHJlYW1zIGVuYWJsZWQuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhciIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iOCIgeT0iMzQiIHdpZHRoPSI4MjAiIGhlaWdodD0iMjA4IiByeD0iMTYiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjYiIHk9IjU0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiOCI+Q1VTVE9NRVInUyBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjExMCIgd2lkdGg9IjExNCIgaGVpZ2h0PSI5MiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI4MyIgeT0iMTUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEzcHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTY4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+RHluYW1vREIgU0RLPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTg0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnVuY2hhbmdlZDwvdGV4dD4KPGxpbmUgeDE9IjE0MCIgeTE9IjE1NiIgeDI9IjE5MiIgeTI9IjE1NiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FyKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+Cjx0ZXh0IHg9IjE2NiIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZm9udC1zaXplOjguNXB4Ij5EeW5hbW9EQjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxMjIiIHdpZHRoPSIxNjgiIGhlaWdodD0iNjgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjgwIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTNweCI+YWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMjgwIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmtlZXBzIG5vIGRhdGE8L3RleHQ+CjxsaW5lIHgxPSIzNjQiIHkxPSIxNTYiIHgyPSI0MzYiIHkyPSIxNTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhcikiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSI0MDAiIHk9IjE0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPlNRTDwvdGV4dD4KPHRleHQgeD0iNDAwIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5wb29sZWQ8L3RleHQ+CjxyZWN0IHg9IjQ0MCIgeT0iODYiIHdpZHRoPSIzNzIiIGhlaWdodD0iMTQ4IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjYyNiIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEyLjVweCI+UG9zdGdyZVNRTCDCtyBvbmUgZGF0YWJhc2U8L3RleHQ+CjxyZWN0IHg9IjQ1NCIgeT0iMTE2IiB3aWR0aD0iMjMwIiBoZWlnaHQ9IjEwOCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1NjkiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+b25lIHRhYmxlIGVhY2g8L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMTQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNjQ3NDhiIj5vbmUgZGRiXyZsdDtuYW1lJmd0OyBwZXIgdGFibGU8L3RleHQ+CjxyZWN0IHg9IjQ2NiIgeT0iMTUyIiB3aWR0aD0iMjA2IiBoZWlnaHQ9IjIwIiByeD0iNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1NjkiIHk9IjE2NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6IzMzNDE1NSI+ZGRiX29yZGVycyAgIChwaywgc2ssIGl0ZW0pPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE3NiIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTY5IiB5PSIxOTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPmRkYl9zZXNzaW9ucyAocGssIHNrLCBpdGVtKTwvdGV4dD4KPHJlY3QgeD0iNDY2IiB5PSIyMDAiIHdpZHRoPSIyMDYiIGhlaWdodD0iMjAiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjU2OSIgeT0iMjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMzM0MTU1Ij5kZGJfdGFibGVzICAg4oaSIHJlZ2lzdHJ5PC90ZXh0Pgo8cmVjdCB4PSI2OTYiIHk9IjExNiIgd2lkdGg9IjEwMiIgaGVpZ2h0PSIxMDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzQ3IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiMzMzQxNTUiPlBvc3RncmVTUUw8L3RleHQ+Cjx0ZXh0IHg9Ijc0NyIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDA7ZmlsbDojMzM0MTU1Ij5pbmRleCAvIEdTSTwvdGV4dD4KPHRleHQgeD0iNzQ3IiB5PSIxNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj4rIGNoYW5nZSByZWNvcmRzPC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjE5MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnBlciBzdHJlYW1lZCB0YWJsZTwvdGV4dD4KPC9zdmc+)

![Your app's DynamoDB SDK calls the Tensor9 adapter, which keeps no data of its own. PostgreSQL holds everything in one database: a table for each DynamoDB table, the ddb\_tables registry, an index for each declared GSI, and a change-record table for each table with Streams enabled.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJZb3VyIGFwcCdzIER5bmFtb0RCIFNESyBjYWxscyB0aGUgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBrZWVwcyBubyBkYXRhIG9mIGl0cyBvd24uIFBvc3RncmVTUUwgaG9sZHMgZXZlcnl0aGluZyBpbiBvbmUgZGF0YWJhc2U6IGEgdGFibGUgZm9yIGVhY2ggRHluYW1vREIgdGFibGUsIHRoZSBkZGJfdGFibGVzIHJlZ2lzdHJ5LCBhbiBpbmRleCBmb3IgZWFjaCBkZWNsYXJlZCBHU0ksIGFuZCBhIGNoYW5nZS1yZWNvcmQgdGFibGUgZm9yIGVhY2ggdGFibGUgd2l0aCBTdHJlYW1zIGVuYWJsZWQuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhciIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iOCIgeT0iMzQiIHdpZHRoPSI4MjAiIGhlaWdodD0iMjA4IiByeD0iMTYiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjYiIHk9IjU0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YiI+Q1VTVE9NRVInUyBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjExMCIgd2lkdGg9IjExNCIgaGVpZ2h0PSI5MiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI4MyIgeT0iMTUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEzcHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTY4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+RHluYW1vREIgU0RLPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTg0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnVuY2hhbmdlZDwvdGV4dD4KPGxpbmUgeDE9IjE0MCIgeTE9IjE1NiIgeDI9IjE5MiIgeTI9IjE1NiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FyKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+Cjx0ZXh0IHg9IjE2NiIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZm9udC1zaXplOjguNXB4Ij5EeW5hbW9EQjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxMjIiIHdpZHRoPSIxNjgiIGhlaWdodD0iNjgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjgwIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTNweCI+YWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMjgwIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmtlZXBzIG5vIGRhdGE8L3RleHQ+CjxsaW5lIHgxPSIzNjQiIHkxPSIxNTYiIHgyPSI0MzYiIHkyPSIxNTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhcikiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSI0MDAiIHk9IjE0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPlNRTDwvdGV4dD4KPHRleHQgeD0iNDAwIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5wb29sZWQ8L3RleHQ+CjxyZWN0IHg9IjQ0MCIgeT0iODYiIHdpZHRoPSIzNzIiIGhlaWdodD0iMTQ4IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjYyNiIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEyLjVweCI+UG9zdGdyZVNRTCDCtyBvbmUgZGF0YWJhc2U8L3RleHQ+CjxyZWN0IHg9IjQ1NCIgeT0iMTE2IiB3aWR0aD0iMjMwIiBoZWlnaHQ9IjEwOCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1NjkiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+b25lIHRhYmxlIGVhY2g8L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMTQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojOTRhM2I4Ij5vbmUgZGRiXyZsdDtuYW1lJmd0OyBwZXIgdGFibGU8L3RleHQ+CjxyZWN0IHg9IjQ2NiIgeT0iMTUyIiB3aWR0aD0iMjA2IiBoZWlnaHQ9IjIwIiByeD0iNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1NjkiIHk9IjE2NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6I2NiZDVlMSI+ZGRiX29yZGVycyAgIChwaywgc2ssIGl0ZW0pPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE3NiIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTY5IiB5PSIxOTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPmRkYl9zZXNzaW9ucyAocGssIHNrLCBpdGVtKTwvdGV4dD4KPHJlY3QgeD0iNDY2IiB5PSIyMDAiIHdpZHRoPSIyMDYiIGhlaWdodD0iMjAiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjU2OSIgeT0iMjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojY2JkNWUxIj5kZGJfdGFibGVzICAg4oaSIHJlZ2lzdHJ5PC90ZXh0Pgo8cmVjdCB4PSI2OTYiIHk9IjExNiIgd2lkdGg9IjEwMiIgaGVpZ2h0PSIxMDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzQ3IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiNjYmQ1ZTEiPlBvc3RncmVTUUw8L3RleHQ+Cjx0ZXh0IHg9Ijc0NyIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDA7ZmlsbDojY2JkNWUxIj5pbmRleCAvIEdTSTwvdGV4dD4KPHRleHQgeD0iNzQ3IiB5PSIxNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij4rIGNoYW5nZSByZWNvcmRzPC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjE5MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnBlciBzdHJlYW1lZCB0YWJsZTwvdGV4dD4KPC9zdmc+)

The adapter keeps no data; each DynamoDB table is its own table in one PostgreSQL database.

#### Item storage

Each DynamoDB item is one PostgreSQL row with columns `pk TEXT`, `sk TEXT`, `okey TEXT` and `item JSONB`. The `PRIMARY KEY (pk, sk)` index serves `GetItem`, and a second index over `pk` and byte-ordered `okey` serves ordered base-table `Query` requests.

The `item` column keeps DynamoDB's typed attributes, such as `{"N":"123.45"}`, `{"B":"<b64>"}` and typed sets. Numbers stay decimal strings, so a 38-digit amount or a Snowflake ID is never rounded, and a number stays distinct from a numeric string. Enabling TTL builds a PostgreSQL expression index over the configured epoch attribute in the item JSONB, and a leader-elected background worker, one adapter instance at a time, deletes expired rows through it in bounded batches. Expired items stay readable until they are deleted, because reads do not filter on TTL.

![A DynamoDB item becomes one row with pk, sk, okey and item columns and PRIMARY KEY (pk, sk). The whole item is stored as JSONB in its DynamoDB form, so a number keeps its exact decimal text. The okey column keeps the sort order, and TTL uses an index over the item.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0gYmVjb21lcyBvbmUgcm93IHdpdGggcGssIHNrLCBva2V5IGFuZCBpdGVtIGNvbHVtbnMgYW5kIFBSSU1BUlkgS0VZIChwaywgc2spLiBUaGUgd2hvbGUgaXRlbSBpcyBzdG9yZWQgYXMgSlNPTkIgaW4gaXRzIER5bmFtb0RCIGZvcm0sIHNvIGEgbnVtYmVyIGtlZXBzIGl0cyBleGFjdCBkZWNpbWFsIHRleHQuIFRoZSBva2V5IGNvbHVtbiBrZWVwcyB0aGUgc29ydCBvcmRlciwgYW5kIFRUTCB1c2VzIGFuIGluZGV4IG92ZXIgdGhlIGl0ZW0uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImEzIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIzMCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+RFlOQU1PREIgSVRFTTwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjE4MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NCIgeT0iNzQiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiYjMTIzOzwvdGV4dD4KPHRleHQgeD0iNjAiIHk9Ijk4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4icGsiOiAgICAmIzEyMzsgIlMiOiAidXNlciM0MiIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTIyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4ic2siOiAgICAmIzEyMzsgIlMiOiAib3JkZXIjNyIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojYjQ1MzA5Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAiMTIzLjQ1IiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxNzAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiJ0YWdzIjogICYjMTIzOyAiU1MiOiBbInZpcCJdICYjMTI1OzwvdGV4dD4KPHRleHQgeD0iNDQiIHk9IjE5NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0NCIgeT0iMjE0IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojYjQ1MzA5Ij5OIGlzIGV4YWN0IGRlY2ltYWwsIG5vdCBhIGZsb2F0PC90ZXh0Pgo8bGluZSB4MT0iMzM0IiB5MT0iMTMyIiB4Mj0iMzg2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTMpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzYwIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+c3RvcmU8L3RleHQ+Cjx0ZXh0IHg9IjM5NiIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPmRkYl9vcmRlcnMgUk9XIMK3IFBSSU1BUlkgS0VZIChwaywgc2spPC90ZXh0Pgo8cmVjdCB4PSIzOTYiIHk9IjQyIiB3aWR0aD0iNDE0IiBoZWlnaHQ9IjE5OCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0MTQiIHk9IjY2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5wayAgICAgICAgPHRzcGFuIHN0eWxlPSJmaWxsOiMzMzQxNTUiPlRFWFQ8L3RzcGFuPiAgICAidXNlciM0MiI8L3RleHQ+Cjx0ZXh0IHg9IjQxNCIgeT0iODgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnNrICAgICAgICA8dHNwYW4gc3R5bGU9ImZpbGw6IzMzNDE1NSI+VEVYVDwvdHNwYW4+ICAgICJvcmRlciM3IjwvdGV4dD4KPHRleHQgeD0iNDE0IiB5PSIxMTAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPml0ZW0gICAgICA8dHNwYW4gc3R5bGU9ImZpbGw6IzMzNDE1NSI+SlNPTkI8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iNDMwIiB5PSIxMjAiIHdpZHRoPSIzNjYiIGhlaWdodD0iNTIiIHJ4PSI3IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTM5IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4mIzEyMzsgInRvdGFsIjogJiMxMjM7ICJOIjogIjEyMy40NSIgJiMxMjU7LDwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiAgInRhZ3MiOiAmIzEyMzsgIlNTIjogWyJ2aXAiXSAmIzEyNTssIOKApiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjQxNCIgeT0iMTk0IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5va2V5ICAgICAgPHRzcGFuIHN0eWxlPSJmaWxsOiMzMzQxNTUiPlRFWFQ8L3RzcGFuPiAgICBwcmVzZXJ2ZXMgc29ydCBvcmRlcjwvdGV4dD4KPHRleHQgeD0iNDE0IiB5PSIyMTYiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiMzMzQxNTUiPlRUTDogYW4gaW5kZXggb3ZlciB0aGUgaXRlbSBKU09OQjwvdGV4dD4KPC9zdmc+)

![A DynamoDB item becomes one row with pk, sk, okey and item columns and PRIMARY KEY (pk, sk). The whole item is stored as JSONB in its DynamoDB form, so a number keeps its exact decimal text. The okey column keeps the sort order, and TTL uses an index over the item.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0gYmVjb21lcyBvbmUgcm93IHdpdGggcGssIHNrLCBva2V5IGFuZCBpdGVtIGNvbHVtbnMgYW5kIFBSSU1BUlkgS0VZIChwaywgc2spLiBUaGUgd2hvbGUgaXRlbSBpcyBzdG9yZWQgYXMgSlNPTkIgaW4gaXRzIER5bmFtb0RCIGZvcm0sIHNvIGEgbnVtYmVyIGtlZXBzIGl0cyBleGFjdCBkZWNpbWFsIHRleHQuIFRoZSBva2V5IGNvbHVtbiBrZWVwcyB0aGUgc29ydCBvcmRlciwgYW5kIFRUTCB1c2VzIGFuIGluZGV4IG92ZXIgdGhlIGl0ZW0uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImEzIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIzMCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+RFlOQU1PREIgSVRFTTwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjE4MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NCIgeT0iNzQiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiYjMTIzOzwvdGV4dD4KPHRleHQgeD0iNjAiIHk9Ijk4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4icGsiOiAgICAmIzEyMzsgIlMiOiAidXNlciM0MiIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTIyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4ic2siOiAgICAmIzEyMzsgIlMiOiAib3JkZXIjNyIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojZmJiZjI0Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAiMTIzLjQ1IiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxNzAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiJ0YWdzIjogICYjMTIzOyAiU1MiOiBbInZpcCJdICYjMTI1OzwvdGV4dD4KPHRleHQgeD0iNDQiIHk9IjE5NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0NCIgeT0iMjE0IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojZmJiZjI0Ij5OIGlzIGV4YWN0IGRlY2ltYWwsIG5vdCBhIGZsb2F0PC90ZXh0Pgo8bGluZSB4MT0iMzM0IiB5MT0iMTMyIiB4Mj0iMzg2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTMpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzYwIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+c3RvcmU8L3RleHQ+Cjx0ZXh0IHg9IjM5NiIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPmRkYl9vcmRlcnMgUk9XIMK3IFBSSU1BUlkgS0VZIChwaywgc2spPC90ZXh0Pgo8cmVjdCB4PSIzOTYiIHk9IjQyIiB3aWR0aD0iNDE0IiBoZWlnaHQ9IjE5OCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI0MTQiIHk9IjY2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5wayAgICAgICAgPHRzcGFuIHN0eWxlPSJmaWxsOiNjYmQ1ZTEiPlRFWFQ8L3RzcGFuPiAgICAidXNlciM0MiI8L3RleHQ+Cjx0ZXh0IHg9IjQxNCIgeT0iODgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnNrICAgICAgICA8dHNwYW4gc3R5bGU9ImZpbGw6I2NiZDVlMSI+VEVYVDwvdHNwYW4+ICAgICJvcmRlciM3IjwvdGV4dD4KPHRleHQgeD0iNDE0IiB5PSIxMTAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPml0ZW0gICAgICA8dHNwYW4gc3R5bGU9ImZpbGw6I2NiZDVlMSI+SlNPTkI8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iNDMwIiB5PSIxMjAiIHdpZHRoPSIzNjYiIGhlaWdodD0iNTIiIHJ4PSI3IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTM5IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4mIzEyMzsgInRvdGFsIjogJiMxMjM7ICJOIjogIjEyMy40NSIgJiMxMjU7LDwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiAgInRhZ3MiOiAmIzEyMzsgIlNTIjogWyJ2aXAiXSAmIzEyNTssIOKApiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjQxNCIgeT0iMTk0IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5va2V5ICAgICAgPHRzcGFuIHN0eWxlPSJmaWxsOiNjYmQ1ZTEiPlRFWFQ8L3RzcGFuPiAgICBwcmVzZXJ2ZXMgc29ydCBvcmRlcjwvdGV4dD4KPHRleHQgeD0iNDE0IiB5PSIyMTYiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNjYmQ1ZTEiPlRUTDogYW4gaW5kZXggb3ZlciB0aGUgaXRlbSBKU09OQjwvdGV4dD4KPC9zdmc+)

Each attribute keeps its DynamoDB type tag inside item JSONB , so \{"N":"123.45"} keeps its exact decimal string.

#### Tables

Each DynamoDB table has its own PostgreSQL table, indexes and, when Streams is on, a `_strm` change-record table. `CreateTable` creates those objects and the registry entry, and `DeleteTable` drops them. You can tune storage, indexes and vacuum settings per table.

When it creates a table, the adapter checks a limit of 500 DynamoDB tables per namespace. Concurrent creates of different tables can exceed it; it is a safeguard, not a PostgreSQL quota. Tables are not spread across database instances automatically, so plan database capacity and table placement for larger deployments. A provisioned instance costs compute while idle.

![Each DynamoDB table is its own PostgreSQL table in one database, next to the ddb\_tables registry and each table's indexes. The adapter allows 500 tables per namespace; larger deployments need capacity and placement planning.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjI2IiB2aWV3Qm94PSIwIDAgODM2IDIyNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFYWNoIER5bmFtb0RCIHRhYmxlIGlzIGl0cyBvd24gUG9zdGdyZVNRTCB0YWJsZSBpbiBvbmUgZGF0YWJhc2UsIG5leHQgdG8gdGhlIGRkYl90YWJsZXMgcmVnaXN0cnkgYW5kIGVhY2ggdGFibGUncyBpbmRleGVzLiBUaGUgYWRhcHRlciBhbGxvd3MgNTAwIHRhYmxlcyBwZXIgbmFtZXNwYWNlOyBsYXJnZXIgZGVwbG95bWVudHMgbmVlZCBjYXBhY2l0eSBhbmQgcGxhY2VtZW50IHBsYW5uaW5nLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPk9ORSBQT1NUR1JFU1FMIERBVEFCQVNFIMK3IGEgdGFibGUgcGVyIER5bmFtb0RCIHRhYmxlPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iNDAiIHdpZHRoPSI1MjAiIGhlaWdodD0iMTY2IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjQ0IiB5PSI2NiIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMjQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMTE5IiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+ZGRiX29yZGVyczwvdGV4dD4KPHJlY3QgeD0iNTgiIHk9IjEwMCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTE5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnJvd3MgKHBrLCBzayk8L3RleHQ+CjxyZWN0IHg9IjU4IiB5PSIxMzIiIHdpZHRoPSIxMjIiIGhlaWdodD0iMjYiIHJ4PSI2IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjExOSIgeT0iMTQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5HU0kgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjExOSIgeT0iMTc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+aXRzIG93biB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iMjA2IiB5PSI2NiIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMjQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMjgxIiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+ZGRiX3Nlc3Npb25zPC90ZXh0Pgo8cmVjdCB4PSIyMjAiIHk9IjEwMCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjgxIiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnJvd3MgKHBrLCBzayk8L3RleHQ+CjxyZWN0IHg9IjIyMCIgeT0iMTMyIiB3aWR0aD0iMTIyIiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyODEiIHk9IjE0OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+X3N0cm0gcmVjb3JkczwvdGV4dD4KPHRleHQgeD0iMjgxIiB5PSIxNzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5jcmVhdGVkIGF0IHJ1bnRpbWU8L3RleHQ+CjxyZWN0IHg9IjM2OCIgeT0iNjYiIHdpZHRoPSIxNjAiIGhlaWdodD0iMTI0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjQ0OCIgeT0iODgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPmRkYl90YWJsZXM8L3RleHQ+CjxyZWN0IHg9IjM4MiIgeT0iMTAwIiB3aWR0aD0iMTMyIiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NDgiIHk9IjExNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+b3JkZXJzIOKGkiB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iMzgyIiB5PSIxMzIiIHdpZHRoPSIxMzIiIGhlaWdodD0iMjYiIHJ4PSI2IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5zZXNzaW9ucyDihpIgdGFibGU8L3RleHQ+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dGFibGUgcmVnaXN0cnk8L3RleHQ+Cjx0ZXh0IHg9IjU3NiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPkxhcmdlciB0YWJsZSBzZXRzPC90ZXh0Pgo8cmVjdCB4PSI1NzYiIHk9IjQwIiB3aWR0aD0iMjM2IiBoZWlnaHQ9IjE2NiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNCA0IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjY5NCIgeT0iNjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmb250LXdlaWdodDo3MDA7ZmlsbDojMzM0MTU1Ij5QbGFuIGNhcGFjaXR5IGFuZCB0YWJsZSBwbGFjZW1lbnQ8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5MaW1pdDogNTAwIHRhYmxlcyBwZXIgbmFtZXNwYWNlPC90ZXh0Pgo8cmVjdCB4PSI1OTYiIHk9IjEwMCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjMwIiByeD0iNyIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI2NDIiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+Y2FwYWNpdHk8L3RleHQ+CjxyZWN0IHg9IjcwMCIgeT0iMTAwIiB3aWR0aD0iOTIiIGhlaWdodD0iMzAiIHJ4PSI3IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc0NiIgeT0iMTIwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij50YWJsZSBjb3VudDwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxNTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5ObyBhdXRvbWF0aWMgcGxhY2VtZW50PC90ZXh0Pgo8dGV4dCB4PSI2OTQiIHk9IjE2OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmFjcm9zcyBkYXRhYmFzZSBpbnN0YW5jZXM8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iMTkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cHJvdmlzaW9uZWQgLyBhbHdheXMtb248L3RleHQ+Cjwvc3ZnPg==)

![Each DynamoDB table is its own PostgreSQL table in one database, next to the ddb\_tables registry and each table's indexes. The adapter allows 500 tables per namespace; larger deployments need capacity and placement planning.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjI2IiB2aWV3Qm94PSIwIDAgODM2IDIyNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFYWNoIER5bmFtb0RCIHRhYmxlIGlzIGl0cyBvd24gUG9zdGdyZVNRTCB0YWJsZSBpbiBvbmUgZGF0YWJhc2UsIG5leHQgdG8gdGhlIGRkYl90YWJsZXMgcmVnaXN0cnkgYW5kIGVhY2ggdGFibGUncyBpbmRleGVzLiBUaGUgYWRhcHRlciBhbGxvd3MgNTAwIHRhYmxlcyBwZXIgbmFtZXNwYWNlOyBsYXJnZXIgZGVwbG95bWVudHMgbmVlZCBjYXBhY2l0eSBhbmQgcGxhY2VtZW50IHBsYW5uaW5nLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPk9ORSBQT1NUR1JFU1FMIERBVEFCQVNFIMK3IGEgdGFibGUgcGVyIER5bmFtb0RCIHRhYmxlPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iNDAiIHdpZHRoPSI1MjAiIGhlaWdodD0iMTY2IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjQ0IiB5PSI2NiIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMjQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMTE5IiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+ZGRiX29yZGVyczwvdGV4dD4KPHJlY3QgeD0iNTgiIHk9IjEwMCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTE5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnJvd3MgKHBrLCBzayk8L3RleHQ+CjxyZWN0IHg9IjU4IiB5PSIxMzIiIHdpZHRoPSIxMjIiIGhlaWdodD0iMjYiIHJ4PSI2IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjExOSIgeT0iMTQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5HU0kgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjExOSIgeT0iMTc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+aXRzIG93biB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iMjA2IiB5PSI2NiIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMjQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjgxIiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+ZGRiX3Nlc3Npb25zPC90ZXh0Pgo8cmVjdCB4PSIyMjAiIHk9IjEwMCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjgxIiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnJvd3MgKHBrLCBzayk8L3RleHQ+CjxyZWN0IHg9IjIyMCIgeT0iMTMyIiB3aWR0aD0iMTIyIiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyODEiIHk9IjE0OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+X3N0cm0gcmVjb3JkczwvdGV4dD4KPHRleHQgeD0iMjgxIiB5PSIxNzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5jcmVhdGVkIGF0IHJ1bnRpbWU8L3RleHQ+CjxyZWN0IHg9IjM2OCIgeT0iNjYiIHdpZHRoPSIxNjAiIGhlaWdodD0iMTI0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ0OCIgeT0iODgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPmRkYl90YWJsZXM8L3RleHQ+CjxyZWN0IHg9IjM4MiIgeT0iMTAwIiB3aWR0aD0iMTMyIiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NDgiIHk9IjExNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+b3JkZXJzIOKGkiB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iMzgyIiB5PSIxMzIiIHdpZHRoPSIxMzIiIGhlaWdodD0iMjYiIHJ4PSI2IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5zZXNzaW9ucyDihpIgdGFibGU8L3RleHQ+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dGFibGUgcmVnaXN0cnk8L3RleHQ+Cjx0ZXh0IHg9IjU3NiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPkxhcmdlciB0YWJsZSBzZXRzPC90ZXh0Pgo8cmVjdCB4PSI1NzYiIHk9IjQwIiB3aWR0aD0iMjM2IiBoZWlnaHQ9IjE2NiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNCA0IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjY5NCIgeT0iNjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmb250LXdlaWdodDo3MDA7ZmlsbDojY2JkNWUxIj5QbGFuIGNhcGFjaXR5IGFuZCB0YWJsZSBwbGFjZW1lbnQ8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5MaW1pdDogNTAwIHRhYmxlcyBwZXIgbmFtZXNwYWNlPC90ZXh0Pgo8cmVjdCB4PSI1OTYiIHk9IjEwMCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjMwIiByeD0iNyIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI2NDIiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+Y2FwYWNpdHk8L3RleHQ+CjxyZWN0IHg9IjcwMCIgeT0iMTAwIiB3aWR0aD0iOTIiIGhlaWdodD0iMzAiIHJ4PSI3IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc0NiIgeT0iMTIwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj50YWJsZSBjb3VudDwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxNTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5ObyBhdXRvbWF0aWMgcGxhY2VtZW50PC90ZXh0Pgo8dGV4dCB4PSI2OTQiIHk9IjE2OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmFjcm9zcyBkYXRhYmFzZSBpbnN0YW5jZXM8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iMTkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cHJvdmlzaW9uZWQgLyBhbHdheXMtb248L3RleHQ+Cjwvc3ZnPg==)

Each DynamoDB table is its own PostgreSQL table; CreateTable and DeleteTable create and drop them.

#### Conditional writes

For a conditional write, the adapter locks the item's row with `SELECT … FOR UPDATE`, checks the `ConditionExpression` against it, then writes and commits. The lock stops another writer from changing the item between the check and the write, at the cost of one extra round trip. For `attribute_not_exists(pk)`, the primary key ensures that only one of two concurrent creates succeeds.

A false condition returns the non-retryable `ConditionalCheckFailed` error and can return the item that failed it. A PostgreSQL serialization failure or lock timeout (`40001` or lock-not-available) returns a retryable throughput error instead, so the SDK backs off and retries. Concurrency failures are never reported as failed conditions.

Some unconditional writes skip the read: a top-level SET or REMOVE update, or an integer counter add, runs as one statement when it has no condition, asks for no returned item and touches no secondary index or stream.

![A conditional write locks the row with SELECT … FOR UPDATE, evaluates the DynamoDB condition in the adapter against the locked row, then writes and commits. A false condition returns ConditionalCheckFailed; a concurrency conflict returns a retryable error, never a condition failure. The primary key prevents duplicate creates.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGNvbmRpdGlvbmFsIHdyaXRlIGxvY2tzIHRoZSByb3cgd2l0aCBTRUxFQ1Qg4oCmIEZPUiBVUERBVEUsIGV2YWx1YXRlcyB0aGUgRHluYW1vREIgY29uZGl0aW9uIGluIHRoZSBhZGFwdGVyIGFnYWluc3QgdGhlIGxvY2tlZCByb3csIHRoZW4gd3JpdGVzIGFuZCBjb21taXRzLiBBIGZhbHNlIGNvbmRpdGlvbiByZXR1cm5zIENvbmRpdGlvbmFsQ2hlY2tGYWlsZWQ7IGEgY29uY3VycmVuY3kgY29uZmxpY3QgcmV0dXJucyBhIHJldHJ5YWJsZSBlcnJvciwgbmV2ZXIgYSBjb25kaXRpb24gZmFpbHVyZS4gVGhlIHByaW1hcnkga2V5IHByZXZlbnRzIGR1cGxpY2F0ZSBjcmVhdGVzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJhNSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPkxvY2sgY3VycmVudCByb3c8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSI3OSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPjx0c3BhbiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5TRUxFQ1Qg4oCmIEZPUiBVUERBVEU8L3RzcGFuPjwvdGV4dD4KPGxpbmUgeDE9IjE3MiIgeTE9IjkwIiB4Mj0iMTcyIiB5Mj0iMTEyIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjEzNCIgcj0iMTMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+PHRleHQgeD0iNDAiIHk9IjEzOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj4yPC90ZXh0Pgo8cmVjdCB4PSI2MiIgeT0iMTE2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSIxMzYiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTIuNXB4Ij5FdmFsdWF0ZSBjb25kaXRpb248L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIxNTMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmFnYWluc3QgdGhlIGxvY2tlZCByb3c8L3RleHQ+CjxsaW5lIHgxPSIxNzIiIHkxPSIxNjQiIHgyPSIxNzIiIHkyPSIxODYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2E1KSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMjA4IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iMjEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPjM8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxOTAiIHdpZHRoPSIyMjAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzYiIHk9IjIxMCIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPldyaXRlICZhbXA7IENPTU1JVDwvdGV4dD4KPHRleHQgeD0iNzYiIHk9IjIyNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmxvY2sgcmVsZWFzZWQgb24gY29tbWl0PC90ZXh0Pgo8bGluZSB4MT0iMjgyIiB5MT0iMTQwIiB4Mj0iMzU0IiB5Mj0iMTQwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSIzNTYiIHk9IjExOCIgd2lkdGg9IjM0MCIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI1MjYiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMnB4Ij5jb25kaXRpb24gZmFsc2Ug4oaSPC90ZXh0Pgo8dGV4dCB4PSI1MjYiIHk9IjE1MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+Q29uZGl0aW9uYWxDaGVja0ZhaWxlZDwvdGV4dD4KPGxpbmUgeDE9IjI4MiIgeTE9IjIxNCIgeDI9IjM1NCIgeTI9IjIxNCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYTUpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iMzU2IiB5PSIxOTIiIHdpZHRoPSIzNDAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZiZWI7c3Ryb2tlOiNmZGU2OGEiLz4KPHRleHQgeD0iNTI2IiB5PSIyMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMnB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojYjQ1MzA5Ij5sb2NrIHRpbWVvdXQgLyA0MDAwMSDihpI8L3RleHQ+Cjx0ZXh0IHg9IjUyNiIgeT0iMjI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojYjQ1MzA5Ij5yZXRyeWFibGUgY29uZmxpY3Q8L3RleHQ+Cjwvc3ZnPg==)

![A conditional write locks the row with SELECT … FOR UPDATE, evaluates the DynamoDB condition in the adapter against the locked row, then writes and commits. A false condition returns ConditionalCheckFailed; a concurrency conflict returns a retryable error, never a condition failure. The primary key prevents duplicate creates.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGNvbmRpdGlvbmFsIHdyaXRlIGxvY2tzIHRoZSByb3cgd2l0aCBTRUxFQ1Qg4oCmIEZPUiBVUERBVEUsIGV2YWx1YXRlcyB0aGUgRHluYW1vREIgY29uZGl0aW9uIGluIHRoZSBhZGFwdGVyIGFnYWluc3QgdGhlIGxvY2tlZCByb3csIHRoZW4gd3JpdGVzIGFuZCBjb21taXRzLiBBIGZhbHNlIGNvbmRpdGlvbiByZXR1cm5zIENvbmRpdGlvbmFsQ2hlY2tGYWlsZWQ7IGEgY29uY3VycmVuY3kgY29uZmxpY3QgcmV0dXJucyBhIHJldHJ5YWJsZSBlcnJvciwgbmV2ZXIgYSBjb25kaXRpb24gZmFpbHVyZS4gVGhlIHByaW1hcnkga2V5IHByZXZlbnRzIGR1cGxpY2F0ZSBjcmVhdGVzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJhNSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPkxvY2sgY3VycmVudCByb3c8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSI3OSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPjx0c3BhbiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5TRUxFQ1Qg4oCmIEZPUiBVUERBVEU8L3RzcGFuPjwvdGV4dD4KPGxpbmUgeDE9IjE3MiIgeTE9IjkwIiB4Mj0iMTcyIiB5Mj0iMTEyIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjEzNCIgcj0iMTMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+PHRleHQgeD0iNDAiIHk9IjEzOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj4yPC90ZXh0Pgo8cmVjdCB4PSI2MiIgeT0iMTE2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSIxMzYiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTIuNXB4Ij5FdmFsdWF0ZSBjb25kaXRpb248L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIxNTMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmFnYWluc3QgdGhlIGxvY2tlZCByb3c8L3RleHQ+CjxsaW5lIHgxPSIxNzIiIHkxPSIxNjQiIHgyPSIxNzIiIHkyPSIxODYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2E1KSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMjA4IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iMjEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPjM8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxOTAiIHdpZHRoPSIyMjAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzYiIHk9IjIxMCIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPldyaXRlICZhbXA7IENPTU1JVDwvdGV4dD4KPHRleHQgeD0iNzYiIHk9IjIyNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmxvY2sgcmVsZWFzZWQgb24gY29tbWl0PC90ZXh0Pgo8bGluZSB4MT0iMjgyIiB5MT0iMTQwIiB4Mj0iMzU0IiB5Mj0iMTQwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSIzNTYiIHk9IjExOCIgd2lkdGg9IjM0MCIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI1MjYiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMnB4Ij5jb25kaXRpb24gZmFsc2Ug4oaSPC90ZXh0Pgo8dGV4dCB4PSI1MjYiIHk9IjE1MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+Q29uZGl0aW9uYWxDaGVja0ZhaWxlZDwvdGV4dD4KPGxpbmUgeDE9IjI4MiIgeTE9IjIxNCIgeDI9IjM1NCIgeTI9IjIxNCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYTUpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iMzU2IiB5PSIxOTIiIHdpZHRoPSIzNDAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiM0MjIwMDY7c3Ryb2tlOiM5MjQwMGUiLz4KPHRleHQgeD0iNTI2IiB5PSIyMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMnB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojZmJiZjI0Ij5sb2NrIHRpbWVvdXQgLyA0MDAwMSDihpI8L3RleHQ+Cjx0ZXh0IHg9IjUyNiIgeT0iMjI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojZmJiZjI0Ij5yZXRyeWFibGUgY29uZmxpY3Q8L3RleHQ+Cjwvc3ZnPg==)

Failed conditions and PostgreSQL concurrency conflicts return different error types.

#### Secondary indexes

On each write, the adapter adds two index fields to the item's JSONB. `_idx_<name>_h` holds the index partition key and treats equal numbers such as `1` and `1.0` as the same; `_idx_<name>_o` holds the sort key in sort order, with the base key breaking ties. A PostgreSQL index over these fields finds the items with a matching partition key, and the adapter then applies sort-key conditions, ordering, pagination and any `FilterExpression`.

The index fields are saved in the same transaction as the item, so GSI queries are strongly consistent; DynamoDB's own GSIs update asynchronously. One index lookup can examine at most 10,000 items for a single partition-key value, and a lookup beyond that returns an error, so choose index keys with this limit in mind.

![On each write, the adapter adds two index fields to the item's JSONB, and PostgreSQL keeps an index over them. A GSI query looks up the index, then the adapter filters and orders the results. The index fields are saved with the item, so the index is strongly consistent.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBlYWNoIHdyaXRlLCB0aGUgYWRhcHRlciBhZGRzIHR3byBpbmRleCBmaWVsZHMgdG8gdGhlIGl0ZW0ncyBKU09OQiwgYW5kIFBvc3RncmVTUUwga2VlcHMgYW4gaW5kZXggb3ZlciB0aGVtLiBBIEdTSSBxdWVyeSBsb29rcyB1cCB0aGUgaW5kZXgsIHRoZW4gdGhlIGFkYXB0ZXIgZmlsdGVycyBhbmQgb3JkZXJzIHRoZSByZXN1bHRzLiBUaGUgaW5kZXggZmllbGRzIGFyZSBzYXZlZCB3aXRoIHRoZSBpdGVtLCBzbyB0aGUgaW5kZXggaXMgc3Ryb25nbHkgY29uc2lzdGVudC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iYTYiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzA0Nzg1NyIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJhNnEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzRmNDZlNSIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjEwMSIgeT0iNjUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5QdXRJdGVtPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+c3RhdHVzID0gU0hJUFBFRDwvdGV4dD4KPGxpbmUgeDE9IjE3NiIgeTE9IjY5IiB4Mj0iMjMyIiB5Mj0iNjkiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhNikiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIyMDQiIHk9IjYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmluZGV4IGtleXM8L3RleHQ+CjxyZWN0IHg9IjIzNiIgeT0iMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNzAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzI2IiB5PSI1OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMnB4Ij5pdGVtIEpTT05CPC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9Ijc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij4rIF9pZHhfeF9oIChwYXJ0aXRpb24ga2V5KTwvdGV4dD4KPHRleHQgeD0iMzI2IiB5PSI5MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+KyBfaWR4X3hfbyAoc29ydCBrZXkpPC90ZXh0Pgo8bGluZSB4MT0iMzI2IiB5MT0iMTA0IiB4Mj0iMzI2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTYpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzM4IiB5PSIxMjIiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+c2FtZSB0cmFuc2FjdGlvbjwvdGV4dD4KPHJlY3QgeD0iMjM2IiB5PSIxMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMzI2IiB5PSIxNTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTEuNXB4Ij5Qb3N0Z3JlU1FMIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+b24gKF9pZHhfeF9oLCBfaWR4X3hfbyk8L3RleHQ+CjxyZWN0IHg9IjUwMCIgeT0iNDAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNTgiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTc1IiB5PSI2NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlF1ZXJ5IEdTSTwvdGV4dD4KPHRleHQgeD0iNTc1IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnN0YXR1cyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSI1NzUiIHkxPSI5OCIgeDI9IjU3NSIgeTI9IjE2NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIHN0eWxlPSJzdHJva2U6IzRmNDZlNSIvPgo8bGluZSB4MT0iNTc1IiB5MT0iMTY0IiB4Mj0iNDE4IiB5Mj0iMTY0IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNnEpIiBzdHlsZT0ic3Ryb2tlOiM0ZjQ2ZTUiLz4KPHRleHQgeD0iNDk2IiB5PSIxNTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiM0ZjQ2ZTUiPmluZGV4IGxvb2t1cCArIGZpbHRlcjwvdGV4dD4KPHRleHQgeD0iNjkwIiB5PSI3MCIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NTtmb250LXdlaWdodDo2MDAiPlN0cm9uZ2x5IGNvbnNpc3RlbnQ6PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjkwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dGhlIGl0ZW0gYW5kIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjEwNiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmNvbW1pdCB0b2dldGhlci48L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTMwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+RHluYW1vREIgR1NJcyBhcmU8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+ZXZlbnR1YWxseSBjb25zaXN0ZW50LjwvdGV4dD4KPC9zdmc+)

![On each write, the adapter adds two index fields to the item's JSONB, and PostgreSQL keeps an index over them. A GSI query looks up the index, then the adapter filters and orders the results. The index fields are saved with the item, so the index is strongly consistent.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBlYWNoIHdyaXRlLCB0aGUgYWRhcHRlciBhZGRzIHR3byBpbmRleCBmaWVsZHMgdG8gdGhlIGl0ZW0ncyBKU09OQiwgYW5kIFBvc3RncmVTUUwga2VlcHMgYW4gaW5kZXggb3ZlciB0aGVtLiBBIEdTSSBxdWVyeSBsb29rcyB1cCB0aGUgaW5kZXgsIHRoZW4gdGhlIGFkYXB0ZXIgZmlsdGVycyBhbmQgb3JkZXJzIHRoZSByZXN1bHRzLiBUaGUgaW5kZXggZmllbGRzIGFyZSBzYXZlZCB3aXRoIHRoZSBpdGVtLCBzbyB0aGUgaW5kZXggaXMgc3Ryb25nbHkgY29uc2lzdGVudC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iYTYiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzZlZTdiNyIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJhNnEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2E1YjRmYyIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjEwMSIgeT0iNjUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5QdXRJdGVtPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+c3RhdHVzID0gU0hJUFBFRDwvdGV4dD4KPGxpbmUgeDE9IjE3NiIgeTE9IjY5IiB4Mj0iMjMyIiB5Mj0iNjkiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhNikiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIyMDQiIHk9IjYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmluZGV4IGtleXM8L3RleHQ+CjxyZWN0IHg9IjIzNiIgeT0iMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNzAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzI2IiB5PSI1OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMnB4Ij5pdGVtIEpTT05CPC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9Ijc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij4rIF9pZHhfeF9oIChwYXJ0aXRpb24ga2V5KTwvdGV4dD4KPHRleHQgeD0iMzI2IiB5PSI5MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+KyBfaWR4X3hfbyAoc29ydCBrZXkpPC90ZXh0Pgo8bGluZSB4MT0iMzI2IiB5MT0iMTA0IiB4Mj0iMzI2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTYpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzM4IiB5PSIxMjIiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+c2FtZSB0cmFuc2FjdGlvbjwvdGV4dD4KPHJlY3QgeD0iMjM2IiB5PSIxMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzI2IiB5PSIxNTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTEuNXB4Ij5Qb3N0Z3JlU1FMIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+b24gKF9pZHhfeF9oLCBfaWR4X3hfbyk8L3RleHQ+CjxyZWN0IHg9IjUwMCIgeT0iNDAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNTgiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTc1IiB5PSI2NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlF1ZXJ5IEdTSTwvdGV4dD4KPHRleHQgeD0iNTc1IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnN0YXR1cyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSI1NzUiIHkxPSI5OCIgeDI9IjU3NSIgeTI9IjE2NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIHN0eWxlPSJzdHJva2U6I2E1YjRmYyIvPgo8bGluZSB4MT0iNTc1IiB5MT0iMTY0IiB4Mj0iNDE4IiB5Mj0iMTY0IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNnEpIiBzdHlsZT0ic3Ryb2tlOiNhNWI0ZmMiLz4KPHRleHQgeD0iNDk2IiB5PSIxNTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNhNWI0ZmMiPmluZGV4IGxvb2t1cCArIGZpbHRlcjwvdGV4dD4KPHRleHQgeD0iNjkwIiB5PSI3MCIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMTtmb250LXdlaWdodDo2MDAiPlN0cm9uZ2x5IGNvbnNpc3RlbnQ6PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjkwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dGhlIGl0ZW0gYW5kIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjEwNiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmNvbW1pdCB0b2dldGhlci48L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTMwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+RHluYW1vREIgR1NJcyBhcmU8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+ZXZlbnR1YWxseSBjb25zaXN0ZW50LjwvdGV4dD4KPC9zdmc+)

A GSI uses a PostgreSQL index to find candidates, which the adapter filters and orders; the index updates with the item.

#### Transactions

`TransactWriteItems` runs in one PostgreSQL transaction at `SERIALIZABLE` isolation: a debit in one table and a credit in another both commit or both fail, as in DynamoDB. DynamoDB's 100-action limit and one-operation-per-item rule apply.

The adapter saves the `ClientRequestToken` in the same transaction, so within DynamoDB's idempotency window a retry with the same token returns the earlier success without writing again. Row locks are taken in a fixed order so opposite transfers do not deadlock, and serialization or deadlock failures return retryable conflicts. A transaction that touches a table with Streams enabled returns `ValidationException` before it runs, because transactions do not write stream records.

![A TransactWriteItems request with a debit in one table and a credit in another commits atomically in one PostgreSQL transaction at SERIALIZABLE isolation, as on DynamoDB.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA2IiB2aWV3Qm94PSIwIDAgODM2IDIwNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIFRyYW5zYWN0V3JpdGVJdGVtcyByZXF1ZXN0IHdpdGggYSBkZWJpdCBpbiBvbmUgdGFibGUgYW5kIGEgY3JlZGl0IGluIGFub3RoZXIgY29tbWl0cyBhdG9taWNhbGx5IGluIG9uZSBQb3N0Z3JlU1FMIHRyYW5zYWN0aW9uIGF0IFNFUklBTElaQUJMRSBpc29sYXRpb24sIGFzIG9uIER5bmFtb0RCLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJhNyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojMDQ3ODU3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPkNST1NTLVRBQkxFIOKGkiBPTkUgQVRPTUlDIENPTU1JVDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjEyNiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIxMDEiIHk9IjY0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPlRyYW5zYWN0V3JpdGU8L3RleHQ+CjxyZWN0IHg9IjQwIiB5PSI3OCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIzNCIgcng9IjciIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTAxIiB5PSI5MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+ZGViaXQ8L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij5kZGJfYWNjb3VudHM8L3RleHQ+CjxyZWN0IHg9IjQwIiB5PSIxMTgiIHdpZHRoPSIxMjIiIGhlaWdodD0iMzQiIHJ4PSI3IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjEwMSIgeT0iMTMzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5jcmVkaXQ8L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iMTQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij5kZGJfbGVkZ2VyPC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iMTAzIiB4Mj0iMjM2IiB5Mj0iMTAzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTcpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjA2IiB5PSI5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj5vbmUgdHhuPC90ZXh0Pgo8cmVjdCB4PSIyNDAiIHk9IjUyIiB3aWR0aD0iMjI4IiBoZWlnaHQ9IjEwMiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzNTQiIHk9Ijc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEycHgiPkJFR0lOIOKApiBDT01NSVQ8L3RleHQ+Cjx0ZXh0IHg9IjM1NCIgeT0iOTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPlNFUklBTElaQUJMRSBpc29sYXRpb248L3RleHQ+Cjx0ZXh0IHg9IjM1NCIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5ib3RoIHRhYmxlcywgYXRvbWljYWxseTwvdGV4dD4KPHRleHQgeD0iMzU0IiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZpbGw6IzMzNDE1NSI+bG9ja3MgdGFrZW4gaW4gYSBmaXhlZCBvcmRlcjwvdGV4dD4KPHRleHQgeD0iMzU0IiB5PSIxNDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZpbGw6IzMzNDE1NSI+Q2xpZW50UmVxdWVzdFRva2VuIOKGkiBjb21taXRzIG9uY2U8L3RleHQ+CjxsaW5lIHgxPSI0ODQiIHkxPSIzNCIgeDI9IjQ4NCIgeTI9IjE3MiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1MDgiIHk9IjY2IiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHg7ZmlsbDojMDQ3ODU3Ij5Dcm9zcy10YWJsZSBBQ0lEPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjkwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMzM0MTU1Ij5EeW5hbW9EQiBhbmQgdGhpcyBiYWNrZW5kPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjEwNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NSI+Y29tbWl0IGFjcm9zcyB0YWJsZXMuPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjEyNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NSI+U3RyZWFtLWVuYWJsZWQgdGFibGVzPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjE0NCIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NSI+cmVqZWN0IHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjE2MSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NSI+cmVxdWVzdHMuPC90ZXh0Pgo8L3N2Zz4=)

![A TransactWriteItems request with a debit in one table and a credit in another commits atomically in one PostgreSQL transaction at SERIALIZABLE isolation, as on DynamoDB.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA2IiB2aWV3Qm94PSIwIDAgODM2IDIwNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIFRyYW5zYWN0V3JpdGVJdGVtcyByZXF1ZXN0IHdpdGggYSBkZWJpdCBpbiBvbmUgdGFibGUgYW5kIGEgY3JlZGl0IGluIGFub3RoZXIgY29tbWl0cyBhdG9taWNhbGx5IGluIG9uZSBQb3N0Z3JlU1FMIHRyYW5zYWN0aW9uIGF0IFNFUklBTElaQUJMRSBpc29sYXRpb24sIGFzIG9uIER5bmFtb0RCLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJhNyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNmVlN2I3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPkNST1NTLVRBQkxFIOKGkiBPTkUgQVRPTUlDIENPTU1JVDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjEyNiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIxMDEiIHk9IjY0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPlRyYW5zYWN0V3JpdGU8L3RleHQ+CjxyZWN0IHg9IjQwIiB5PSI3OCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIzNCIgcng9IjciIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTAxIiB5PSI5MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+ZGViaXQ8L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij5kZGJfYWNjb3VudHM8L3RleHQ+CjxyZWN0IHg9IjQwIiB5PSIxMTgiIHdpZHRoPSIxMjIiIGhlaWdodD0iMzQiIHJ4PSI3IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjEwMSIgeT0iMTMzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5jcmVkaXQ8L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iMTQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij5kZGJfbGVkZ2VyPC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iMTAzIiB4Mj0iMjM2IiB5Mj0iMTAzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTcpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjA2IiB5PSI5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj5vbmUgdHhuPC90ZXh0Pgo8cmVjdCB4PSIyNDAiIHk9IjUyIiB3aWR0aD0iMjI4IiBoZWlnaHQ9IjEwMiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzNTQiIHk9Ijc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEycHgiPkJFR0lOIOKApiBDT01NSVQ8L3RleHQ+Cjx0ZXh0IHg9IjM1NCIgeT0iOTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPlNFUklBTElaQUJMRSBpc29sYXRpb248L3RleHQ+Cjx0ZXh0IHg9IjM1NCIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5ib3RoIHRhYmxlcywgYXRvbWljYWxseTwvdGV4dD4KPHRleHQgeD0iMzU0IiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZpbGw6I2NiZDVlMSI+bG9ja3MgdGFrZW4gaW4gYSBmaXhlZCBvcmRlcjwvdGV4dD4KPHRleHQgeD0iMzU0IiB5PSIxNDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZpbGw6I2NiZDVlMSI+Q2xpZW50UmVxdWVzdFRva2VuIOKGkiBjb21taXRzIG9uY2U8L3RleHQ+CjxsaW5lIHgxPSI0ODQiIHkxPSIzNCIgeDI9IjQ4NCIgeTI9IjE3MiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1MDgiIHk9IjY2IiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHg7ZmlsbDojNmVlN2I3Ij5Dcm9zcy10YWJsZSBBQ0lEPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjkwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojY2JkNWUxIj5EeW5hbW9EQiBhbmQgdGhpcyBiYWNrZW5kPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjEwNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMSI+Y29tbWl0IGFjcm9zcyB0YWJsZXMuPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjEyNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMSI+U3RyZWFtLWVuYWJsZWQgdGFibGVzPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjE0NCIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMSI+cmVqZWN0IHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjE2MSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMSI+cmVxdWVzdHMuPC90ZXh0Pgo8L3N2Zz4=)

TransactWriteItems runs in one PostgreSQL transaction at SERIALIZABLE isolation, atomic across tables.

#### Limitations

* **Hot keys behave differently: one PostgreSQL instance holds each table.** Heavy contention on one key causes serialization failures and row-lock conflicts. The adapter returns retryable errors, but sustained contention can use up the SDK's retry budget and appear as throttling.
* **You must run one writer per table with Streams enabled.** A writer lease of about 90 seconds keeps stream records in order; a second adapter instance writing during the lease gets a retryable `ThrottlingException`. Throughput depends on the writer, database and workload. Tables without streams accept concurrent writers.
* **Listing more than 100 shards in `DescribeStream` is not supported.** A stream with more shards is not fully listed in one call.
* **Transactions on tables with Streams enabled are not supported.** A `TransactWriteItems` request touching one returns `ValidationException`, because transactions do not write stream records.
* **DynamoDB backup and global-table APIs are not supported.** On-demand backup and restore, point-in-time recovery (PITR) and global-table replication APIs are not available. Use PostgreSQL backups, snapshots, PITR and replica failover instead.
* **Capacity behaves differently: it is provisioned and billed while idle.** Size PostgreSQL capacity ahead of demand. More tables need more instances and table-placement planning.
* **Index lookups over 10,000 items are not supported.** A lookup that examines more than 10,000 items for one index partition-key value returns an error.
* **You must plan around the 500-table limit.** The adapter checks 500 DynamoDB tables per namespace. Larger deployments need database capacity and table-placement planning.
* **Expired items behave differently: they stay readable until deleted.** A background job deletes expired rows through the TTL index in bounded batches. Until then, `GetItem`, `Query` and `Scan` can return the item, and it still uses storage.

#### Other considerations

* **Stream records.** Each change record is saved in the table's `_strm` table in the same transaction as the write, so a record exists only if its write committed. The single-writer lease keeps record order equal to commit order, so a reader can resume without skipping records.
* **Connections.** The adapter pools PostgreSQL connections. With many adapter instances, you may need a separate pooler to keep total connections under the database's limit.
* **Moving data.** Move and test one table at a time, by export and import, dual writes or backfill and switch. Application code keeps using the DynamoDB API.
* **Operations.** Monitor SQL activity, maintain indexes, vacuum tables and run backups, PITR and failover with your usual PostgreSQL tools.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/7de6a41211e0eb618cd1964828b7df7f98da447b28efe9a51f93524e99b6c14b-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/613f28a3398f525db420f29c15b2ca728dcc7429f5d01ff38de313b762dec45c-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Target scenario | PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | PostgreSQL (one copy) | 80.90 | 80.90 |
| 0 | 0.00 | PostgreSQL (two copies) | 161.79 | 161.79 |
| 1 | 0.33 | PostgreSQL (one copy) | 80.90 | 80.57 |
| 1 | 0.33 | PostgreSQL (two copies) | 161.79 | 161.46 |
| 10 | 3.29 | PostgreSQL (one copy) | 80.90 | 77.61 |
| 10 | 3.29 | PostgreSQL (two copies) | 161.79 | 158.51 |
| 100 | 32.85 | PostgreSQL (one copy) | 80.90 | 48.05 |
| 100 | 32.85 | PostgreSQL (two copies) | 161.79 | 128.94 |
| 1,000 | 328.50 | PostgreSQL (one copy) | 80.90 | -247.60 |
| 1,000 | 328.50 | PostgreSQL (two copies) | 161.79 | -166.71 |
| 10,000 | 3,285.00 | PostgreSQL (one copy) | 1,144.34 | -2,140.66 |
| 10,000 | 3,285.00 | PostgreSQL (two copies) | 2,288.68 | -996.32 |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 32 vCPU, 128 GiB memory and 100 GiB SSD at 10,000 per second.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| PostgreSQL (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (one copy) | Representative item size | 1,024 | bytes |
| PostgreSQL (one copy) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (one copy) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (one copy) | Target reads per point read | 1 | operations |
| PostgreSQL (one copy) | Target writes per item write | 1 | operations |
| PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (one copy) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (one copy) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (one copy) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (one copy) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| PostgreSQL (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (two copies) | Representative item size | 1,024 | bytes |
| PostgreSQL (two copies) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (two copies) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (two copies) | Target reads per point read | 1 | operations |
| PostgreSQL (two copies) | Target writes per item write | 1 | operations |
| PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (two copies) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (two copies) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (two copies) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (two copies) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Self-hosted target: PostgreSQL (PostgreSQL License, [https://www.postgresql.org/about/licence/](https://www.postgresql.org/about/licence/)). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer's Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.
* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.
* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
* Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB ([https://docs.cloud.google.com/compute/docs/general-purpose-machines](https://docs.cloud.google.com/compute/docs/general-purpose-machines)); a Persistent Disk volume holds up to 64 TiB ([https://docs.cloud.google.com/compute/docs/disks/persistent-disks](https://docs.cloud.google.com/compute/docs/disks/persistent-disks)).
* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.
* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Compute Engine general-purpose machine pricing: [https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose)
* Disk and image pricing: [https://cloud.google.com/compute/disks-image-pricing](https://cloud.google.com/compute/disks-image-pricing)
* Network pricing: [https://cloud.google.com/vpc/network-pricing](https://cloud.google.com/vpc/network-pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-271febef7b5ad970d96d5373c36c91bf2d6b17bb` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/added456832698012afd2e92c8a1bd0981ba6a1f2798ec6fa8fec78745a06582-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/7f8bdf40ebbea0ed1102c06aa92bef45abd075a62614a27852da01b7e8c46c46-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Target scenario | PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | PostgreSQL (one copy) | 80.90 | 80.90 |
| 0 | 0.00 | PostgreSQL (two copies) | 161.79 | 161.79 |
| 1 | 1.64 | PostgreSQL (one copy) | 80.90 | 79.25 |
| 1 | 1.64 | PostgreSQL (two copies) | 161.79 | 160.15 |
| 10 | 16.43 | PostgreSQL (one copy) | 80.90 | 64.47 |
| 10 | 16.43 | PostgreSQL (two copies) | 161.79 | 145.37 |
| 100 | 164.25 | PostgreSQL (one copy) | 80.90 | -83.35 |
| 100 | 164.25 | PostgreSQL (two copies) | 161.79 | -2.46 |
| 1,000 | 1,642.50 | PostgreSQL (one copy) | 80.90 | -1,561.60 |
| 1,000 | 1,642.50 | PostgreSQL (two copies) | 161.79 | -1,480.71 |
| 10,000 | 16,425.00 | PostgreSQL (one copy) | 1,144.34 | -15,280.66 |
| 10,000 | 16,425.00 | PostgreSQL (two copies) | 2,288.68 | -14,136.32 |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 32 vCPU, 128 GiB memory and 100 GiB SSD at 10,000 per second.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| PostgreSQL (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (one copy) | Representative item size | 1,024 | bytes |
| PostgreSQL (one copy) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (one copy) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (one copy) | Target reads per point read | 1 | operations |
| PostgreSQL (one copy) | Target writes per item write | 1 | operations |
| PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (one copy) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (one copy) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (one copy) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (one copy) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| PostgreSQL (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (two copies) | Representative item size | 1,024 | bytes |
| PostgreSQL (two copies) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (two copies) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (two copies) | Target reads per point read | 1 | operations |
| PostgreSQL (two copies) | Target writes per item write | 1 | operations |
| PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (two copies) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (two copies) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (two copies) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (two copies) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Self-hosted target: PostgreSQL (PostgreSQL License, [https://www.postgresql.org/about/licence/](https://www.postgresql.org/about/licence/)). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer's Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.
* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.
* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
* Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB ([https://docs.cloud.google.com/compute/docs/general-purpose-machines](https://docs.cloud.google.com/compute/docs/general-purpose-machines)); a Persistent Disk volume holds up to 64 TiB ([https://docs.cloud.google.com/compute/docs/disks/persistent-disks](https://docs.cloud.google.com/compute/docs/disks/persistent-disks)).
* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.
* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Compute Engine general-purpose machine pricing: [https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose)
* Disk and image pricing: [https://cloud.google.com/compute/disks-image-pricing](https://cloud.google.com/compute/disks-image-pricing)
* Network pricing: [https://cloud.google.com/vpc/network-pricing](https://cloud.google.com/vpc/network-pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-271febef7b5ad970d96d5373c36c91bf2d6b17bb` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/84a517b1df5a949a2f9b0ba4a09df8ee4e51f363ef98bfd97c2edd5291eb795c-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/cda462fd8112cd349b433eb859ceefcb6afd87a33d351d049fa3a1698ba2bf59-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Target scenario | PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | PostgreSQL (one copy) | 80.90 | 80.90 |
| 0 | 0.00 | PostgreSQL (two copies) | 161.79 | 161.79 |
| 10 | 2.50 | PostgreSQL (one copy) | 80.90 | 78.40 |
| 10 | 2.50 | PostgreSQL (two copies) | 161.79 | 159.29 |
| 100 | 25.00 | PostgreSQL (one copy) | 92.08 | 67.08 |
| 100 | 25.00 | PostgreSQL (two copies) | 184.16 | 159.16 |
| 1,000 | 250.00 | PostgreSQL (one copy) | 806.02 | 556.02 |
| 1,000 | 250.00 | PostgreSQL (two copies) | 1,612.03 | 1,362.03 |
| 10,000 | 2,500.00 | PostgreSQL (one copy) | 6,878.59 | 4,378.59 |
| 10,000 | 2,500.00 | PostgreSQL (two copies) | 13,757.18 | 11,257.18 |
| 100,000 | 25,000.00 | PostgreSQL (one copy) | Unpriced | Unavailable |
| 100,000 | 25,000.00 | PostgreSQL (two copies) | Unpriced | Unavailable |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 GiB-month to 128 vCPU, 864 GiB memory and 12,525 GiB SSD at 10,000 GiB-month. From 100,000 GiB-month the workload exceeds the planning range and the target is unpriced.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| PostgreSQL (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (one copy) | Representative item size | 1,024 | bytes |
| PostgreSQL (one copy) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (one copy) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (one copy) | Target reads per point read | 1 | operations |
| PostgreSQL (one copy) | Target writes per item write | 1 | operations |
| PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (one copy) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (one copy) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (one copy) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (one copy) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| PostgreSQL (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (two copies) | Representative item size | 1,024 | bytes |
| PostgreSQL (two copies) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (two copies) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (two copies) | Target reads per point read | 1 | operations |
| PostgreSQL (two copies) | Target writes per item write | 1 | operations |
| PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (two copies) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (two copies) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (two copies) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (two copies) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Self-hosted target: PostgreSQL (PostgreSQL License, [https://www.postgresql.org/about/licence/](https://www.postgresql.org/about/licence/)). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer's Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.
* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.
* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
* Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB ([https://docs.cloud.google.com/compute/docs/general-purpose-machines](https://docs.cloud.google.com/compute/docs/general-purpose-machines)); a Persistent Disk volume holds up to 64 TiB ([https://docs.cloud.google.com/compute/docs/disks/persistent-disks](https://docs.cloud.google.com/compute/docs/disks/persistent-disks)).
* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.
* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Compute Engine general-purpose machine pricing: [https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose)
* Disk and image pricing: [https://cloud.google.com/compute/disks-image-pricing](https://cloud.google.com/compute/disks-image-pricing)
* Network pricing: [https://cloud.google.com/vpc/network-pricing](https://cloud.google.com/vpc/network-pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-271febef7b5ad970d96d5373c36c91bf2d6b17bb` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

**DynamoDB → PostgreSQL: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Provisioned primary CPU | 46.15 |
| Target: Provisioned primary RAM | 24.74 |
| Target: Provisioned primary disk | 10.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent provisioned resources | 0.00 |
| Target: Independent managed resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **80.90** |

Estimated allocation, not benchmark calibrated: sized at 2 vCPU, 8 GiB memory and 100 GiB SSD for this scenario.

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.1 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Self-hosted target: PostgreSQL (PostgreSQL License, [https://www.postgresql.org/about/licence/](https://www.postgresql.org/about/licence/)). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer's Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.

* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.

* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.

* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.

* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.

* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.

* Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB ([https://docs.cloud.google.com/compute/docs/general-purpose-machines](https://docs.cloud.google.com/compute/docs/general-purpose-machines)); a Persistent Disk volume holds up to 64 TiB ([https://docs.cloud.google.com/compute/docs/disks/persistent-disks](https://docs.cloud.google.com/compute/docs/disks/persistent-disks)).

* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.

* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.

* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.

List prices read: 2026-10-22. Model: `plan-271febef7b5ad970d96d5373c36c91bf2d6b17bb` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

## On Azure

### Azure Cosmos DB (provisioned)

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| DescribeContinuousBackups | Backups | Partial | Full surface | PITR status mapped from the Cosmos continuous-backup mode |
| On-demand backups (CreateBackup / RestoreTableFromBackup / …) | Backups | Out of scope | Full surface | the snapshot-backup model differs from Cosmos; Use the backend's backup and restore workflow. |
| UpdateContinuousBackups | Backups | Partial | Full surface | toggles PITR onto Cosmos continuous backup (the retention window differs) |
| ConditionExpression | Conditional writes | Supported | Common | condition and mutation execute atomically in a stored procedure, eligible PATCH or etag-guarded fallback; write conflicts are retryable |
| Global tables (CreateGlobalTable / UpdateGlobalTable / …) | Global | Out of scope | Full surface | DynamoDB global-table control APIs are outside this mapping; configure the deployment in the target environment and its region separately. |
| DescribeStream | Indexes + streams | Supported | Full surface | returns the shard list and stream ARN |
| GetRecords | Indexes + streams | Supported | Full surface | records co-commit atomically with the write; all four view types; 24-hour retention with TrimmedDataAccessException below the horizon; one writing instance per streamed table |
| GetShardIterator | Indexes + streams | Supported | Full surface | - |
| ListStreams | Indexes + streams | Supported | Full surface | the streamed-table registry |
| Query (GSI) | Indexes + streams | Supported | Most usage | each global secondary index is a dedicated Azure-maintained index container, so a GSI query reads its own index rather than scanning the table; propagation is eventually consistent, matching DynamoDB's own GSI behavior, and a strongly-consistent read on a GSI is rejected exactly as DynamoDB rejects it |
| Query (LSI) | Indexes + streams | Supported | Most usage | a local secondary index shares the table's own container and partition route, so an LSI query reflects a write immediately; large index partitions are subject to a per-query candidate limit |
| S3 import/export + Kinesis streaming + ContributorInsights + ResourcePolicy | Out of scope | Out of scope | Full surface | These AWS integrations are outside the listed mapping. |
| BatchExecuteStatement | PartiQL | Partial | Most usage | batched PartiQL statements, each statement gets its own real outcome |
| ExecuteStatement | PartiQL | Partial | Most usage | PartiQL select/insert/update/delete compiled to the native Cosmos query / item path; some PartiQL functions differ |
| ExecuteTransaction | PartiQL | Out of scope | Most usage | transactional PartiQL is unavailable on the current Cosmos adapter |
| BatchGetItem | Reads | Supported | Most usage | the adapter executes each item operation and reports its result |
| BatchWriteItem | Reads | Supported | Most usage | the adapter executes each item operation and reports its result |
| Query | Reads | Partial | Common | native key/range/order/filter pushdown plus residual evaluation; pagination follows Cosmos result windows |
| Scan | Reads | Partial | Most usage | bounded native result windows; Limit and ScannedCount differ from DynamoDB pre-filter examined-item accounting |
| DeleteItem | Single item | Supported | Common | - |
| GetItem | Single item | Supported | Common | strongly consistent from any instance, whatever the ConsistentRead flag (never weaker than asked) |
| PutItem | Single item | Supported | Common | DynamoDB type tags preserved; native Cosmos numbers require at most 15 significant digits and representable range |
| UpdateItem | Single item | Supported | Common | eligible removals use native conditional PATCH; ordinary updates run in a partition-scoped stored procedure; other shapes use guarded read-modify-write |
| DescribeTimeToLive | TTL | Supported | Most usage | reads the container's TTL policy |
| UpdateTimeToLive | TTL | Supported | Most usage | the DynamoDB per-item TTL attribute is mapped to the Cosmos TTL policy |
| CreateTable | Table control plane | Supported | Most usage | registers a logical table in a deployed container; declared tables receive containers at compile time |
| DeleteTable | Table control plane | Supported | Most usage | logical generation change with bounded cleanup and metadata propagation |
| DescribeEndpoints | Table control plane | Supported | Full surface | returns the adapter endpoint |
| DescribeLimits | Table control plane | Supported | Full surface | account / table limits reported from the compiled config |
| DescribeTable | Table control plane | Supported | Most usage | returns the key schema and stream identifiers |
| ListTables | Table control plane | Supported | Most usage | - |
| UpdateTable | Table control plane | Supported | Most usage | index and stream definitions must match deployed configuration; throughput mode is selected at compile time |
| ListTagsOfResource | Tags | Supported | Full surface | - |
| TagResource | Tags | Supported | Full surface | - |
| UntagResource | Tags | Supported | Full surface | - |
| TransactGetItems | Transactions | Out of scope | Most usage | the current Cosmos adapter rejects DynamoDB transactional reads |
| TransactWriteItems | Transactions | Out of scope | Most usage | the current Cosmos adapter rejects DynamoDB multi-item transactions |

#### How it works

Your application keeps its DynamoDB SDK and code. Tensor9 runs a DynamoDB adapter beside it in the customer's environment and sets `AWS_ENDPOINT_URL_DYNAMODB` so the SDK sends its requests to the adapter over the local network. The adapter accepts DynamoDB requests and data types, returns DynamoDB responses and errors, and stores the data in Azure Cosmos DB.

Each item is stored as a Cosmos document. Most operations behave as they do on DynamoDB. The differences you can see are numeric precision, how results are paged, and multi-item transactions, which are rejected. The sections below describe each one.

![Before: on AWS your application's DynamoDB SDK calls Amazon DynamoDB. After: in the target cloud the same application and SDK call a Tensor9 adapter, which stores the data in Azure Cosmos DB.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIHNhbWUgYXBwbGljYXRpb24gYW5kIFNESyBjYWxsIGEgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBzdG9yZXMgdGhlIGRhdGEgaW4gQXp1cmUgQ29zbW9zIERCLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iYWgxIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDYiIHdpZHRoPSIzNTgiIGhlaWdodD0iMTE4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMzAiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojNjQ3NDhiIj5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI4MCIgd2lkdGg9IjEyMCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI5MCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEyLjVweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjkwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5EeW5hbW9EQiBTREs8L3RleHQ+CjxsaW5lIHgxPSIxNTAiIHkxPSIxMTMiIHgyPSIyMTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iMTgxIiB5PSIxMDQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiOyBmb250LXNpemU6OC41cHgiPkR5bmFtb0RCPC90ZXh0Pgo8cmVjdCB4PSIyMTQiIHk9IjgwIiB3aWR0aD0iMTQ4IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjI4OCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjExLjVweCI+QW1hem9uIER5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiNjYmQ1ZTEiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI3NzQiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMXB4Ij5Db3Ntb3MgREI8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+Q29yZSBTUUw8L3RleHQ+Cjwvc3ZnPg==)

![Before: on AWS your application's DynamoDB SDK calls Amazon DynamoDB. After: in the target cloud the same application and SDK call a Tensor9 adapter, which stores the data in Azure Cosmos DB.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIHNhbWUgYXBwbGljYXRpb24gYW5kIFNESyBjYWxsIGEgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBzdG9yZXMgdGhlIGRhdGEgaW4gQXp1cmUgQ29zbW9zIERCLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iYWgxIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDYiIHdpZHRoPSIzNTgiIGhlaWdodD0iMTE4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMzAiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojOTRhM2I4Ij5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI4MCIgd2lkdGg9IjEyMCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI5MCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEyLjVweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjkwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5EeW5hbW9EQiBTREs8L3RleHQ+CjxsaW5lIHgxPSIxNTAiIHkxPSIxMTMiIHgyPSIyMTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iMTgxIiB5PSIxMDQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4OyBmb250LXNpemU6OC41cHgiPkR5bmFtb0RCPC90ZXh0Pgo8cmVjdCB4PSIyMTQiIHk9IjgwIiB3aWR0aD0iMTQ4IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjI4OCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjExLjVweCI+QW1hem9uIER5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiM0NzU1NjkiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI3NzQiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMXB4Ij5Db3Ntb3MgREI8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+Q29yZSBTUUw8L3RleHQ+Cjwvc3ZnPg==)

Your application keeps using the DynamoDB API; an adapter beside it stores the data in Cosmos DB.

#### Architecture

The adapter keeps no data of its own. Items and table definitions live in Cosmos, and the adapter connects with the customer's workload identity, so an adapter instance can restart without recovering anything. A table with DynamoDB Streams enabled still accepts writes from only one adapter instance at a time.

Tensor9 provisions one Cosmos account and one `ddb` database per stack, with a container for each declared table. The backend you select sets provisioned or serverless throughput for the account. Each item's partition key starts with its table name, and a reserved `_tablemeta` partition holds table definitions and creation times. Tables created at runtime share an existing container, as described below. A local secondary index lives in its table's container. On the provisioned backend, each global secondary index has a separate container that Azure updates asynchronously.

![Architecture: your app's DynamoDB SDK calls the Tensor9 adapter, which keeps no data of its own and stores everything in Azure Cosmos DB. The stack has one Cosmos account with one database named ddb. Each declared table has its own container, partitioned on /\_pk, holding its items and a partition of table definitions. Each global secondary index has its own index container that Azure keeps up to date, and a local secondary index lives in its table's container. Runtime-created tables share a deployed container and its capacity.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBcmNoaXRlY3R1cmU6IHlvdXIgYXBwJ3MgRHluYW1vREIgU0RLIGNhbGxzIHRoZSBUZW5zb3I5IGFkYXB0ZXIsIHdoaWNoIGtlZXBzIG5vIGRhdGEgb2YgaXRzIG93biBhbmQgc3RvcmVzIGV2ZXJ5dGhpbmcgaW4gQXp1cmUgQ29zbW9zIERCLiBUaGUgc3RhY2sgaGFzIG9uZSBDb3Ntb3MgYWNjb3VudCB3aXRoIG9uZSBkYXRhYmFzZSBuYW1lZCBkZGIuIEVhY2ggZGVjbGFyZWQgdGFibGUgaGFzIGl0cyBvd24gY29udGFpbmVyLCBwYXJ0aXRpb25lZCBvbiAvX3BrLCBob2xkaW5nIGl0cyBpdGVtcyBhbmQgYSBwYXJ0aXRpb24gb2YgdGFibGUgZGVmaW5pdGlvbnMuIEVhY2ggZ2xvYmFsIHNlY29uZGFyeSBpbmRleCBoYXMgaXRzIG93biBpbmRleCBjb250YWluZXIgdGhhdCBBenVyZSBrZWVwcyB1cCB0byBkYXRlLCBhbmQgYSBsb2NhbCBzZWNvbmRhcnkgaW5kZXggbGl2ZXMgaW4gaXRzIHRhYmxlJ3MgY29udGFpbmVyLiBSdW50aW1lLWNyZWF0ZWQgdGFibGVzIHNoYXJlIGEgZGVwbG95ZWQgY29udGFpbmVyIGFuZCBpdHMgY2FwYWNpdHkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhciIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iOCIgeT0iMzQiIHdpZHRoPSI4MjAiIGhlaWdodD0iMjA4IiByeD0iMTYiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjYiIHk9IjU0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiOCI+Q1VTVE9NRVInUyBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjExMCIgd2lkdGg9IjExNCIgaGVpZ2h0PSI5MiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI4MyIgeT0iMTUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEzcHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTY4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+RHluYW1vREIgU0RLPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTg0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnVuY2hhbmdlZDwvdGV4dD4KPGxpbmUgeDE9IjE0MCIgeTE9IjE1NiIgeDI9IjE5MiIgeTI9IjE1NiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FyKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+Cjx0ZXh0IHg9IjE2NiIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZm9udC1zaXplOjguNXB4Ij5EeW5hbW9EQjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxMjIiIHdpZHRoPSIxNjgiIGhlaWdodD0iNjgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjgwIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTNweCI+YWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMjgwIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmtlZXBzIG5vIGxvY2FsIGRhdGE8L3RleHQ+CjxsaW5lIHgxPSIzNjQiIHkxPSIxNTYiIHgyPSI0MzYiIHkyPSIxNTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhcikiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSI0MDAiIHk9IjE0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPkNvc21vcyBBUEk8L3RleHQ+Cjx0ZXh0IHg9IjQwMCIgeT0iMTcwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+bm8ga2V5czwvdGV4dD4KPHJlY3QgeD0iNDQwIiB5PSI3OCIgd2lkdGg9IjM3MiIgaGVpZ2h0PSIxNTYiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjI2IiB5PSI5OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPkF6dXJlIENvc21vcyBEQiDCtyB0aGUgc3RhY2sncyBhY2NvdW50PC90ZXh0Pgo8dGV4dCB4PSI2MjYiIHk9IjExMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6IzY0NzQ4YiI+ImRkYiIgwrcgY29udGFpbmVyIHBlciBkZWNsYXJlZCB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iNDU0IiB5PSIxMjAiIHdpZHRoPSIyMzAiIGhlaWdodD0iMTA0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjU2OSIgeT0iMTM1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDA7ZmlsbDojMzM0MTU1Ij50aGUgdGFibGUncyBjb250YWluZXI8L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNjQ3NDhiIj5wYXJ0aXRpb25lZCBvbiAvX3BrPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE1MyIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTY5IiB5PSIxNjciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPm9yZGVyc3x1IzQyICDihpIgIGl0ZW1zPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE3NyIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTY5IiB5PSIxOTEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPm9yZGVyc3x1Izg4ICDihpIgIGl0ZW1zPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjIwMSIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTY5IiB5PSIyMTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPl90YWJsZW1ldGEgIOKGkiAgdGFibGVzPC90ZXh0Pgo8cmVjdCB4PSI2OTYiIHk9IjEyMCIgd2lkdGg9IjEwMiIgaGVpZ2h0PSIxMDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzQ3IiB5PSIxNTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiMzMzQxNTUiPmluZGV4PC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjE2NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+Y29udGFpbmVyPC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjE4NyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnBlciBHU0ksPC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjIwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmV2ZW50dWFsPC90ZXh0Pgo8L3N2Zz4=)

![Architecture: your app's DynamoDB SDK calls the Tensor9 adapter, which keeps no data of its own and stores everything in Azure Cosmos DB. The stack has one Cosmos account with one database named ddb. Each declared table has its own container, partitioned on /\_pk, holding its items and a partition of table definitions. Each global secondary index has its own index container that Azure keeps up to date, and a local secondary index lives in its table's container. Runtime-created tables share a deployed container and its capacity.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBcmNoaXRlY3R1cmU6IHlvdXIgYXBwJ3MgRHluYW1vREIgU0RLIGNhbGxzIHRoZSBUZW5zb3I5IGFkYXB0ZXIsIHdoaWNoIGtlZXBzIG5vIGRhdGEgb2YgaXRzIG93biBhbmQgc3RvcmVzIGV2ZXJ5dGhpbmcgaW4gQXp1cmUgQ29zbW9zIERCLiBUaGUgc3RhY2sgaGFzIG9uZSBDb3Ntb3MgYWNjb3VudCB3aXRoIG9uZSBkYXRhYmFzZSBuYW1lZCBkZGIuIEVhY2ggZGVjbGFyZWQgdGFibGUgaGFzIGl0cyBvd24gY29udGFpbmVyLCBwYXJ0aXRpb25lZCBvbiAvX3BrLCBob2xkaW5nIGl0cyBpdGVtcyBhbmQgYSBwYXJ0aXRpb24gb2YgdGFibGUgZGVmaW5pdGlvbnMuIEVhY2ggZ2xvYmFsIHNlY29uZGFyeSBpbmRleCBoYXMgaXRzIG93biBpbmRleCBjb250YWluZXIgdGhhdCBBenVyZSBrZWVwcyB1cCB0byBkYXRlLCBhbmQgYSBsb2NhbCBzZWNvbmRhcnkgaW5kZXggbGl2ZXMgaW4gaXRzIHRhYmxlJ3MgY29udGFpbmVyLiBSdW50aW1lLWNyZWF0ZWQgdGFibGVzIHNoYXJlIGEgZGVwbG95ZWQgY29udGFpbmVyIGFuZCBpdHMgY2FwYWNpdHkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhciIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iOCIgeT0iMzQiIHdpZHRoPSI4MjAiIGhlaWdodD0iMjA4IiByeD0iMTYiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjYiIHk9IjU0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YiI+Q1VTVE9NRVInUyBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjExMCIgd2lkdGg9IjExNCIgaGVpZ2h0PSI5MiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI4MyIgeT0iMTUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEzcHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTY4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+RHluYW1vREIgU0RLPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTg0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnVuY2hhbmdlZDwvdGV4dD4KPGxpbmUgeDE9IjE0MCIgeTE9IjE1NiIgeDI9IjE5MiIgeTI9IjE1NiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FyKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+Cjx0ZXh0IHg9IjE2NiIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZm9udC1zaXplOjguNXB4Ij5EeW5hbW9EQjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxMjIiIHdpZHRoPSIxNjgiIGhlaWdodD0iNjgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjgwIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTNweCI+YWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMjgwIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmtlZXBzIG5vIGxvY2FsIGRhdGE8L3RleHQ+CjxsaW5lIHgxPSIzNjQiIHkxPSIxNTYiIHgyPSI0MzYiIHkyPSIxNTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhcikiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSI0MDAiIHk9IjE0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPkNvc21vcyBBUEk8L3RleHQ+Cjx0ZXh0IHg9IjQwMCIgeT0iMTcwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+bm8ga2V5czwvdGV4dD4KPHJlY3QgeD0iNDQwIiB5PSI3OCIgd2lkdGg9IjM3MiIgaGVpZ2h0PSIxNTYiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjI2IiB5PSI5OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPkF6dXJlIENvc21vcyBEQiDCtyB0aGUgc3RhY2sncyBhY2NvdW50PC90ZXh0Pgo8dGV4dCB4PSI2MjYiIHk9IjExMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6Izk0YTNiOCI+ImRkYiIgwrcgY29udGFpbmVyIHBlciBkZWNsYXJlZCB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iNDU0IiB5PSIxMjAiIHdpZHRoPSIyMzAiIGhlaWdodD0iMTA0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjU2OSIgeT0iMTM1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDA7ZmlsbDojY2JkNWUxIj50aGUgdGFibGUncyBjb250YWluZXI8L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojOTRhM2I4Ij5wYXJ0aXRpb25lZCBvbiAvX3BrPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE1MyIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTY5IiB5PSIxNjciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPm9yZGVyc3x1IzQyICDihpIgIGl0ZW1zPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE3NyIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTY5IiB5PSIxOTEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPm9yZGVyc3x1Izg4ICDihpIgIGl0ZW1zPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjIwMSIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTY5IiB5PSIyMTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPl90YWJsZW1ldGEgIOKGkiAgdGFibGVzPC90ZXh0Pgo8cmVjdCB4PSI2OTYiIHk9IjEyMCIgd2lkdGg9IjEwMiIgaGVpZ2h0PSIxMDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzQ3IiB5PSIxNTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiNjYmQ1ZTEiPmluZGV4PC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjE2NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+Y29udGFpbmVyPC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjE4NyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnBlciBHU0ksPC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjIwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmV2ZW50dWFsPC90ZXh0Pgo8L3N2Zz4=)

![How a request is carried out: the adapter checks each DynamoDB request and turns it into one Cosmos operation: a point read, a SQL query, a PATCH or a stored procedure. Cosmos holds a container per declared table, partitioned on /\_pk, and an index container per global secondary index that Azure keeps up to date. Runtime-created tables share a deployed container and its capacity.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJIb3cgYSByZXF1ZXN0IGlzIGNhcnJpZWQgb3V0OiB0aGUgYWRhcHRlciBjaGVja3MgZWFjaCBEeW5hbW9EQiByZXF1ZXN0IGFuZCB0dXJucyBpdCBpbnRvIG9uZSBDb3Ntb3Mgb3BlcmF0aW9uOiBhIHBvaW50IHJlYWQsIGEgU1FMIHF1ZXJ5LCBhIFBBVENIIG9yIGEgc3RvcmVkIHByb2NlZHVyZS4gQ29zbW9zIGhvbGRzIGEgY29udGFpbmVyIHBlciBkZWNsYXJlZCB0YWJsZSwgcGFydGl0aW9uZWQgb24gL19waywgYW5kIGFuIGluZGV4IGNvbnRhaW5lciBwZXIgZ2xvYmFsIHNlY29uZGFyeSBpbmRleCB0aGF0IEF6dXJlIGtlZXBzIHVwIHRvIGRhdGUuIFJ1bnRpbWUtY3JlYXRlZCB0YWJsZXMgc2hhcmUgYSBkZXBsb3llZCBjb250YWluZXIgYW5kIGl0cyBjYXBhY2l0eS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFjeDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj4KPG1hcmtlciBpZD0iYWN4MiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNi41IiBtYXJrZXJIZWlnaHQ9IjYuNSIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzA0Nzg1NyIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0MCIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIxNDAiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzMiIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5USEUgQURBUFRFUjwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjY0IiB3aWR0aD0iMTA2IiBoZWlnaHQ9IjQ2IiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iODMiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+RHluYW1vREI8L3RleHQ+Cjx0ZXh0IHg9IjgzIiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnlvdXIgcmVxdWVzdDwvdGV4dD4KPGxpbmUgeDE9IjEzNiIgeTE9Ijg3IiB4Mj0iMTU4IiB5Mj0iODciIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2FjeDIpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iMTY0IiB5PSI2NCIgd2lkdGg9IjEwNiIgaGVpZ2h0PSI0NiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjIxNyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5DaGVjazwvdGV4dD4KPHRleHQgeD0iMjE3IiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnR5cGVzIGFuZCBsaW1pdHM8L3RleHQ+CjxsaW5lIHgxPSIyNzAiIHkxPSI4NyIgeDI9IjI5MiIgeTI9Ijg3IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhY3gyKSIgc3R5bGU9InN0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjI5OCIgeT0iNjQiIHdpZHRoPSIxMDAiIGhlaWdodD0iNDYiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzNDgiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+Q29zbW9zIGNhbGw8L3RleHQ+Cjx0ZXh0IHg9IjM0OCIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vbmUgb3BlcmF0aW9uPC90ZXh0Pgo8dGV4dCB4PSIyMTIiIHk9IjE0MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmEgcG9pbnQgcmVhZCwgYSBTUUwgcXVlcnksIGEgUEFUQ0ggb3IgYSBzdG9yZWQgcHJvY2VkdXJlPC90ZXh0Pgo8bGluZSB4MT0iNDEyIiB5MT0iODciIHgyPSI0NTIiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYWN4MSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSI0NTgiIHk9IjQwIiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjE0MCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ3NCIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5BWlVSRSBDT1NNT1MgREI8L3RleHQ+CjxyZWN0IHg9IjQ3NiIgeT0iNjQiIHdpZHRoPSIxNTAiIGhlaWdodD0iNDQiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1NTEiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+RGVjbGFyZWQgdGFibGUgY29udGFpbmVyPC90ZXh0Pgo8dGV4dCB4PSI1NTEiIHk9Ijk5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cGFydGl0aW9uZWQgb24gL19wazwvdGV4dD4KPHJlY3QgeD0iNjQyIiB5PSI2NCIgd2lkdGg9IjE2MiIgaGVpZ2h0PSI0NCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjcyMyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5JbmRleCBwZXIgR1NJPC90ZXh0Pgo8dGV4dCB4PSI3MjMiIHk9Ijk5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+QXp1cmUtbWFpbnRhaW5lZDwvdGV4dD4KPHRleHQgeD0iNjM5IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vbmUgZGRiIGRhdGFiYXNlIGZvciB0aGUgc3RhY2s8L3RleHQ+Cjwvc3ZnPg==)

![How a request is carried out: the adapter checks each DynamoDB request and turns it into one Cosmos operation: a point read, a SQL query, a PATCH or a stored procedure. Cosmos holds a container per declared table, partitioned on /\_pk, and an index container per global secondary index that Azure keeps up to date. Runtime-created tables share a deployed container and its capacity.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJIb3cgYSByZXF1ZXN0IGlzIGNhcnJpZWQgb3V0OiB0aGUgYWRhcHRlciBjaGVja3MgZWFjaCBEeW5hbW9EQiByZXF1ZXN0IGFuZCB0dXJucyBpdCBpbnRvIG9uZSBDb3Ntb3Mgb3BlcmF0aW9uOiBhIHBvaW50IHJlYWQsIGEgU1FMIHF1ZXJ5LCBhIFBBVENIIG9yIGEgc3RvcmVkIHByb2NlZHVyZS4gQ29zbW9zIGhvbGRzIGEgY29udGFpbmVyIHBlciBkZWNsYXJlZCB0YWJsZSwgcGFydGl0aW9uZWQgb24gL19waywgYW5kIGFuIGluZGV4IGNvbnRhaW5lciBwZXIgZ2xvYmFsIHNlY29uZGFyeSBpbmRleCB0aGF0IEF6dXJlIGtlZXBzIHVwIHRvIGRhdGUuIFJ1bnRpbWUtY3JlYXRlZCB0YWJsZXMgc2hhcmUgYSBkZXBsb3llZCBjb250YWluZXIgYW5kIGl0cyBjYXBhY2l0eS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFjeDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj4KPG1hcmtlciBpZD0iYWN4MiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNi41IiBtYXJrZXJIZWlnaHQ9IjYuNSIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzZlZTdiNyIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0MCIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIxNDAiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzMiIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5USEUgQURBUFRFUjwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjY0IiB3aWR0aD0iMTA2IiBoZWlnaHQ9IjQ2IiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iODMiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+RHluYW1vREI8L3RleHQ+Cjx0ZXh0IHg9IjgzIiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnlvdXIgcmVxdWVzdDwvdGV4dD4KPGxpbmUgeDE9IjEzNiIgeTE9Ijg3IiB4Mj0iMTU4IiB5Mj0iODciIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2FjeDIpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iMTY0IiB5PSI2NCIgd2lkdGg9IjEwNiIgaGVpZ2h0PSI0NiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjIxNyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5DaGVjazwvdGV4dD4KPHRleHQgeD0iMjE3IiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnR5cGVzIGFuZCBsaW1pdHM8L3RleHQ+CjxsaW5lIHgxPSIyNzAiIHkxPSI4NyIgeDI9IjI5MiIgeTI9Ijg3IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhY3gyKSIgc3R5bGU9InN0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjI5OCIgeT0iNjQiIHdpZHRoPSIxMDAiIGhlaWdodD0iNDYiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzNDgiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+Q29zbW9zIGNhbGw8L3RleHQ+Cjx0ZXh0IHg9IjM0OCIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vbmUgb3BlcmF0aW9uPC90ZXh0Pgo8dGV4dCB4PSIyMTIiIHk9IjE0MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmEgcG9pbnQgcmVhZCwgYSBTUUwgcXVlcnksIGEgUEFUQ0ggb3IgYSBzdG9yZWQgcHJvY2VkdXJlPC90ZXh0Pgo8bGluZSB4MT0iNDEyIiB5MT0iODciIHgyPSI0NTIiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYWN4MSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSI0NTgiIHk9IjQwIiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjE0MCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ3NCIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5BWlVSRSBDT1NNT1MgREI8L3RleHQ+CjxyZWN0IHg9IjQ3NiIgeT0iNjQiIHdpZHRoPSIxNTAiIGhlaWdodD0iNDQiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1NTEiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+RGVjbGFyZWQgdGFibGUgY29udGFpbmVyPC90ZXh0Pgo8dGV4dCB4PSI1NTEiIHk9Ijk5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cGFydGl0aW9uZWQgb24gL19wazwvdGV4dD4KPHJlY3QgeD0iNjQyIiB5PSI2NCIgd2lkdGg9IjE2MiIgaGVpZ2h0PSI0NCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjcyMyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5JbmRleCBwZXIgR1NJPC90ZXh0Pgo8dGV4dCB4PSI3MjMiIHk9Ijk5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+QXp1cmUtbWFpbnRhaW5lZDwvdGV4dD4KPHRleHQgeD0iNjM5IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vbmUgZGRiIGRhdGFiYXNlIGZvciB0aGUgc3RhY2s8L3RleHQ+Cjwvc3ZnPg==)

The adapter keeps no data of its own; Cosmos holds it all. One account and one "ddb" database hold a container per declared table, partitioned on /\_pk. Runtime-created tables share a deployed container and its capacity.

Each DynamoDB request becomes one Cosmos operation. Each declared table has its own container; runtime-created tables share a deployed container and its capacity.

#### Schemas

Each item keeps its DynamoDB type tags inside the document's `item` field. Numbers are stored as native Cosmos JSON numbers, and binary values as hex that sorts in the same order. Extra fields record the table and partition each item belongs to.

**Numbers have less precision.** A number must have at most 15 significant digits and fit Cosmos's native number range. A value outside that is rejected before anything is stored; DynamoDB's full 38-digit numbers are not kept as strings.

**Items are still limited to 400 KiB.** Updates check the size of the resulting item, including the attributes copied into local secondary indexes. Cosmos's larger document limit does not lift this DynamoDB check.

![A DynamoDB item keeps its type tags inside the Cosmos document. Numbers are stored as native JSON numbers after their precision and range are checked.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0ga2VlcHMgaXRzIHR5cGUgdGFncyBpbnNpZGUgdGhlIENvc21vcyBkb2N1bWVudC4gTnVtYmVycyBhcmUgc3RvcmVkIGFzIG5hdGl2ZSBKU09OIG51bWJlcnMgYWZ0ZXIgdGhlaXIgcHJlY2lzaW9uIGFuZCByYW5nZSBhcmUgY2hlY2tlZC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iYTMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzA0Nzg1NyIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjMwIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojNjQ3NDhiIj5EWU5BTU9EQiBJVEVNPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iNDIiIHdpZHRoPSIzMDAiIGhlaWdodD0iMTgwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ0IiB5PSI3NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+JiMxMjM7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iOTgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiJwayI6ICAgICYjMTIzOyAiUyI6ICJ1c2VyIzQyIiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxMjIiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiJzayI6ICAgICYjMTIzOyAiUyI6ICJvcmRlciM3IiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxNDYiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiNiNDUzMDkiPiJ0b3RhbCI6ICYjMTIzOyAiTiI6ICIxMjMuNDUiICYjMTI1OzwvdGV4dD4KPHRleHQgeD0iNjAiIHk9IjE3MCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+InRhZ3MiOiAgJiMxMjM7ICJTUyI6IFsidmlwIl0gJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0NCIgeT0iMTk0IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4mIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjQ0IiB5PSIyMTQiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiNiNDUzMDkiPkFjY2VwdGVkIGhlcmU6IGF0IG1vc3QgMTUgc2lnbmlmaWNhbnQgZGlnaXRzPC90ZXh0Pgo8bGluZSB4MT0iMzM0IiB5MT0iMTMyIiB4Mj0iMzg2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTMpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzYwIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+c3RvcmU8L3RleHQ+Cjx0ZXh0IHg9IjM5NiIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPkNPU01PUyBET0NVTUVOVCAoc29tZSBmaWVsZHMgb21pdHRlZCk8L3RleHQ+CjxyZWN0IHg9IjM5NiIgeT0iNDIiIHdpZHRoPSI0MTQiIGhlaWdodD0iMTk4IiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQxNCIgeT0iNjgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiYjMTIzOzwvdGV4dD4KPHRleHQgeD0iNDMwIiB5PSI4OCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+ImlkIjogICAgICAgICJwaz1TOnVzZXIjNDJ8c2s9UzpvcmRlciM3Iiw8L3RleHQ+Cjx0ZXh0IHg9IjQzMCIgeT0iMTA3IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij4iX3BrIjogICAgICAgIm9yZGVyc3xTOnVzZXIjNDIiLDwvdGV4dD4KPHRleHQgeD0iNDMwIiB5PSIxMjYiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPiJfdGJsIjogICAgICAib3JkZXJzIiw8L3RleHQ+Cjx0ZXh0IHg9IjQzMCIgeT0iMTQ1IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij4iX2tleUF0dHJzIjogWyJwayIsInNrIl0sPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjE2NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+Iml0ZW0iOiAmIzEyMzs8L3RleHQ+Cjx0ZXh0IHg9IjQ0NiIgeT0iMTgzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojYjQ1MzA5Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAxMjMuNDUgJiMxMjU7LCAg4oCmPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjIwMiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0MTQiIHk9IjIyMSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+JiMxMjU7PC90ZXh0Pgo8L3N2Zz4=)

![A DynamoDB item keeps its type tags inside the Cosmos document. Numbers are stored as native JSON numbers after their precision and range are checked.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0ga2VlcHMgaXRzIHR5cGUgdGFncyBpbnNpZGUgdGhlIENvc21vcyBkb2N1bWVudC4gTnVtYmVycyBhcmUgc3RvcmVkIGFzIG5hdGl2ZSBKU09OIG51bWJlcnMgYWZ0ZXIgdGhlaXIgcHJlY2lzaW9uIGFuZCByYW5nZSBhcmUgY2hlY2tlZC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iYTMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzZlZTdiNyIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjMwIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojOTRhM2I4Ij5EWU5BTU9EQiBJVEVNPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iNDIiIHdpZHRoPSIzMDAiIGhlaWdodD0iMTgwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ0IiB5PSI3NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+JiMxMjM7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iOTgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiJwayI6ICAgICYjMTIzOyAiUyI6ICJ1c2VyIzQyIiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxMjIiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiJzayI6ICAgICYjMTIzOyAiUyI6ICJvcmRlciM3IiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxNDYiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNmYmJmMjQiPiJ0b3RhbCI6ICYjMTIzOyAiTiI6ICIxMjMuNDUiICYjMTI1OzwvdGV4dD4KPHRleHQgeD0iNjAiIHk9IjE3MCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+InRhZ3MiOiAgJiMxMjM7ICJTUyI6IFsidmlwIl0gJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0NCIgeT0iMTk0IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4mIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjQ0IiB5PSIyMTQiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNmYmJmMjQiPkFjY2VwdGVkIGhlcmU6IGF0IG1vc3QgMTUgc2lnbmlmaWNhbnQgZGlnaXRzPC90ZXh0Pgo8bGluZSB4MT0iMzM0IiB5MT0iMTMyIiB4Mj0iMzg2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTMpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzYwIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+c3RvcmU8L3RleHQ+Cjx0ZXh0IHg9IjM5NiIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPkNPU01PUyBET0NVTUVOVCAoc29tZSBmaWVsZHMgb21pdHRlZCk8L3RleHQ+CjxyZWN0IHg9IjM5NiIgeT0iNDIiIHdpZHRoPSI0MTQiIGhlaWdodD0iMTk4IiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjQxNCIgeT0iNjgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiYjMTIzOzwvdGV4dD4KPHRleHQgeD0iNDMwIiB5PSI4OCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+ImlkIjogICAgICAgICJwaz1TOnVzZXIjNDJ8c2s9UzpvcmRlciM3Iiw8L3RleHQ+Cjx0ZXh0IHg9IjQzMCIgeT0iMTA3IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij4iX3BrIjogICAgICAgIm9yZGVyc3xTOnVzZXIjNDIiLDwvdGV4dD4KPHRleHQgeD0iNDMwIiB5PSIxMjYiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPiJfdGJsIjogICAgICAib3JkZXJzIiw8L3RleHQ+Cjx0ZXh0IHg9IjQzMCIgeT0iMTQ1IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij4iX2tleUF0dHJzIjogWyJwayIsInNrIl0sPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjE2NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+Iml0ZW0iOiAmIzEyMzs8L3RleHQ+Cjx0ZXh0IHg9IjQ0NiIgeT0iMTgzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojZmJiZjI0Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAxMjMuNDUgJiMxMjU7LCAg4oCmPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjIwMiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0MTQiIHk9IjIyMSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+JiMxMjU7PC90ZXh0Pgo8L3N2Zz4=)

Type tags keep numbers, strings, binary values and sets distinct; native numbers let Cosmos evaluate conditions on them.

#### Where tables live

Each declared table has its own container, indexing policy and storage within the stack's shared account and database. The containers share account administration and lifecycle, so watch account limits as the number of tables grows.

You choose provisioned or serverless throughput when you select the backend. A provisioned container gets an autoscale range of request units (RUs) derived from the table's declared capacity; a `PAY_PER_REQUEST` table gets a configurable default range. Serverless containers bill for the requests they use and do not reserve the table's requested capacity. Throughput depends on request-unit use and on how evenly keys spread across partitions. Changing the selected backend recreates the account and containers, so plan a data migration.

Inside a container, a partition key that starts with the table name, such as `orders|S:user#42`, keeps tables apart. Point reads and base-table queries use that `_pk` value; scans and table lookups filter on `_tbl`. A runtime `CreateTable` writes a table record in the stack's first deployed container, because the adapter's identity has no permission to create Cosmos containers. `DescribeTable` and `ListTables` read those records.

* **A table needs a known key schema.** A composite-key table's key schema comes from a declared table, its table record, or the first request that includes the full key. A Put whose key schema cannot be determined is rejected; it is never written under a guessed key.
* **Declared tables get their own container; runtime-created tables share one.** A declared table's container, throughput, index and storage are its own. A table created at runtime shares a deployed container: the table-name prefix keeps its items apart, but it shares that container's physical partitions. A hot partition key is still limited by the capacity of the physical partition it lands on.

![All of a stack's tables share one Cosmos account with one database named ddb; each declared table keeps its own container, index and storage. The selected backend sets the account's throughput mode: provisioned gives each container its own autoscale range of request units, serverless bills per request with no throughput reserved per container. Runtime-created tables share a deployed container and its capacity.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjI2IiB2aWV3Qm94PSIwIDAgODM2IDIyNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBbGwgb2YgYSBzdGFjaydzIHRhYmxlcyBzaGFyZSBvbmUgQ29zbW9zIGFjY291bnQgd2l0aCBvbmUgZGF0YWJhc2UgbmFtZWQgZGRiOyBlYWNoIGRlY2xhcmVkIHRhYmxlIGtlZXBzIGl0cyBvd24gY29udGFpbmVyLCBpbmRleCBhbmQgc3RvcmFnZS4gVGhlIHNlbGVjdGVkIGJhY2tlbmQgc2V0cyB0aGUgYWNjb3VudCdzIHRocm91Z2hwdXQgbW9kZTogcHJvdmlzaW9uZWQgZ2l2ZXMgZWFjaCBjb250YWluZXIgaXRzIG93biBhdXRvc2NhbGUgcmFuZ2Ugb2YgcmVxdWVzdCB1bml0cywgc2VydmVybGVzcyBiaWxscyBwZXIgcmVxdWVzdCB3aXRoIG5vIHRocm91Z2hwdXQgcmVzZXJ2ZWQgcGVyIGNvbnRhaW5lci4gUnVudGltZS1jcmVhdGVkIHRhYmxlcyBzaGFyZSBhIGRlcGxveWVkIGNvbnRhaW5lciBhbmQgaXRzIGNhcGFjaXR5LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPlRIRSBTVEFDSydTIENPU01PUyBBQ0NPVU5UIMK3IGRhdGFiYXNlICJkZGIiPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iNDAiIHdpZHRoPSI1MjAiIGhlaWdodD0iMTY2IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjQ0IiB5PSI1OCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMTgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMTE5IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+Y29udGFpbmVyOiBvcmRlcnM8L3RleHQ+Cjx0ZXh0IHg9IjExOSIgeT0iMTAyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b3duIC9fcGsgcGFydGl0aW9uczwvdGV4dD4KPHRleHQgeD0iMTE5IiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj50aHJvdWdocHV0IHBlciBtb2RlPC90ZXh0Pgo8dGV4dCB4PSIxMTkiIHk9IjEzOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm93biBuYXRpdmUgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjExOSIgeT0iMTYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+X3RhYmxlbWV0YSByZWdpc3RyeTwvdGV4dD4KPHJlY3QgeD0iMjA2IiB5PSI1OCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMTgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMjgxIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+Y29udGFpbmVyOiB1c2VyczwvdGV4dD4KPHRleHQgeD0iMjgxIiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vd24gL19wayBwYXJ0aXRpb25zPC90ZXh0Pgo8dGV4dCB4PSIyODEiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnRocm91Z2hwdXQgcGVyIG1vZGU8L3RleHQ+Cjx0ZXh0IHg9IjI4MSIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b3duIG5hdGl2ZSBpbmRleDwvdGV4dD4KPHRleHQgeD0iMjgxIiB5PSIxNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5fdGFibGVtZXRhIHJlZ2lzdHJ5PC90ZXh0Pgo8cmVjdCB4PSIzNjgiIHk9IjU4IiB3aWR0aD0iMTYwIiBoZWlnaHQ9IjExOCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2E3ZjNkMCIvPgo8dGV4dCB4PSI0NDgiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij5jb250YWluZXI6IGV2ZW50czwvdGV4dD4KPHRleHQgeD0iNDQ4IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vd24gL19wayBwYXJ0aXRpb25zPC90ZXh0Pgo8dGV4dCB4PSI0NDgiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnRocm91Z2hwdXQgcGVyIG1vZGU8L3RleHQ+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b3duIG5hdGl2ZSBpbmRleDwvdGV4dD4KPHRleHQgeD0iNDQ4IiB5PSIxNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5fdGFibGVtZXRhIHJlZ2lzdHJ5PC90ZXh0Pgo8dGV4dCB4PSIyODYiIHk9IjE5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm9uZSBzb3VyY2UgY29udGFpbmVyIHBlciBkZWNsYXJlZCB0YWJsZTwvdGV4dD4KPHRleHQgeD0iNTc2IiB5PSIyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+QUNDT1VOVCBUSFJPVUdIUFVUIE1PREU8L3RleHQ+CjxyZWN0IHg9IjU3NiIgeT0iNDAiIHdpZHRoPSIyMzYiIGhlaWdodD0iMTY2IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI0IDQiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjk0IiB5PSI2MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiMzMzQxNTUiPm9uZSBtb2RlIGZvciB0aGUgZGVwbG95bWVudDwvdGV4dD4KPHJlY3QgeD0iNTkyIiB5PSI3NCIgd2lkdGg9IjIwNCIgaGVpZ2h0PSI1NiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjY5NCIgeT0iOTMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPjo6cHJvdmlzaW9uZWQ8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iMTA5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+ZWFjaCBjb250YWluZXIgaXRzIG93bjwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxMjIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5hdXRvc2NhbGUgUlUgcmFuZ2U8L3RleHQ+CjxyZWN0IHg9IjU5MiIgeT0iMTM4IiB3aWR0aD0iMjA0IiBoZWlnaHQ9IjYwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjk0IiB5PSIxNTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPjo6c2VydmVybGVzczwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxNzMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5iaWxsZWQgcGVyIHJlcXVlc3QsIG5vPC90ZXh0Pgo8dGV4dCB4PSI2OTQiIHk9IjE4NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnRocm91Z2hwdXQgdG8gcmVzZXJ2ZTwvdGV4dD4KPC9zdmc+)

![All of a stack's tables share one Cosmos account with one database named ddb; each declared table keeps its own container, index and storage. The selected backend sets the account's throughput mode: provisioned gives each container its own autoscale range of request units, serverless bills per request with no throughput reserved per container. Runtime-created tables share a deployed container and its capacity.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjI2IiB2aWV3Qm94PSIwIDAgODM2IDIyNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBbGwgb2YgYSBzdGFjaydzIHRhYmxlcyBzaGFyZSBvbmUgQ29zbW9zIGFjY291bnQgd2l0aCBvbmUgZGF0YWJhc2UgbmFtZWQgZGRiOyBlYWNoIGRlY2xhcmVkIHRhYmxlIGtlZXBzIGl0cyBvd24gY29udGFpbmVyLCBpbmRleCBhbmQgc3RvcmFnZS4gVGhlIHNlbGVjdGVkIGJhY2tlbmQgc2V0cyB0aGUgYWNjb3VudCdzIHRocm91Z2hwdXQgbW9kZTogcHJvdmlzaW9uZWQgZ2l2ZXMgZWFjaCBjb250YWluZXIgaXRzIG93biBhdXRvc2NhbGUgcmFuZ2Ugb2YgcmVxdWVzdCB1bml0cywgc2VydmVybGVzcyBiaWxscyBwZXIgcmVxdWVzdCB3aXRoIG5vIHRocm91Z2hwdXQgcmVzZXJ2ZWQgcGVyIGNvbnRhaW5lci4gUnVudGltZS1jcmVhdGVkIHRhYmxlcyBzaGFyZSBhIGRlcGxveWVkIGNvbnRhaW5lciBhbmQgaXRzIGNhcGFjaXR5LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPlRIRSBTVEFDSydTIENPU01PUyBBQ0NPVU5UIMK3IGRhdGFiYXNlICJkZGIiPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iNDAiIHdpZHRoPSI1MjAiIGhlaWdodD0iMTY2IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjQ0IiB5PSI1OCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMTgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMTE5IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+Y29udGFpbmVyOiBvcmRlcnM8L3RleHQ+Cjx0ZXh0IHg9IjExOSIgeT0iMTAyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b3duIC9fcGsgcGFydGl0aW9uczwvdGV4dD4KPHRleHQgeD0iMTE5IiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij50aHJvdWdocHV0IHBlciBtb2RlPC90ZXh0Pgo8dGV4dCB4PSIxMTkiIHk9IjEzOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm93biBuYXRpdmUgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjExOSIgeT0iMTYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+X3RhYmxlbWV0YSByZWdpc3RyeTwvdGV4dD4KPHJlY3QgeD0iMjA2IiB5PSI1OCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMTgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjgxIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+Y29udGFpbmVyOiB1c2VyczwvdGV4dD4KPHRleHQgeD0iMjgxIiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vd24gL19wayBwYXJ0aXRpb25zPC90ZXh0Pgo8dGV4dCB4PSIyODEiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnRocm91Z2hwdXQgcGVyIG1vZGU8L3RleHQ+Cjx0ZXh0IHg9IjI4MSIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b3duIG5hdGl2ZSBpbmRleDwvdGV4dD4KPHRleHQgeD0iMjgxIiB5PSIxNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5fdGFibGVtZXRhIHJlZ2lzdHJ5PC90ZXh0Pgo8cmVjdCB4PSIzNjgiIHk9IjU4IiB3aWR0aD0iMTYwIiBoZWlnaHQ9IjExOCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0NDgiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij5jb250YWluZXI6IGV2ZW50czwvdGV4dD4KPHRleHQgeD0iNDQ4IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vd24gL19wayBwYXJ0aXRpb25zPC90ZXh0Pgo8dGV4dCB4PSI0NDgiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnRocm91Z2hwdXQgcGVyIG1vZGU8L3RleHQ+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b3duIG5hdGl2ZSBpbmRleDwvdGV4dD4KPHRleHQgeD0iNDQ4IiB5PSIxNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5fdGFibGVtZXRhIHJlZ2lzdHJ5PC90ZXh0Pgo8dGV4dCB4PSIyODYiIHk9IjE5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm9uZSBzb3VyY2UgY29udGFpbmVyIHBlciBkZWNsYXJlZCB0YWJsZTwvdGV4dD4KPHRleHQgeD0iNTc2IiB5PSIyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+QUNDT1VOVCBUSFJPVUdIUFVUIE1PREU8L3RleHQ+CjxyZWN0IHg9IjU3NiIgeT0iNDAiIHdpZHRoPSIyMzYiIGhlaWdodD0iMTY2IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI0IDQiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjk0IiB5PSI2MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiNjYmQ1ZTEiPm9uZSBtb2RlIGZvciB0aGUgZGVwbG95bWVudDwvdGV4dD4KPHJlY3QgeD0iNTkyIiB5PSI3NCIgd2lkdGg9IjIwNCIgaGVpZ2h0PSI1NiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjY5NCIgeT0iOTMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPjo6cHJvdmlzaW9uZWQ8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iMTA5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+ZWFjaCBjb250YWluZXIgaXRzIG93bjwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxMjIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5hdXRvc2NhbGUgUlUgcmFuZ2U8L3RleHQ+CjxyZWN0IHg9IjU5MiIgeT0iMTM4IiB3aWR0aD0iMjA0IiBoZWlnaHQ9IjYwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjk0IiB5PSIxNTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPjo6c2VydmVybGVzczwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxNzMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5iaWxsZWQgcGVyIHJlcXVlc3QsIG5vPC90ZXh0Pgo8dGV4dCB4PSI2OTQiIHk9IjE4NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnRocm91Z2hwdXQgdG8gcmVzZXJ2ZTwvdGV4dD4KPC9zdmc+)

A stack's tables share one account and one "ddb" database, using the selected throughput mode. Each declared table has its own container; runtime-created tables share a deployed container and its capacity. At runtime, CreateTable, DeleteTable and UpdateTable change table records, not Cosmos resources.

#### Conditional writes

**How the adapter writes an item depends on the operation and its options.** Ordinary SET updates run in a stored procedure scoped to the item's partition. Cosmos reads the current item, checks the condition, applies the update and checks the 400 KiB item limit in one atomic step. This is read-modify-write inside the database, with no extra round trip from the adapter.

A Cosmos PATCH is used only in a narrower case. The condition must require the item or attribute to exist, every action must remove a top-level attribute, the table must have no TTL or stream, and the request must not ask for the old item. A SET that grows the item cannot use PATCH, because PATCH cannot check the resulting DynamoDB item size.

LSI updates, unsupported expressions and requests that need the old item when a condition fails take a third path: the adapter reads the item, then writes it only if its ETag is unchanged. Writes to a table with a stream use this path too, so the item and its stream record are saved together. A conflict with a concurrent write is retryable; it is not reported as a failed condition.

The Yahoo! Cloud Serving Benchmark (YCSB) workload F measures read-modify-write from the application side: a GetItem followed by an UpdateItem. Its full latency covers both calls and is not the same as the update step alone, and the sequence is not a multi-item transaction. In the recorded 2026-09-09 provisioned run with 16 workers, the full read-modify-write median (p50) was 21.071 ms and the update step's median was 15.935 ms, each the median of three completed repetitions. These are two parts of the same workload, not two competing implementations.

![Three ways an item is written: eligible removals use a conditional Cosmos PATCH; ordinary writes use a stored procedure that runs atomically; other requests read the item, then write it only if it has not changed.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjIwIiB2aWV3Qm94PSIwIDAgODM2IDIyMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaHJlZSB3YXlzIGFuIGl0ZW0gaXMgd3JpdHRlbjogZWxpZ2libGUgcmVtb3ZhbHMgdXNlIGEgY29uZGl0aW9uYWwgQ29zbW9zIFBBVENIOyBvcmRpbmFyeSB3cml0ZXMgdXNlIGEgc3RvcmVkIHByb2NlZHVyZSB0aGF0IHJ1bnMgYXRvbWljYWxseTsgb3RoZXIgcmVxdWVzdHMgcmVhZCB0aGUgaXRlbSwgdGhlbiB3cml0ZSBpdCBvbmx5IGlmIGl0IGhhcyBub3QgY2hhbmdlZC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPHJlY3QgeD0iMTAiIHk9IjIwIiB3aWR0aD0iMjU4IiBoZWlnaHQ9IjE3NSIgcng9IjEyIiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjI4IiB5PSI1MSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmEiPkVsaWdpYmxlIHJlbW92YWxzPC90ZXh0Pjx0ZXh0IHg9IjI4IiB5PSI4MyIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTUiPmNvbmRpdGlvbmFsIFBBVENIPC90ZXh0Pjx0ZXh0IHg9IjI4IiB5PSIxMTciIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5jb25kaXRpb24gcmVxdWlyZXMgaXRlbS9wYXRoPC90ZXh0Pjx0ZXh0IHg9IjI4IiB5PSIxNDEiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5ubyBzaXplIGdyb3d0aCwgVFRMIG9yIHN0cmVhbTwvdGV4dD48dGV4dCB4PSIyOCIgeT0iMTY1IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b2xkIGl0ZW0gbm90IHJlcXVlc3RlZDwvdGV4dD4KPHJlY3QgeD0iMjg5IiB5PSIyMCIgd2lkdGg9IjI1OCIgaGVpZ2h0PSIxNzUiIHJ4PSIxMiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzMDciIHk9IjUxIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYSI+T3JkaW5hcnkgd3JpdGVzLCBubyBzdHJlYW08L3RleHQ+PHRleHQgeD0iMzA3IiB5PSI4MyIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTUiPmF0b21pYyBzdG9yZWQgcHJvY2VkdXJlPC90ZXh0Pjx0ZXh0IHg9IjMwNyIgeT0iMTE3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cmVhZCDihpIgY2hlY2sg4oaSIGNoYW5nZTwvdGV4dD48dGV4dCB4PSIzMDciIHk9IjE0MSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnJlc3VsdCBjaGVja2VkIOKJpCA0MDAgS2lCPC90ZXh0Pjx0ZXh0IHg9IjMwNyIgeT0iMTY1IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+YWxsIHdpdGhpbiBvbmUgcGFydGl0aW9uPC90ZXh0Pgo8cmVjdCB4PSI1NjgiIHk9IjIwIiB3aWR0aD0iMjU4IiBoZWlnaHQ9IjE3NSIgcng9IjEyIiBzdHlsZT0iZmlsbDojZmZmYmViO3N0cm9rZTojZjU5ZTBiIi8+Cjx0ZXh0IHg9IjU4NiIgeT0iNTEiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhIj5PdGhlciByZXF1ZXN0czwvdGV4dD48dGV4dCB4PSI1ODYiIHk9IjgzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NSI+cmVhZCwgdGhlbiBndWFyZGVkIHdyaXRlPC90ZXh0Pjx0ZXh0IHg9IjU4NiIgeT0iMTE3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+TFNJIHVwZGF0ZXMsIGNvbXBsZXggZXhwcmVzc2lvbnM8L3RleHQ+PHRleHQgeD0iNTg2IiB5PSIxNDEiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vbGQgaXRlbSBvbiBmYWlsZWQgY29uZGl0aW9uPC90ZXh0Pjx0ZXh0IHg9IjU4NiIgeT0iMTY1IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+c3RyZWFtczogaXRlbSArIHJlY29yZCB0b2dldGhlcjwvdGV4dD4KPC9zdmc+)

![Three ways an item is written: eligible removals use a conditional Cosmos PATCH; ordinary writes use a stored procedure that runs atomically; other requests read the item, then write it only if it has not changed.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjIwIiB2aWV3Qm94PSIwIDAgODM2IDIyMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaHJlZSB3YXlzIGFuIGl0ZW0gaXMgd3JpdHRlbjogZWxpZ2libGUgcmVtb3ZhbHMgdXNlIGEgY29uZGl0aW9uYWwgQ29zbW9zIFBBVENIOyBvcmRpbmFyeSB3cml0ZXMgdXNlIGEgc3RvcmVkIHByb2NlZHVyZSB0aGF0IHJ1bnMgYXRvbWljYWxseTsgb3RoZXIgcmVxdWVzdHMgcmVhZCB0aGUgaXRlbSwgdGhlbiB3cml0ZSBpdCBvbmx5IGlmIGl0IGhhcyBub3QgY2hhbmdlZC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPHJlY3QgeD0iMTAiIHk9IjIwIiB3aWR0aD0iMjU4IiBoZWlnaHQ9IjE3NSIgcng9IjEyIiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjI4IiB5PSI1MSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1ZjkiPkVsaWdpYmxlIHJlbW92YWxzPC90ZXh0Pjx0ZXh0IHg9IjI4IiB5PSI4MyIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTEiPmNvbmRpdGlvbmFsIFBBVENIPC90ZXh0Pjx0ZXh0IHg9IjI4IiB5PSIxMTciIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5jb25kaXRpb24gcmVxdWlyZXMgaXRlbS9wYXRoPC90ZXh0Pjx0ZXh0IHg9IjI4IiB5PSIxNDEiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5ubyBzaXplIGdyb3d0aCwgVFRMIG9yIHN0cmVhbTwvdGV4dD48dGV4dCB4PSIyOCIgeT0iMTY1IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b2xkIGl0ZW0gbm90IHJlcXVlc3RlZDwvdGV4dD4KPHJlY3QgeD0iMjg5IiB5PSIyMCIgd2lkdGg9IjI1OCIgaGVpZ2h0PSIxNzUiIHJ4PSIxMiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzMDciIHk9IjUxIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOSI+T3JkaW5hcnkgd3JpdGVzLCBubyBzdHJlYW08L3RleHQ+PHRleHQgeD0iMzA3IiB5PSI4MyIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTEiPmF0b21pYyBzdG9yZWQgcHJvY2VkdXJlPC90ZXh0Pjx0ZXh0IHg9IjMwNyIgeT0iMTE3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cmVhZCDihpIgY2hlY2sg4oaSIGNoYW5nZTwvdGV4dD48dGV4dCB4PSIzMDciIHk9IjE0MSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnJlc3VsdCBjaGVja2VkIOKJpCA0MDAgS2lCPC90ZXh0Pjx0ZXh0IHg9IjMwNyIgeT0iMTY1IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+YWxsIHdpdGhpbiBvbmUgcGFydGl0aW9uPC90ZXh0Pgo8cmVjdCB4PSI1NjgiIHk9IjIwIiB3aWR0aD0iMjU4IiBoZWlnaHQ9IjE3NSIgcng9IjEyIiBzdHlsZT0iZmlsbDojNDIyMDA2O3N0cm9rZTojZmJiZjI0Ii8+Cjx0ZXh0IHg9IjU4NiIgeT0iNTEiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5Ij5PdGhlciByZXF1ZXN0czwvdGV4dD48dGV4dCB4PSI1ODYiIHk9IjgzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMSI+cmVhZCwgdGhlbiBndWFyZGVkIHdyaXRlPC90ZXh0Pjx0ZXh0IHg9IjU4NiIgeT0iMTE3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+TFNJIHVwZGF0ZXMsIGNvbXBsZXggZXhwcmVzc2lvbnM8L3RleHQ+PHRleHQgeD0iNTg2IiB5PSIxNDEiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vbGQgaXRlbSBvbiBmYWlsZWQgY29uZGl0aW9uPC90ZXh0Pjx0ZXh0IHg9IjU4NiIgeT0iMTY1IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+c3RyZWFtczogaXRlbSArIHJlY29yZCB0b2dldGhlcjwvdGV4dD4KPC9zdmc+)

#### Secondary indexes

A local secondary index lives in its table's container and uses the same partition, so a read from it reflects a completed write immediately. Its entry size also counts toward DynamoDB's item-size check.

On the provisioned backend, Azure keeps a separate container for each declared global secondary index and updates it asynchronously. A query on the index reads that container, with its key condition, sort order and paging applied there. GSI reads are eventually consistent, and `ConsistentRead=true` on a GSI is rejected, as on DynamoDB.

Serverless tables cannot declare these global secondary indexes. Index definitions must match the provisioned configuration; the adapter never builds a substitute index at runtime.

![A local secondary index lives in the table's container, so writes show up in it immediately. On provisioned accounts, Azure updates a separate container for each global secondary index asynchronously.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcwIiB2aWV3Qm94PSIwIDAgODM2IDE3MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGxvY2FsIHNlY29uZGFyeSBpbmRleCBsaXZlcyBpbiB0aGUgdGFibGUncyBjb250YWluZXIsIHNvIHdyaXRlcyBzaG93IHVwIGluIGl0IGltbWVkaWF0ZWx5LiBPbiBwcm92aXNpb25lZCBhY2NvdW50cywgQXp1cmUgdXBkYXRlcyBhIHNlcGFyYXRlIGNvbnRhaW5lciBmb3IgZWFjaCBnbG9iYWwgc2Vjb25kYXJ5IGluZGV4IGFzeW5jaHJvbm91c2x5LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8cmVjdCB4PSIyMCIgeT0iMzAiIHdpZHRoPSIzMTAiIGhlaWdodD0iMTEyIiByeD0iMTIiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MiIgeT0iNjQiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhIj5UYWJsZSBjb250YWluZXI8L3RleHQ+PHRleHQgeD0iNDIiIHk9IjkyIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+YmFzZSBpdGVtcyArIGxvY2FsIHNlY29uZGFyeSBpbmRleGVzPC90ZXh0Pjx0ZXh0IHg9IjQyIiB5PSIxMTkiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c3Ryb25nIHJlYWRzLCBpbW1lZGlhdGUgTFNJIHZpc2liaWxpdHk8L3RleHQ+CjxwYXRoIGQ9Ik0zNDAgODQgSDQ5NCBsLTEwIC03IE00OTQgODQgbC0xMCA3IiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPjx0ZXh0IHg9IjQxNyIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5BenVyZSBjb3BpZXMgY2hhbmdlczwvdGV4dD48dGV4dCB4PSI0MTciIHk9IjExMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmFzeW5jaHJvbm91c2x5PC90ZXh0Pgo8cmVjdCB4PSI1MDYiIHk9IjMwIiB3aWR0aD0iMzEwIiBoZWlnaHQ9IjExMiIgcng9IjEyIiBzdHlsZT0iZmlsbDojZWVmMmZmO3N0cm9rZTojNGY0NmU1Ii8+PHRleHQgeD0iNTI4IiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmEiPkdTSSBjb250YWluZXI8L3RleHQ+PHRleHQgeD0iNTI4IiB5PSI5MiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm9uZSBwZXIgZGVjbGFyZWQgR1NJPC90ZXh0Pjx0ZXh0IHg9IjUyOCIgeT0iMTE5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cHJvdmlzaW9uZWQgb25seTsgZXZlbnR1YWxseSBjb25zaXN0ZW50PC90ZXh0Pjwvc3ZnPg==)

![A local secondary index lives in the table's container, so writes show up in it immediately. On provisioned accounts, Azure updates a separate container for each global secondary index asynchronously.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTcwIiB2aWV3Qm94PSIwIDAgODM2IDE3MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGxvY2FsIHNlY29uZGFyeSBpbmRleCBsaXZlcyBpbiB0aGUgdGFibGUncyBjb250YWluZXIsIHNvIHdyaXRlcyBzaG93IHVwIGluIGl0IGltbWVkaWF0ZWx5LiBPbiBwcm92aXNpb25lZCBhY2NvdW50cywgQXp1cmUgdXBkYXRlcyBhIHNlcGFyYXRlIGNvbnRhaW5lciBmb3IgZWFjaCBnbG9iYWwgc2Vjb25kYXJ5IGluZGV4IGFzeW5jaHJvbm91c2x5LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8cmVjdCB4PSIyMCIgeT0iMzAiIHdpZHRoPSIzMTAiIGhlaWdodD0iMTEyIiByeD0iMTIiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MiIgeT0iNjQiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5Ij5UYWJsZSBjb250YWluZXI8L3RleHQ+PHRleHQgeD0iNDIiIHk9IjkyIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+YmFzZSBpdGVtcyArIGxvY2FsIHNlY29uZGFyeSBpbmRleGVzPC90ZXh0Pjx0ZXh0IHg9IjQyIiB5PSIxMTkiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c3Ryb25nIHJlYWRzLCBpbW1lZGlhdGUgTFNJIHZpc2liaWxpdHk8L3RleHQ+CjxwYXRoIGQ9Ik0zNDAgODQgSDQ5NCBsLTEwIC03IE00OTQgODQgbC0xMCA3IiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPjx0ZXh0IHg9IjQxNyIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5BenVyZSBjb3BpZXMgY2hhbmdlczwvdGV4dD48dGV4dCB4PSI0MTciIHk9IjExMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmFzeW5jaHJvbm91c2x5PC90ZXh0Pgo8cmVjdCB4PSI1MDYiIHk9IjMwIiB3aWR0aD0iMzEwIiBoZWlnaHQ9IjExMiIgcng9IjEyIiBzdHlsZT0iZmlsbDojMWUxYjRiO3N0cm9rZTojYTViNGZjIi8+PHRleHQgeD0iNTI4IiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1ZjkiPkdTSSBjb250YWluZXI8L3RleHQ+PHRleHQgeD0iNTI4IiB5PSI5MiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm9uZSBwZXIgZGVjbGFyZWQgR1NJPC90ZXh0Pjx0ZXh0IHg9IjUyOCIgeT0iMTE5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cHJvdmlzaW9uZWQgb25seTsgZXZlbnR1YWxseSBjb25zaXN0ZW50PC90ZXh0Pjwvc3ZnPg==)

#### Transactions

**The Cosmos adapter rejects DynamoDB multi-item transactions.** This includes `TransactWriteItems`, `TransactGetItems` and transactional PartiQL (`ExecuteTransaction`), even when every item shares one partition key.

Cosmos still makes each single-item write atomic, and saves an item together with its stream record, using stored procedures and batches within one partition. These do not provide the DynamoDB transaction APIs.

If your application needs DynamoDB multi-item transactions, choose another listed backend that supports them.

#### Limitations

Where DynamoDB and Cosmos DB differ

* **Numbers behave differently: at most 15 significant digits.** Values must also fit Cosmos's native number range, where DynamoDB allows 38 digits. A value outside that range is rejected.
* **LSI updates behave differently: they take the read-then-write path.** The adapter still enforces DynamoDB's 400 KiB item limit. Ordinary SET updates are checked in the stored procedure; LSI updates read the item first so the index entry size is counted too.
* **Multi-item transactions are not supported.** The adapter rejects every DynamoDB multi-item transaction API, including requests confined to one partition key.
* **Reads behave differently: they are always strongly consistent.** The account uses Strong consistency whatever the request's `ConsistentRead` flag says. Plan capacity for strongly consistent reads.
* **Paging behaves differently.** Query and Scan return Cosmos-sized result pages. `Limit` and `ScannedCount` do not exactly match DynamoDB's count of items examined before filtering, and some filter conditions are checked in the adapter.
* **Global secondary indexes behave differently: provisioned backend only.** They are eventually consistent; local secondary indexes share the table's container. Declared index definitions must match the deployment.
* **Streams behave differently: one writing instance per table.** Stream records are saved with the item, but a stream-enabled table accepts writes from one adapter instance at a time to keep records in order. Writes from another instance can be rejected until the writer lease is free.
* **Hot keys behave differently.** Capacity depends on how keys spread and on the account's throughput mode. Requests to one hot item can contend with each other even when overall capacity remains.
* **DeleteTable behaves differently: other instances see it after about five seconds.** Adapter instances cache table definitions, so others can take about five seconds to see the deletion. Cleanup of the stored items finishes within a bounded time.

#### Other considerations

* **Moving from AWS.** The Cosmos containers start empty. Move existing DynamoDB data with an export and import, a backfill or a dual-write cutover before you switch traffic.
* **Deployment and access.** Tensor9 provisions one account with the chosen throughput mode, a shared database and a container for each declared table. Access uses managed identities; no account keys are needed.
* **Capacity.** Provisioned containers each have their own autoscale RU range. Serverless containers reserve no throughput and bill for the requests they use. The 2026-09-09 adapter measurements used separate Standard\_D8s\_v5 driver and adapter VMs in westus2, Strong consistency and gateway-mode connections; the provisioned container autoscaled up to 40,000 RU/s. YCSB used 100,000 verified records of ten 100-byte fields and 200,000 operations per repetition. Each mode has its own results, and medians summarize three completed repetitions. There is no matching native DynamoDB baseline for this setup, so these results do not show a performance advantage over DynamoDB.
* **Runtime-created tables.** They live inside an already deployed container, kept apart by name, and share its capacity. Declared tables have their own containers.
* **What to monitor.** Microsoft operates Cosmos storage; Tensor9 operates the adapter. Watch request units, throttling, write conflicts and latency, along with resource use on the adapter and application hosts.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/193dccbec2796b6e5b1171fc4a7111fefeabb172227aef8c11ca6d5c32ad8196-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/8cc3648d8e340bbe4e76584c2e56cc26eb1ed0795f0657b10359947799ae7de5-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Azure Cosmos DB (provisioned) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 23.36 | 23.36 |
| 1 | 0.33 | 23.36 | 23.03 |
| 10 | 3.29 | 23.36 | 20.08 |
| 100 | 32.85 | 23.36 | -9.49 |
| 1,000 | 328.50 | 116.80 | -211.70 |
| 10,000 | 3,285.00 | 1,168.00 | -2,117.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.008 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 23.36 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Provisioned Cosmos DB bills reserved throughput in 100 RU/s blocks per hour, not consumed operations: planning-peak reads at 1 RU and writes at about 5.5 RU each are summed and rounded up to whole 100 RU/s blocks, with the documented 400 RU/s manual minimum ([https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput](https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput)). The blocks are a hard throughput limit, so they are planned at full utilization of the planning peak. Autoscale (USD 0.012 per 100 RU/s-hour, 100-1,000 RU/s entry) and the free tier (1,000 RU/s and 25 GB on one account) are not selected. Each additional region bills its own RU/s and storage.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-fa502df1b7bcaf6b86688cf2258a7216e475f489` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/246f19192dd7bc78a94f9f0df86544666da950f42b74e6a9ea2679108a556580-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/c6b19771b87a678f0ea1ea5181bcea37c8319c87c472ee7006b0c6526b66aacc-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Azure Cosmos DB (provisioned) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 23.36 | 23.36 |
| 1 | 1.64 | 23.36 | 21.72 |
| 10 | 16.43 | 23.36 | 6.94 |
| 100 | 164.25 | 70.08 | -94.17 |
| 1,000 | 1,642.50 | 648.24 | -994.26 |
| 10,000 | 16,425.00 | 6,429.84 | -9,995.16 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.008 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 23.36 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Provisioned Cosmos DB bills reserved throughput in 100 RU/s blocks per hour, not consumed operations: planning-peak reads at 1 RU and writes at about 5.5 RU each are summed and rounded up to whole 100 RU/s blocks, with the documented 400 RU/s manual minimum ([https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput](https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput)). The blocks are a hard throughput limit, so they are planned at full utilization of the planning peak. Autoscale (USD 0.012 per 100 RU/s-hour, 100-1,000 RU/s entry) and the free tier (1,000 RU/s and 25 GB on one account) are not selected. Each additional region bills its own RU/s and storage.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-fa502df1b7bcaf6b86688cf2258a7216e475f489` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/8fc506740d01cb1e3d31a20b358a55b374a8029899df42f92417a18e0b8830bf-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/ced7d83588c442c589c3870b5a69544f2a2009dbd22027b25d754e0abcf83f01-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Azure Cosmos DB (provisioned) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 23.36 | 23.36 |
| 10 | 2.50 | 25.86 | 23.36 |
| 100 | 25.00 | 48.36 | 23.36 |
| 1,000 | 250.00 | 273.36 | 23.36 |
| 10,000 | 2,500.00 | 2,523.36 | 23.36 |
| 100,000 | 25,000.00 | 25,023.36 | 23.36 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.008 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 23.36 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Provisioned Cosmos DB bills reserved throughput in 100 RU/s blocks per hour, not consumed operations: planning-peak reads at 1 RU and writes at about 5.5 RU each are summed and rounded up to whole 100 RU/s blocks, with the documented 400 RU/s manual minimum ([https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput](https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput)). The blocks are a hard throughput limit, so they are planned at full utilization of the planning peak. Autoscale (USD 0.012 per 100 RU/s-hour, 100-1,000 RU/s entry) and the free tier (1,000 RU/s and 25 GB on one account) are not selected. Each additional region bills its own RU/s and storage.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-fa502df1b7bcaf6b86688cf2258a7216e475f489` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

**DynamoDB → Azure Cosmos DB (provisioned): Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: eastus. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Target read operations | 0.00 |
| Target: Target write operations | 0.00 |
| Target: Target retained physical data | 0.00 |
| Target: Additional broker replica storage | 0.00 |
| Target: Execution or worker CPU | 0.00 |
| Target: Execution or worker RAM | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent native resources | 0.00 |
| Target: 100 RU/s blocks at planning peak | 23.36 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **23.36** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.008 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 23.36 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Provisioned Cosmos DB bills reserved throughput in 100 RU/s blocks per hour, not consumed operations: planning-peak reads at 1 RU and writes at about 5.5 RU each are summed and rounded up to whole 100 RU/s blocks, with the documented 400 RU/s manual minimum ([https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput](https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput)). The blocks are a hard throughput limit, so they are planned at full utilization of the planning peak. Autoscale (USD 0.012 per 100 RU/s-hour, 100-1,000 RU/s entry) and the free tier (1,000 RU/s and 25 GB on one account) are not selected. Each additional region bills its own RU/s and storage.

List prices read: 2026-10-22. Model: `plan-fa502df1b7bcaf6b86688cf2258a7216e475f489` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

### Azure Cosmos DB (serverless)

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| DescribeContinuousBackups | Backups | Partial | Full surface | PITR status mapped from the Cosmos continuous-backup mode |
| On-demand backups (CreateBackup / RestoreTableFromBackup / …) | Backups | Out of scope | Full surface | the snapshot-backup model differs from Cosmos; Use the backend's backup and restore workflow. |
| UpdateContinuousBackups | Backups | Partial | Full surface | toggles PITR onto Cosmos continuous backup (the retention window differs) |
| ConditionExpression | Conditional writes | Supported | Common | condition and mutation execute atomically in a stored procedure, eligible PATCH or etag-guarded fallback; write conflicts are retryable |
| Global tables (CreateGlobalTable / UpdateGlobalTable / …) | Global | Out of scope | Full surface | DynamoDB global-table control APIs are outside this mapping; configure the deployment in the target environment and its region separately. |
| DescribeStream | Indexes + streams | Supported | Full surface | returns the shard list and stream ARN |
| GetRecords | Indexes + streams | Supported | Full surface | records co-commit atomically with the write; all four view types; 24-hour retention with TrimmedDataAccessException below the horizon; one writing instance per streamed table |
| GetShardIterator | Indexes + streams | Supported | Full surface | - |
| ListStreams | Indexes + streams | Supported | Full surface | the streamed-table registry |
| Query (GSI) | Indexes + streams | Out of scope | Most usage | a global secondary index needs autoscale throughput to maintain its index container, which a consumption account does not offer; a table declaring one stops the build and names the provisioned backend rather than deploying without the index. Local secondary indexes are unaffected |
| Query (LSI) | Indexes + streams | Supported | Most usage | a local secondary index shares the table's own container and partition route, so an LSI query reflects a write immediately; large index partitions are subject to a per-query candidate limit |
| S3 import/export + Kinesis streaming + ContributorInsights + ResourcePolicy | Out of scope | Out of scope | Full surface | These AWS integrations are outside the listed mapping. |
| BatchExecuteStatement | PartiQL | Partial | Most usage | batched PartiQL statements, each statement gets its own real outcome |
| ExecuteStatement | PartiQL | Partial | Most usage | PartiQL select/insert/update/delete compiled to the native Cosmos query / item path; some PartiQL functions differ |
| ExecuteTransaction | PartiQL | Out of scope | Most usage | transactional PartiQL is unavailable on the current Cosmos adapter |
| BatchGetItem | Reads | Supported | Most usage | the adapter executes each item operation and reports its result |
| BatchWriteItem | Reads | Supported | Most usage | the adapter executes each item operation and reports its result |
| Query | Reads | Partial | Common | native key/range/order/filter pushdown plus residual evaluation; pagination follows Cosmos result windows |
| Scan | Reads | Partial | Most usage | bounded native result windows; Limit and ScannedCount differ from DynamoDB pre-filter examined-item accounting |
| DeleteItem | Single item | Supported | Common | - |
| GetItem | Single item | Supported | Common | strongly consistent from any instance, whatever the ConsistentRead flag (never weaker than asked) |
| PutItem | Single item | Supported | Common | DynamoDB type tags preserved; native Cosmos numbers require at most 15 significant digits and representable range |
| UpdateItem | Single item | Supported | Common | eligible removals use native conditional PATCH; ordinary updates run in a partition-scoped stored procedure; other shapes use guarded read-modify-write |
| DescribeTimeToLive | TTL | Supported | Most usage | reads the container's TTL policy |
| UpdateTimeToLive | TTL | Supported | Most usage | the DynamoDB per-item TTL attribute is mapped to the Cosmos TTL policy |
| CreateTable | Table control plane | Supported | Most usage | registers a logical table in a deployed container; declared tables receive containers at compile time |
| DeleteTable | Table control plane | Supported | Most usage | logical generation change with bounded cleanup and metadata propagation |
| DescribeEndpoints | Table control plane | Supported | Full surface | returns the adapter endpoint |
| DescribeLimits | Table control plane | Supported | Full surface | account / table limits reported from the compiled config |
| DescribeTable | Table control plane | Supported | Most usage | returns the key schema and stream identifiers |
| ListTables | Table control plane | Supported | Most usage | - |
| UpdateTable | Table control plane | Supported | Most usage | index and stream definitions must match deployed configuration; throughput mode is selected at compile time |
| ListTagsOfResource | Tags | Supported | Full surface | - |
| TagResource | Tags | Supported | Full surface | - |
| UntagResource | Tags | Supported | Full surface | - |
| TransactGetItems | Transactions | Out of scope | Most usage | the current Cosmos adapter rejects DynamoDB transactional reads |
| TransactWriteItems | Transactions | Out of scope | Most usage | the current Cosmos adapter rejects DynamoDB multi-item transactions |

#### Requests and database state

Your DynamoDB client sends requests to the Rust adapter in the target environment. The adapter parses DynamoDB expressions, performs Cosmos operations and returns DynamoDB responses. Cosmos stores items, table definitions and stream records. The adapter uses workload identity to access that data; restarting an adapter instance does not require restoring local item state.

#### Choosing serverless capacity

Tensor9 provisions a serverless Cosmos account and one ddb database for the deployment. Charges follow consumed request units and stored data, without a dedicated autoscale range. The selected account mode applies to its containers; a source table's provisioned capacity does not reserve Cosmos request units. Test the workload's bursts, retries and partition distribution against the serverless limits.

#### Declared and runtime-created tables

Each declared table gets a container. A table created through the runtime CreateTable API instead uses the first deployed container: the adapter records its schema and separates its items with a table-prefixed partition key. The data identity cannot provision a new Cosmos container. DescribeTable and ListTables read the durable registry; DeleteTable invalidates the table generation and performs bounded cleanup. Runtime-created tables therefore share container capacity.

#### Items, reads and conditional writes

DynamoDB attribute type tags are retained, but numbers must fit the native Cosmos representation: at most 15 significant digits and a representable range. Unsupported numbers are rejected. The adapter enforces a 400 KiB item limit and uses strong reads regardless of ConsistentRead. Ordinary writes use a Cosmos stored procedure; eligible conditional removals use PATCH, and other request shapes use guarded read-modify-write. Query and Scan use Cosmos result windows, so Limit and ScannedCount differ from DynamoDB's examined-item accounting.

#### Indexes, transactions and streams

Local secondary indexes share the table's container and reflect a write immediately. A global secondary index requires the provisioned backend because the separate Azure-maintained index container needs autoscale throughput; declaring one on serverless stops the build. DynamoDB multi-item transaction APIs are rejected. Streams commit each change record with the item and require one writing instance per streamed table. All four view types and 24-hour retention are available; an older position returns TrimmedDataAccessException.

#### Expiry, migration and operation

The adapter converts the configured absolute TTL epoch into Cosmos's relative expiry value. Cosmos removes expired documents asynchronously. Deploy the destination, load existing items and validate the application's queries and stream consumers before switching traffic. Changing between provisioned and serverless accounts requires a new destination and data migration. Microsoft operates Cosmos, while Tensor9 operates the adapter; configure account access, backups and monitoring for the target environment.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/4771757d971e3824401e9b7583642844fc6318107e3589725df9928cca48993a-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/bd6716370e8b2e94e5c955d6b09b9e3a7954c2dd78eced8e3cc17e92b4b50173-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Azure Cosmos DB (serverless) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 0.33 | 0.66 | 0.33 |
| 10 | 3.29 | 6.57 | 3.29 |
| 100 | 32.85 | 65.70 | 32.85 |
| 1,000 | 328.50 | 657.00 | 328.50 |
| 10,000 | 3,285.00 | 6,570.00 | 3,285.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.00000025 | USD/read |
| Target list price · write | 0.000001375 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Cosmos DB serverless bills consumed Request Units (USD 0.25 per million) and stored GB. Per-operation rates assume Microsoft's published 1 KB costs: a point read is 1 RU and an unindexed insert about 5.5 RU ([https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes](https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes)). Larger items, default indexing of every property, replaces (2x an insert) and strong or bounded-staleness reads (2x) cost more RU than these rates assume.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-26501e747dcdbd0b7586f4ab58235e0ced69b13c` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/c8207c089627fc4683370a73685e038ae3ae76a56b3f8b6000746fada5469ebd-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/368a2449ad33f0b70ee82375401b8f8daf5e214d4d54f30d5cf97aad688848d2-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Azure Cosmos DB (serverless) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 1.64 | 3.61 | 1.97 |
| 10 | 16.43 | 36.14 | 19.71 |
| 100 | 164.25 | 361.35 | 197.10 |
| 1,000 | 1,642.50 | 3,613.50 | 1,971.00 |
| 10,000 | 16,425.00 | 36,135.00 | 19,710.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.00000025 | USD/read |
| Target list price · write | 0.000001375 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Cosmos DB serverless bills consumed Request Units (USD 0.25 per million) and stored GB. Per-operation rates assume Microsoft's published 1 KB costs: a point read is 1 RU and an unindexed insert about 5.5 RU ([https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes](https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes)). Larger items, default indexing of every property, replaces (2x an insert) and strong or bounded-staleness reads (2x) cost more RU than these rates assume.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-26501e747dcdbd0b7586f4ab58235e0ced69b13c` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/b5db18ebd2d54c999de35f1b739ab68377aca6dbf19f5946ea6653b0a18afc48-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/7d9f1b7ae0b26fe135d08c8d080e58ca7d472f4f7c5a6270b93261f96394c22e-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Azure Cosmos DB (serverless) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 10 | 2.50 | 2.50 | 0.00 |
| 100 | 25.00 | 25.00 | 0.00 |
| 1,000 | 250.00 | 250.00 | 0.00 |
| 10,000 | 2,500.00 | 2,500.00 | 0.00 |
| 100,000 | 25,000.00 | 25,000.00 | 0.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.00000025 | USD/read |
| Target list price · write | 0.000001375 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Cosmos DB serverless bills consumed Request Units (USD 0.25 per million) and stored GB. Per-operation rates assume Microsoft's published 1 KB costs: a point read is 1 RU and an unindexed insert about 5.5 RU ([https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes](https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes)). Larger items, default indexing of every property, replaces (2x an insert) and strong or bounded-staleness reads (2x) cost more RU than these rates assume.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-26501e747dcdbd0b7586f4ab58235e0ced69b13c` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

**DynamoDB → Azure Cosmos DB (serverless): Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: eastus. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Target read operations | 0.00 |
| Target: Target write operations | 0.00 |
| Target: Target retained physical data | 0.00 |
| Target: Additional broker replica storage | 0.00 |
| Target: Execution or worker CPU | 0.00 |
| Target: Execution or worker RAM | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent native resources | 0.00 |
| Target: Independent native resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **0.00** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.00000025 | USD/read |
| Target list price · write | 0.000001375 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Cosmos DB serverless bills consumed Request Units (USD 0.25 per million) and stored GB. Per-operation rates assume Microsoft's published 1 KB costs: a point read is 1 RU and an unindexed insert about 5.5 RU ([https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes](https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes)). Larger items, default indexing of every property, replaces (2x an insert) and strong or bounded-staleness reads (2x) cost more RU than these rates assume.

List prices read: 2026-10-22. Model: `plan-26501e747dcdbd0b7586f4ab58235e0ced69b13c` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

## On Google Cloud

### Firestore

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| ConditionExpression | Conditional writes | Supported | Common | evaluated against the live document under an optimistic precondition; a lost race retries, never a spurious condition failure |
| DescribeStream | Indexes + streams | Supported | Full surface | shard list + stream ARN |
| GetRecords | Indexes + streams | Supported | Full surface | DynamoDB Streams served from an ordered change log co-committed with each write; all four view types |
| GetShardIterator | Indexes + streams | Supported | Full surface | - |
| ListStreams | Indexes + streams | Supported | Full surface | the streamed-table registry |
| Query (GSI / LSI) | Indexes + streams | Supported | Most usage | served by a real maintained secondary index (a per-index seek), not a table scan |
| Query | Reads | Supported | Common | ordering, filters and pagination honored |
| Scan | Reads | Supported | Common | streamed page by page |
| DeleteItem | Single item | Supported | Common | - |
| GetItem | Single item | Supported | Common | - |
| PutItem | Single item | Supported | Common | Documents are keyed by partition and sort key. Signed 64-bit integers remain exact; other numbers must fit the supported 15-significant-digit native range. |
| UpdateItem | Single item | Supported | Common | default: eligible REMOVE-only requests use a masked write; SET reads the item to enforce 400 KiB. FIRESTORE\_ALLOW\_OVERSIZED\_BLIND\_UPDATES=true permits eligible blind SET/REMOVE while relaxing that size check; conditions, returned attributes and complex updates retain read-modify-write |
| TransactWriteItems | Transactions | Supported | Most usage | a real cross-document Firestore transaction, atomic up to the 100-action limit DynamoDB itself imposes |

#### How it works

Your application keeps its AWS SDK and code. Tensor9 runs a DynamoDB adapter beside it in the customer's environment and sets `AWS_ENDPOINT_URL_DYNAMODB`, so the SDK sends its requests to the adapter over the local network. The adapter accepts DynamoDB requests and data types, returns DynamoDB responses and errors, and stores the data in Google Cloud Firestore.

Items, conditions, indexes and transactions map to Firestore documents and operations. Three differences matter most: numbers must fit Firestore's native number types, every read is strongly consistent, and writes that need the current item first add a read and can meet contention.

![Before: on AWS, the application's DynamoDB SDK calls Amazon DynamoDB. After: on Google Cloud, the same application and SDK call a Tensor9 adapter, which stores the data in Firestore.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUywgdGhlIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IG9uIEdvb2dsZSBDbG91ZCwgdGhlIHNhbWUgYXBwbGljYXRpb24gYW5kIFNESyBjYWxsIGEgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBzdG9yZXMgdGhlIGRhdGEgaW4gRmlyZXN0b3JlLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iZmExIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDYiIHdpZHRoPSIzNTgiIGhlaWdodD0iMTE4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMzAiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojNjQ3NDhiIj5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI4MCIgd2lkdGg9IjEyMCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI5MCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEyLjVweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjkwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5EeW5hbW9EQiBTREs8L3RleHQ+CjxsaW5lIHgxPSIxNTAiIHkxPSIxMTMiIHgyPSIyMTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNmYTEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iMTgxIiB5PSIxMDQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiOyBmb250LXNpemU6OC41cHgiPkR5bmFtb0RCPC90ZXh0Pgo8cmVjdCB4PSIyMTQiIHk9IjgwIiB3aWR0aD0iMTQ4IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjI4OCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjExLjVweCI+QW1hem9uIER5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiNjYmQ1ZTEiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZmExKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZmExKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI3NzQiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMXB4Ij5GaXJlc3RvcmU8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+TmF0aXZlPC90ZXh0Pgo8L3N2Zz4=)

![Before: on AWS, the application's DynamoDB SDK calls Amazon DynamoDB. After: on Google Cloud, the same application and SDK call a Tensor9 adapter, which stores the data in Firestore.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUywgdGhlIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IG9uIEdvb2dsZSBDbG91ZCwgdGhlIHNhbWUgYXBwbGljYXRpb24gYW5kIFNESyBjYWxsIGEgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBzdG9yZXMgdGhlIGRhdGEgaW4gRmlyZXN0b3JlLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iZmExIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDYiIHdpZHRoPSIzNTgiIGhlaWdodD0iMTE4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMzAiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojOTRhM2I4Ij5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI4MCIgd2lkdGg9IjEyMCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI5MCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEyLjVweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjkwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5EeW5hbW9EQiBTREs8L3RleHQ+CjxsaW5lIHgxPSIxNTAiIHkxPSIxMTMiIHgyPSIyMTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNmYTEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iMTgxIiB5PSIxMDQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4OyBmb250LXNpemU6OC41cHgiPkR5bmFtb0RCPC90ZXh0Pgo8cmVjdCB4PSIyMTQiIHk9IjgwIiB3aWR0aD0iMTQ4IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjI4OCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjExLjVweCI+QW1hem9uIER5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiM0NzU1NjkiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZmExKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZmExKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI3NzQiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMXB4Ij5GaXJlc3RvcmU8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+TmF0aXZlPC90ZXh0Pgo8L3N2Zz4=)

Your application keeps its DynamoDB SDK; an adapter in the target environment stores the data in Firestore.

#### Architecture

The adapter parses DynamoDB requests and expressions, runs the matching Firestore operations and returns DynamoDB responses. It authenticates to Firestore with the customer's workload identity, using short-lived tokens rather than a stored key. All item and table data lives in Firestore, so an adapter instance can restart without recovering anything locally. A table with DynamoDB Streams enabled still needs a single writing instance.

There is no Firestore collection or capacity to provision per table. Every DynamoDB table lives in one Firestore collection named `ddb`. Each item is a document whose ID combines the table name and the item's key (for example `orders|u#42`), with fields recording its table and partition. A registry document in the same collection holds the table definitions, so a table your application creates at run time needs no Firestore setup. Each declared secondary index is a Firestore composite index over the item's own fields.

![Your app's DynamoDB SDK calls the Tensor9 adapter, which keeps no data of its own. Firestore holds every table's items as documents in one collection named ddb, and Firestore composite indexes over the item fields serve the secondary indexes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJZb3VyIGFwcCdzIER5bmFtb0RCIFNESyBjYWxscyB0aGUgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBrZWVwcyBubyBkYXRhIG9mIGl0cyBvd24uIEZpcmVzdG9yZSBob2xkcyBldmVyeSB0YWJsZSdzIGl0ZW1zIGFzIGRvY3VtZW50cyBpbiBvbmUgY29sbGVjdGlvbiBuYW1lZCBkZGIsIGFuZCBGaXJlc3RvcmUgY29tcG9zaXRlIGluZGV4ZXMgb3ZlciB0aGUgaXRlbSBmaWVsZHMgc2VydmUgdGhlIHNlY29uZGFyeSBpbmRleGVzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iZmEyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIzNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDgiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyNiIgeT0iNTQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTEwIiB3aWR0aD0iMTE0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjgzIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTNweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjgzIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5EeW5hbW9EQiBTREs8L3RleHQ+Cjx0ZXh0IHg9IjgzIiB5PSIxODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTQwIiB5MT0iMTU2IiB4Mj0iMTkyIiB5Mj0iMTU2IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZmEyKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+Cjx0ZXh0IHg9IjE2NiIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZm9udC1zaXplOjguNXB4Ij5EeW5hbW9EQjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxMjIiIHdpZHRoPSIxNjgiIGhlaWdodD0iNjgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjgwIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTNweCI+YWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMjgwIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmtlZXBzIG5vIGRhdGE8L3RleHQ+CjxsaW5lIHgxPSIzNjQiIHkxPSIxNTYiIHgyPSI0MzYiIHkyPSIxNTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNmYTIpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iNDAwIiB5PSIxNDgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiOyBmb250LXNpemU6OC41cHgiPkZpcmVzdG9yZSBBUEk8L3RleHQ+Cjx0ZXh0IHg9IjQwMCIgeT0iMTcwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZm9udC1zaXplOjguNXB4Ij53b3JrbG9hZCBpZGVudGl0eTwvdGV4dD4KPHJlY3QgeD0iNDQwIiB5PSI3OCIgd2lkdGg9IjM3MiIgaGVpZ2h0PSIxNTYiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjI2IiB5PSI5OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPkdvb2dsZSBDbG91ZCBGaXJlc3RvcmUgwrcgTmF0aXZlPC90ZXh0Pgo8dGV4dCB4PSI2MjYiIHk9IjExMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6IzY0NzQ4YiI+b25lIGNvbGxlY3Rpb24gImRkYiIgwrcgZXZlcnkgdGFibGUgdG9nZXRoZXI8L3RleHQ+CjxyZWN0IHg9IjQ1NCIgeT0iMTIwIiB3aWR0aD0iMjMwIiBoZWlnaHQ9IjEwNCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI1NjkiIHk9IjEzNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj5jb2xsZWN0aW9uOiBkZGI8L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMDQ3ODU3Ij5rZXllZCBieSBkb2N1bWVudCBpZDwvdGV4dD4KPHJlY3QgeD0iNDY2IiB5PSIxNTMiIHdpZHRoPSIyMDYiIGhlaWdodD0iMjAiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjU2OSIgeT0iMTY3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMzM0MTU1Ij5vcmRlcnN8dSM0MiAg4oaSICBpdGVtPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE3NyIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iNTY5IiB5PSIxOTEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPm9yZGVyc3x1Izg4ICDihpIgIGl0ZW08L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+YSB0YWJsZSBmaWVsZCB0ZWxscyB0aGVtIGFwYXJ0PC90ZXh0Pgo8cmVjdCB4PSI2OTYiIHk9IjEyMCIgd2lkdGg9IjEwMiIgaGVpZ2h0PSIxMDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzQ3IiB5PSIxNTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiMzMzQxNTUiPmNvbXBvc2l0ZTwvdGV4dD4KPHRleHQgeD0iNzQ3IiB5PSIxNjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiMzMzQxNTUiPmluZGV4ZXM8L3RleHQ+Cjx0ZXh0IHg9Ijc0NyIgeT0iMTg3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+bmF0aXZlIGl0ZW08L3RleHQ+Cjx0ZXh0IHg9Ijc0NyIgeT0iMjAyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+ZmllbGQgcGF0aHM8L3RleHQ+Cjwvc3ZnPg==)

![Your app's DynamoDB SDK calls the Tensor9 adapter, which keeps no data of its own. Firestore holds every table's items as documents in one collection named ddb, and Firestore composite indexes over the item fields serve the secondary indexes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJZb3VyIGFwcCdzIER5bmFtb0RCIFNESyBjYWxscyB0aGUgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBrZWVwcyBubyBkYXRhIG9mIGl0cyBvd24uIEZpcmVzdG9yZSBob2xkcyBldmVyeSB0YWJsZSdzIGl0ZW1zIGFzIGRvY3VtZW50cyBpbiBvbmUgY29sbGVjdGlvbiBuYW1lZCBkZGIsIGFuZCBGaXJlc3RvcmUgY29tcG9zaXRlIGluZGV4ZXMgb3ZlciB0aGUgaXRlbSBmaWVsZHMgc2VydmUgdGhlIHNlY29uZGFyeSBpbmRleGVzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iZmEyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIzNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDgiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyNiIgeT0iNTQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTEwIiB3aWR0aD0iMTE0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjgzIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTNweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjgzIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5EeW5hbW9EQiBTREs8L3RleHQ+Cjx0ZXh0IHg9IjgzIiB5PSIxODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTQwIiB5MT0iMTU2IiB4Mj0iMTkyIiB5Mj0iMTU2IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZmEyKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+Cjx0ZXh0IHg9IjE2NiIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZm9udC1zaXplOjguNXB4Ij5EeW5hbW9EQjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxMjIiIHdpZHRoPSIxNjgiIGhlaWdodD0iNjgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjgwIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTNweCI+YWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMjgwIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmtlZXBzIG5vIGRhdGE8L3RleHQ+CjxsaW5lIHgxPSIzNjQiIHkxPSIxNTYiIHgyPSI0MzYiIHkyPSIxNTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNmYTIpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iNDAwIiB5PSIxNDgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4OyBmb250LXNpemU6OC41cHgiPkZpcmVzdG9yZSBBUEk8L3RleHQ+Cjx0ZXh0IHg9IjQwMCIgeT0iMTcwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZm9udC1zaXplOjguNXB4Ij53b3JrbG9hZCBpZGVudGl0eTwvdGV4dD4KPHJlY3QgeD0iNDQwIiB5PSI3OCIgd2lkdGg9IjM3MiIgaGVpZ2h0PSIxNTYiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjI2IiB5PSI5OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPkdvb2dsZSBDbG91ZCBGaXJlc3RvcmUgwrcgTmF0aXZlPC90ZXh0Pgo8dGV4dCB4PSI2MjYiIHk9IjExMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6Izk0YTNiOCI+b25lIGNvbGxlY3Rpb24gImRkYiIgwrcgZXZlcnkgdGFibGUgdG9nZXRoZXI8L3RleHQ+CjxyZWN0IHg9IjQ1NCIgeT0iMTIwIiB3aWR0aD0iMjMwIiBoZWlnaHQ9IjEwNCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI1NjkiIHk9IjEzNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj5jb2xsZWN0aW9uOiBkZGI8L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNmVlN2I3Ij5rZXllZCBieSBkb2N1bWVudCBpZDwvdGV4dD4KPHJlY3QgeD0iNDY2IiB5PSIxNTMiIHdpZHRoPSIyMDYiIGhlaWdodD0iMjAiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjU2OSIgeT0iMTY3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojY2JkNWUxIj5vcmRlcnN8dSM0MiAg4oaSICBpdGVtPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE3NyIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNTY5IiB5PSIxOTEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPm9yZGVyc3x1Izg4ICDihpIgIGl0ZW08L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+YSB0YWJsZSBmaWVsZCB0ZWxscyB0aGVtIGFwYXJ0PC90ZXh0Pgo8cmVjdCB4PSI2OTYiIHk9IjEyMCIgd2lkdGg9IjEwMiIgaGVpZ2h0PSIxMDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzQ3IiB5PSIxNTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiNjYmQ1ZTEiPmNvbXBvc2l0ZTwvdGV4dD4KPHRleHQgeD0iNzQ3IiB5PSIxNjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiNjYmQ1ZTEiPmluZGV4ZXM8L3RleHQ+Cjx0ZXh0IHg9Ijc0NyIgeT0iMTg3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+bmF0aXZlIGl0ZW08L3RleHQ+Cjx0ZXh0IHg9Ijc0NyIgeT0iMjAyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+ZmllbGQgcGF0aHM8L3RleHQ+Cjwvc3ZnPg==)

The adapter keeps no data; every table's items live as documents in one Firestore collection, ddb.

#### Item types and numbers

Each attribute is stored as a map with one DynamoDB type tag: strings as `{"S": …}`, numbers as `{"N": …}`, binary as `{"B": …}`, and sets, lists, maps, booleans and null with their own tags. The value inside is a native Firestore value, so a number stays distinct from a string that looks like a number, and Firestore can filter and index fields such as `item.total.N`.

Numbers have a limit. Signed 64-bit integers are stored exactly, as Firestore integers. Other numbers are accepted only if they fit within 15 significant digits, and are stored as doubles. A DynamoDB number outside that range is rejected before it is stored rather than rounded. Beside the `item` map, each document also holds fields the adapter manages: `id`, `_pk`, `_tbl`, `_okey` and `_keyAttrs`.

![A DynamoDB item is stored in a Firestore document. Each attribute keeps its DynamoDB type tag around a native Firestore value. Integers stay exact; other numbers are checked for precision before they are stored as doubles.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0gaXMgc3RvcmVkIGluIGEgRmlyZXN0b3JlIGRvY3VtZW50LiBFYWNoIGF0dHJpYnV0ZSBrZWVwcyBpdHMgRHluYW1vREIgdHlwZSB0YWcgYXJvdW5kIGEgbmF0aXZlIEZpcmVzdG9yZSB2YWx1ZS4gSW50ZWdlcnMgc3RheSBleGFjdDsgb3RoZXIgbnVtYmVycyBhcmUgY2hlY2tlZCBmb3IgcHJlY2lzaW9uIGJlZm9yZSB0aGV5IGFyZSBzdG9yZWQgYXMgZG91Ymxlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZmEzIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIzMCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+RFlOQU1PREIgSVRFTTwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjE4MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NCIgeT0iNzQiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiYjMTIzOzwvdGV4dD4KPHRleHQgeD0iNjAiIHk9Ijk4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4icGsiOiAgICAmIzEyMzsgIlMiOiAidXNlciM0MiIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTIyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4ic2siOiAgICAmIzEyMzsgIlMiOiAib3JkZXIjNyIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojYjQ1MzA5Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAiMTIzLjQ1IiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxNzAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiJ0YWdzIjogICYjMTIzOyAiU1MiOiBbInZpcCJdICYjMTI1OzwvdGV4dD4KPHRleHQgeD0iNDQiIHk9IjE5NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0NCIgeT0iMjE0IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojYjQ1MzA5Ij5OIGlzIGNoZWNrZWQgYmVmb3JlIGl0IGlzIHN0b3JlZDwvdGV4dD4KPGxpbmUgeDE9IjMzNCIgeTE9IjEzMiIgeDI9IjM4NiIgeTI9IjEzMiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2ZhMykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzNjAiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZTwvdGV4dD4KPHRleHQgeD0iMzk2IiB5PSIzMCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzA0Nzg1NyI+RklSRVNUT1JFIERPQ1VNRU5UPC90ZXh0Pgo8cmVjdCB4PSIzOTYiIHk9IjQyIiB3aWR0aD0iNDE0IiBoZWlnaHQ9IjE5OCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0MTQiIHk9IjY4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4mIzEyMzs8L3RleHQ+Cjx0ZXh0IHg9IjQzMCIgeT0iODQiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiJpZCI6ICAgICAgICAib3JkZXJzfHBrPVM6dXNlciM0Mnxzaz1TOm9yZGVyIzciLDwvdGV4dD4KPHRleHQgeD0iNDMwIiB5PSIxMDIiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPiJfcGsiOiAgICAgICAib3JkZXJzfFM6dXNlciM0MiIsPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjEyMCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+Il90YmwiOiAgICAgICJvcmRlcnMiLDwvdGV4dD4KPHRleHQgeD0iNDMwIiB5PSIxMzgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPiJfb2tleSI6ICAgICAi4oCmIiw8L3RleHQ+Cjx0ZXh0IHg9IjQzMCIgeT0iMTU2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij4iX2tleUF0dHJzIjogWyJwayIsInNrIl0sPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjE3NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+Iml0ZW0iOiAmIzEyMzs8L3RleHQ+Cjx0ZXh0IHg9IjQ0NiIgeT0iMTkyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojYjQ1MzA5Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAxMjMuNDUgJiMxMjU7LCAg4oCmPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjIxMCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0MTQiIHk9IjIyOCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+JiMxMjU7PC90ZXh0Pgo8L3N2Zz4=)

![A DynamoDB item is stored in a Firestore document. Each attribute keeps its DynamoDB type tag around a native Firestore value. Integers stay exact; other numbers are checked for precision before they are stored as doubles.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0gaXMgc3RvcmVkIGluIGEgRmlyZXN0b3JlIGRvY3VtZW50LiBFYWNoIGF0dHJpYnV0ZSBrZWVwcyBpdHMgRHluYW1vREIgdHlwZSB0YWcgYXJvdW5kIGEgbmF0aXZlIEZpcmVzdG9yZSB2YWx1ZS4gSW50ZWdlcnMgc3RheSBleGFjdDsgb3RoZXIgbnVtYmVycyBhcmUgY2hlY2tlZCBmb3IgcHJlY2lzaW9uIGJlZm9yZSB0aGV5IGFyZSBzdG9yZWQgYXMgZG91Ymxlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZmEzIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIzMCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+RFlOQU1PREIgSVRFTTwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjE4MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NCIgeT0iNzQiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiYjMTIzOzwvdGV4dD4KPHRleHQgeD0iNjAiIHk9Ijk4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4icGsiOiAgICAmIzEyMzsgIlMiOiAidXNlciM0MiIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTIyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4ic2siOiAgICAmIzEyMzsgIlMiOiAib3JkZXIjNyIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojZmJiZjI0Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAiMTIzLjQ1IiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxNzAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiJ0YWdzIjogICYjMTIzOyAiU1MiOiBbInZpcCJdICYjMTI1OzwvdGV4dD4KPHRleHQgeD0iNDQiIHk9IjE5NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0NCIgeT0iMjE0IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojZmJiZjI0Ij5OIGlzIGNoZWNrZWQgYmVmb3JlIGl0IGlzIHN0b3JlZDwvdGV4dD4KPGxpbmUgeDE9IjMzNCIgeTE9IjEzMiIgeDI9IjM4NiIgeTI9IjEzMiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2ZhMykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzNjAiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZTwvdGV4dD4KPHRleHQgeD0iMzk2IiB5PSIzMCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzZlZTdiNyI+RklSRVNUT1JFIERPQ1VNRU5UPC90ZXh0Pgo8cmVjdCB4PSIzOTYiIHk9IjQyIiB3aWR0aD0iNDE0IiBoZWlnaHQ9IjE5OCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI0MTQiIHk9IjY4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4mIzEyMzs8L3RleHQ+Cjx0ZXh0IHg9IjQzMCIgeT0iODQiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiJpZCI6ICAgICAgICAib3JkZXJzfHBrPVM6dXNlciM0Mnxzaz1TOm9yZGVyIzciLDwvdGV4dD4KPHRleHQgeD0iNDMwIiB5PSIxMDIiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPiJfcGsiOiAgICAgICAib3JkZXJzfFM6dXNlciM0MiIsPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjEyMCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+Il90YmwiOiAgICAgICJvcmRlcnMiLDwvdGV4dD4KPHRleHQgeD0iNDMwIiB5PSIxMzgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPiJfb2tleSI6ICAgICAi4oCmIiw8L3RleHQ+Cjx0ZXh0IHg9IjQzMCIgeT0iMTU2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij4iX2tleUF0dHJzIjogWyJwayIsInNrIl0sPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjE3NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+Iml0ZW0iOiAmIzEyMzs8L3RleHQ+Cjx0ZXh0IHg9IjQ0NiIgeT0iMTkyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojZmJiZjI0Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAxMjMuNDUgJiMxMjU7LCAg4oCmPC90ZXh0Pgo8dGV4dCB4PSI0MzAiIHk9IjIxMCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0MTQiIHk9IjIyOCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+JiMxMjU7PC90ZXh0Pgo8L3N2Zz4=)

Each attribute keeps its DynamoDB type tag around a native Firestore value, so filters and indexes can run in Firestore.

#### Tables

Firestore is serverless: there is no account tier, throughput mode or capacity to size. Every DynamoDB table you declare goes into the same `ddb` collection, and documents are kept apart by table-prefixed IDs and a table field. Firestore shards documents automatically and bills for operations and stored data, so an idle table still costs storage.

`CreateTable`, `UpdateTable` and `DeleteTable` change only the registry document, and `DescribeTable` and `ListTables` read it; none of them calls Firestore's admin API. `DeleteTable` removes the table with one metadata write: its documents disappear from the application at once but stay stored until a later deletion of a table with the same name cleans them up in bounded batches. A table re-created under the same name starts empty, under a new internal name such as `orders#2`.

* **The key schema must be known.** It comes from a declared table, the registry or the first request that includes the key. A `PutItem` whose key schema cannot be resolved is rejected, never written under a guessed key.
* **Tables are separated by name, not by database.** All tables share the project's one Firestore database, which other Firestore-backed apps in the project also use. A `GetItem` or base `Query` reads only its table's documents by ID prefix; a `Scan` filters on the table field. A dedicated database or database-scoped identity per install is not provided.

![Every table lives in one Firestore collection named ddb, told apart by a table field. Firestore is serverless: there is no throughput mode to choose and no capacity to size, documents are sharded automatically, and billing follows operations and storage.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjE4IiB2aWV3Qm94PSIwIDAgODM2IDIxOCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFdmVyeSB0YWJsZSBsaXZlcyBpbiBvbmUgRmlyZXN0b3JlIGNvbGxlY3Rpb24gbmFtZWQgZGRiLCB0b2xkIGFwYXJ0IGJ5IGEgdGFibGUgZmllbGQuIEZpcmVzdG9yZSBpcyBzZXJ2ZXJsZXNzOiB0aGVyZSBpcyBubyB0aHJvdWdocHV0IG1vZGUgdG8gY2hvb3NlIGFuZCBubyBjYXBhY2l0eSB0byBzaXplLCBkb2N1bWVudHMgYXJlIHNoYXJkZWQgYXV0b21hdGljYWxseSwgYW5kIGJpbGxpbmcgZm9sbG93cyBvcGVyYXRpb25zIGFuZCBzdG9yYWdlLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPlRIRSBQUk9KRUNUJ1MgRklSRVNUT1JFIMK3IGNvbGxlY3Rpb24gImRkYiI8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSI0MCIgd2lkdGg9IjQ3MCIgaGVpZ2h0PSIxNTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMTMyIiBoZWlnaHQ9Ijg2IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjExMCIgeT0iODYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPl90Ymw6IG9yZGVyczwvdGV4dD4KPHRleHQgeD0iMTEwIiB5PSIxMDgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vd24gZG9jdW1lbnRzPC90ZXh0Pgo8dGV4dCB4PSIxMTAiIHk9IjEyNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm93biBpbmRleGVzPC90ZXh0Pgo8cmVjdCB4PSIxOTUiIHk9IjU4IiB3aWR0aD0iMTMyIiBoZWlnaHQ9Ijg2IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjI2MSIgeT0iODYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPl90Ymw6IHVzZXJzPC90ZXh0Pgo8dGV4dCB4PSIyNjEiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm93biBkb2N1bWVudHM8L3RleHQ+Cjx0ZXh0IHg9IjI2MSIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b3duIGluZGV4ZXM8L3RleHQ+CjxyZWN0IHg9IjM0NiIgeT0iNTgiIHdpZHRoPSIxMzIiIGhlaWdodD0iODYiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iNDEyIiB5PSI4NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+X3RibDogZXZlbnRzPC90ZXh0Pgo8dGV4dCB4PSI0MTIiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm93biBkb2N1bWVudHM8L3RleHQ+Cjx0ZXh0IHg9IjQxMiIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b3duIGluZGV4ZXM8L3RleHQ+Cjx0ZXh0IHg9IjI2MSIgeT0iMTc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b25lIGNvbGxlY3Rpb24gwrcgYSByZWdpc3RyeSBkb2N1bWVudCBob2xkcyB0aGUgdGFibGUgZGVmaW5pdGlvbnM8L3RleHQ+Cjx0ZXh0IHg9IjUyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPlNFUlZFUkxFU1M8L3RleHQ+CjxyZWN0IHg9IjUyNiIgeT0iNDAiIHdpZHRoPSIyODYiIGhlaWdodD0iMTU4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI0IDQiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHJlY3QgeD0iNTQyIiB5PSI1OCIgd2lkdGg9IjI1NCIgaGVpZ2h0PSI0MCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjY2OSIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiMzMzQxNTUiPm5vIHRocm91Z2hwdXQgbW9kZSB0byBjaG9vc2U8L3RleHQ+CjxyZWN0IHg9IjU0MiIgeT0iMTA2IiB3aWR0aD0iMjU0IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjY5IiB5PSIxMzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiMzMzQxNTUiPmRvY3VtZW50cyBhdXRvLXNoYXJkZWQsIG5vIGNhcGFjaXR5IHRvIHNpemU8L3RleHQ+CjxyZWN0IHg9IjU0MiIgeT0iMTU0IiB3aWR0aD0iMjU0IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjY5IiB5PSIxNzkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiMzMzQxNTUiPm9wZXJhdGlvbiBhbmQgc3RvcmFnZSBjaGFyZ2VzPC90ZXh0Pgo8L3N2Zz4=)

![Every table lives in one Firestore collection named ddb, told apart by a table field. Firestore is serverless: there is no throughput mode to choose and no capacity to size, documents are sharded automatically, and billing follows operations and storage.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjE4IiB2aWV3Qm94PSIwIDAgODM2IDIxOCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFdmVyeSB0YWJsZSBsaXZlcyBpbiBvbmUgRmlyZXN0b3JlIGNvbGxlY3Rpb24gbmFtZWQgZGRiLCB0b2xkIGFwYXJ0IGJ5IGEgdGFibGUgZmllbGQuIEZpcmVzdG9yZSBpcyBzZXJ2ZXJsZXNzOiB0aGVyZSBpcyBubyB0aHJvdWdocHV0IG1vZGUgdG8gY2hvb3NlIGFuZCBubyBjYXBhY2l0eSB0byBzaXplLCBkb2N1bWVudHMgYXJlIHNoYXJkZWQgYXV0b21hdGljYWxseSwgYW5kIGJpbGxpbmcgZm9sbG93cyBvcGVyYXRpb25zIGFuZCBzdG9yYWdlLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPlRIRSBQUk9KRUNUJ1MgRklSRVNUT1JFIMK3IGNvbGxlY3Rpb24gImRkYiI8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSI0MCIgd2lkdGg9IjQ3MCIgaGVpZ2h0PSIxNTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMTMyIiBoZWlnaHQ9Ijg2IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjExMCIgeT0iODYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPl90Ymw6IG9yZGVyczwvdGV4dD4KPHRleHQgeD0iMTEwIiB5PSIxMDgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vd24gZG9jdW1lbnRzPC90ZXh0Pgo8dGV4dCB4PSIxMTAiIHk9IjEyNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm93biBpbmRleGVzPC90ZXh0Pgo8cmVjdCB4PSIxOTUiIHk9IjU4IiB3aWR0aD0iMTMyIiBoZWlnaHQ9Ijg2IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjI2MSIgeT0iODYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPl90Ymw6IHVzZXJzPC90ZXh0Pgo8dGV4dCB4PSIyNjEiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm93biBkb2N1bWVudHM8L3RleHQ+Cjx0ZXh0IHg9IjI2MSIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b3duIGluZGV4ZXM8L3RleHQ+CjxyZWN0IHg9IjM0NiIgeT0iNTgiIHdpZHRoPSIxMzIiIGhlaWdodD0iODYiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNDEyIiB5PSI4NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+X3RibDogZXZlbnRzPC90ZXh0Pgo8dGV4dCB4PSI0MTIiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm93biBkb2N1bWVudHM8L3RleHQ+Cjx0ZXh0IHg9IjQxMiIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b3duIGluZGV4ZXM8L3RleHQ+Cjx0ZXh0IHg9IjI2MSIgeT0iMTc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b25lIGNvbGxlY3Rpb24gwrcgYSByZWdpc3RyeSBkb2N1bWVudCBob2xkcyB0aGUgdGFibGUgZGVmaW5pdGlvbnM8L3RleHQ+Cjx0ZXh0IHg9IjUyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPlNFUlZFUkxFU1M8L3RleHQ+CjxyZWN0IHg9IjUyNiIgeT0iNDAiIHdpZHRoPSIyODYiIGhlaWdodD0iMTU4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI0IDQiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHJlY3QgeD0iNTQyIiB5PSI1OCIgd2lkdGg9IjI1NCIgaGVpZ2h0PSI0MCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjY2OSIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNjYmQ1ZTEiPm5vIHRocm91Z2hwdXQgbW9kZSB0byBjaG9vc2U8L3RleHQ+CjxyZWN0IHg9IjU0MiIgeT0iMTA2IiB3aWR0aD0iMjU0IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjY5IiB5PSIxMzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNjYmQ1ZTEiPmRvY3VtZW50cyBhdXRvLXNoYXJkZWQsIG5vIGNhcGFjaXR5IHRvIHNpemU8L3RleHQ+CjxyZWN0IHg9IjU0MiIgeT0iMTU0IiB3aWR0aD0iMjU0IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjY5IiB5PSIxNzkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNjYmQ1ZTEiPm9wZXJhdGlvbiBhbmQgc3RvcmFnZSBjaGFyZ2VzPC90ZXh0Pgo8L3N2Zz4=)

Every table shares the ddb collection; Firestore has no throughput mode or capacity to size.

#### Conditional writes

A conditional write reads the document and its `updateTime`, evaluates your DynamoDB condition in the adapter, and writes only if the document has not changed since. Creating an item uses a does-not-exist precondition instead. A false condition returns `ConditionalCheckFailed`. A concurrent change returns a retryable conflict, which your SDK retries with its own backoff; the adapter does not loop.

The read adds latency and a billed read operation even without contention. On a heavily contended document, retries can keep colliding, and once the SDK's retry budget runs out your application sees a throttling error. Read-then-write updates are computed in the adapter and written with a version check, so they stay atomic when another writer races.

Which writes skip the read?

Firestore supports masked field updates and atomic increments, but the adapter uses a narrower set:

* **PutItem and DeleteItem:** one direct document write when there is no condition, `ReturnValues=NONE` and DynamoDB Streams is off.
* **UpdateItem with only top-level REMOVE actions:** one masked document write under the same conditions, provided the update does not touch the configured TTL attribute.
* **Everything else, including SET:** read, then write. A SET cannot check DynamoDB's 400-KiB item limit without the current item. Arithmetic, nested updates, returned attributes and TTL changes also read first, and Firestore's native increment is not used for numeric updates.

**Relaxing the size check.** Setting `FIRESTORE_ALLOW_OVERSIZED_BLIND_UPDATES` to `"true"` in the adapter configuration lets top-level SET and REMOVE updates skip the read under the same conditions: no condition, no returned values, Streams off and no TTL change. Primary-key and secondary-index-key changes, and tables with a local secondary index, still read first. The default is `"false"`.

The option skips only the 400-KiB check on the resulting item. Firestore's own [1-MiB document limit](https://docs.cloud.google.com/firestore/quotas) still applies and includes the adapter's type tags and fields, so it is not a 1-MiB DynamoDB item allowance. PutItem, read-then-write updates and transactions keep their checks, so an item grown past 400 KiB may need a large attribute removed or replaced before those writes succeed. This option has not been benchmarked.

![A conditional write reads the current document and its update time, evaluates the DynamoDB condition in the adapter, then writes only if the document is unchanged. A write that loses a race returns a retryable conflict, not a condition failure.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGNvbmRpdGlvbmFsIHdyaXRlIHJlYWRzIHRoZSBjdXJyZW50IGRvY3VtZW50IGFuZCBpdHMgdXBkYXRlIHRpbWUsIGV2YWx1YXRlcyB0aGUgRHluYW1vREIgY29uZGl0aW9uIGluIHRoZSBhZGFwdGVyLCB0aGVuIHdyaXRlcyBvbmx5IGlmIHRoZSBkb2N1bWVudCBpcyB1bmNoYW5nZWQuIEEgd3JpdGUgdGhhdCBsb3NlcyBhIHJhY2UgcmV0dXJucyBhIHJldHJ5YWJsZSBjb25mbGljdCwgbm90IGEgY29uZGl0aW9uIGZhaWx1cmUuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImZhNSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlJlYWQgY3VycmVudCBkb2M8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSI3OSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmNhcHR1cmUgaXRzIDx0c3BhbiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij51cGRhdGVUaW1lPC90c3Bhbj48L3RleHQ+CjxsaW5lIHgxPSIxNzIiIHkxPSI5MCIgeDI9IjE3MiIgeTI9IjExMiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZmE1KSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIyMjAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMi41cHgiPkV2YWx1YXRlIGNvbmRpdGlvbjwvdGV4dD4KPHRleHQgeD0iNzYiIHk9IjE1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+YWdhaW5zdCB0aGUgY3VycmVudCBpdGVtPC90ZXh0Pgo8bGluZSB4MT0iMTcyIiB5MT0iMTY0IiB4Mj0iMTcyIiB5Mj0iMTg2IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNmYTUpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEyLjVweCI+V3JpdGUgaWYgdXBkYXRlVGltZSBtYXRjaGVzPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMjI3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+ZmFpbHMgaWYgaXQgaGFzIGNoYW5nZWQ8L3RleHQ+CjxsaW5lIHgxPSIyODIiIHkxPSIxNDAiIHgyPSIzNTQiIHkyPSIxNDAiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZhNSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSIzNTYiIHk9IjExOCIgd2lkdGg9IjM0MCIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI1MjYiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMnB4Ij5jb25kaXRpb24gZmFsc2Ug4oaSPC90ZXh0Pgo8dGV4dCB4PSI1MjYiIHk9IjE1MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+Q29uZGl0aW9uYWxDaGVja0ZhaWxlZDwvdGV4dD4KPGxpbmUgeDE9IjI4MiIgeTE9IjIxNCIgeDI9IjM1NCIgeTI9IjIxNCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZmE1KSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjM1NiIgeT0iMTkyIiB3aWR0aD0iMzQwIiBoZWlnaHQ9IjQ0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmYmViO3N0cm9rZTojZmRlNjhhIi8+Cjx0ZXh0IHg9IjUyNiIgeT0iMjEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTJweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2I0NTMwOSI+YSByYWNlciBjaGFuZ2VkIGl0IGZpcnN0IOKGkjwvdGV4dD4KPHRleHQgeD0iNTI2IiB5PSIyMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiNiNDUzMDkiPnJldHJ5YWJsZSBjb25mbGljdDwvdGV4dD4KPC9zdmc+)

![A conditional write reads the current document and its update time, evaluates the DynamoDB condition in the adapter, then writes only if the document is unchanged. A write that loses a race returns a retryable conflict, not a condition failure.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGNvbmRpdGlvbmFsIHdyaXRlIHJlYWRzIHRoZSBjdXJyZW50IGRvY3VtZW50IGFuZCBpdHMgdXBkYXRlIHRpbWUsIGV2YWx1YXRlcyB0aGUgRHluYW1vREIgY29uZGl0aW9uIGluIHRoZSBhZGFwdGVyLCB0aGVuIHdyaXRlcyBvbmx5IGlmIHRoZSBkb2N1bWVudCBpcyB1bmNoYW5nZWQuIEEgd3JpdGUgdGhhdCBsb3NlcyBhIHJhY2UgcmV0dXJucyBhIHJldHJ5YWJsZSBjb25mbGljdCwgbm90IGEgY29uZGl0aW9uIGZhaWx1cmUuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImZhNSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlJlYWQgY3VycmVudCBkb2M8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSI3OSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmNhcHR1cmUgaXRzIDx0c3BhbiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj51cGRhdGVUaW1lPC90c3Bhbj48L3RleHQ+CjxsaW5lIHgxPSIxNzIiIHkxPSI5MCIgeDI9IjE3MiIgeTI9IjExMiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZmE1KSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIyMjAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMi41cHgiPkV2YWx1YXRlIGNvbmRpdGlvbjwvdGV4dD4KPHRleHQgeD0iNzYiIHk9IjE1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+YWdhaW5zdCB0aGUgY3VycmVudCBpdGVtPC90ZXh0Pgo8bGluZSB4MT0iMTcyIiB5MT0iMTY0IiB4Mj0iMTcyIiB5Mj0iMTg2IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNmYTUpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjIyMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEyLjVweCI+V3JpdGUgaWYgdXBkYXRlVGltZSBtYXRjaGVzPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMjI3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+ZmFpbHMgaWYgaXQgaGFzIGNoYW5nZWQ8L3RleHQ+CjxsaW5lIHgxPSIyODIiIHkxPSIxNDAiIHgyPSIzNTQiIHkyPSIxNDAiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZhNSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSIzNTYiIHk9IjExOCIgd2lkdGg9IjM0MCIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI1MjYiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMnB4Ij5jb25kaXRpb24gZmFsc2Ug4oaSPC90ZXh0Pgo8dGV4dCB4PSI1MjYiIHk9IjE1MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+Q29uZGl0aW9uYWxDaGVja0ZhaWxlZDwvdGV4dD4KPGxpbmUgeDE9IjI4MiIgeTE9IjIxNCIgeDI9IjM1NCIgeTI9IjIxNCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZmE1KSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjM1NiIgeT0iMTkyIiB3aWR0aD0iMzQwIiBoZWlnaHQ9IjQ0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojNDIyMDA2O3N0cm9rZTojOTI0MDBlIi8+Cjx0ZXh0IHg9IjUyNiIgeT0iMjEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTJweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2ZiYmYyNCI+YSByYWNlciBjaGFuZ2VkIGl0IGZpcnN0IOKGkjwvdGV4dD4KPHRleHQgeD0iNTI2IiB5PSIyMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNmYmJmMjQiPnJldHJ5YWJsZSBjb25mbGljdDwvdGV4dD4KPC9zdmc+)

A false condition and a concurrent change to the document return different errors.

#### Secondary indexes

Each declared global secondary index is a pair of Firestore composite indexes, ascending and descending, over the table field, the index's hash attribute, its optional range attribute and the document ID. There is no separate copy of the item. Firestore updates the index with the item write: a changed key moves the item, a deleted item leaves the index, and an item without the hash or range attribute is not in the index, as on DynamoDB.

Index reads are therefore stronger than on DynamoDB, whose GSIs are eventually consistent: a query sees the write that just completed. Key conditions, ordering, cursor, limit and supported filters run in Firestore; other filters run in the adapter over that bounded result. Numbers compare numerically, and the document ID breaks ties, so pagination is exact when items share a range value. Indexes must be declared when your stack is compiled; querying an undeclared index returns a validation error rather than scanning the table.

![A base write stores the item's fields. Firestore updates composite indexes over those fields with the write, so a GSI query runs its key conditions, order, cursor and limit in Firestore.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGJhc2Ugd3JpdGUgc3RvcmVzIHRoZSBpdGVtJ3MgZmllbGRzLiBGaXJlc3RvcmUgdXBkYXRlcyBjb21wb3NpdGUgaW5kZXhlcyBvdmVyIHRob3NlIGZpZWxkcyB3aXRoIHRoZSB3cml0ZSwgc28gYSBHU0kgcXVlcnkgcnVucyBpdHMga2V5IGNvbmRpdGlvbnMsIG9yZGVyLCBjdXJzb3IgYW5kIGxpbWl0IGluIEZpcmVzdG9yZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZmE2IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZmE2cSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNGY0NmU1Ii8+PC9tYXJrZXI+PC9kZWZzPgo8cmVjdCB4PSIyNiIgeT0iNDAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNTgiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTAxIiB5PSI2NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlB1dEl0ZW08L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5zdGF0dXMgPSBTSElQUEVEPC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNjkiIHgyPSIyMzIiIHkyPSI2OSIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2ZhNikiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIyMDQiIHk9IjYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPndyaXRlPC90ZXh0Pgo8cmVjdCB4PSIyMzYiIHk9IjM0IiB3aWR0aD0iMTgwIiBoZWlnaHQ9IjcwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjMyNiIgeT0iNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTJweCI+YmFzZSBkb2N1bWVudDwvdGV4dD4KPHRleHQgeD0iMzI2IiB5PSI3OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+dGhlIGl0ZW0ncyBkb2N1bWVudDwvdGV4dD4KPHRleHQgeD0iMzI2IiB5PSI5MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+aXRlbS5zdGF0dXMuUyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSIzMjYiIHkxPSIxMDQiIHgyPSIzMjYiIHkyPSIxMzIiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNmYTYpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzM4IiB5PSIxMjIiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+aW5kZXhlZDwvdGV4dD4KPHJlY3QgeD0iMjM2IiB5PSIxMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMzI2IiB5PSIxNTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTEuNXB4Ij5GaXJlc3RvcmUgY29tcG9zaXRlIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+X3RibCwgaXRlbS5zdGF0dXMuUywgaWQ8L3RleHQ+CjxyZWN0IHg9IjUwMCIgeT0iNDAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNTgiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTc1IiB5PSI2NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlF1ZXJ5IEdTSTwvdGV4dD4KPHRleHQgeD0iNTc1IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnN0YXR1cyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSI1NzUiIHkxPSI5OCIgeDI9IjU3NSIgeTI9IjE2NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIHN0eWxlPSJzdHJva2U6IzRmNDZlNSIvPgo8bGluZSB4MT0iNTc1IiB5MT0iMTY0IiB4Mj0iNDE4IiB5Mj0iMTY0IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNmYTZxKSIgc3R5bGU9InN0cm9rZTojNGY0NmU1Ii8+Cjx0ZXh0IHg9IjQ5NiIgeT0iMTU3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNGY0NmU1Ij5lcXVhbGl0eSBsb29rdXA8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iNzAiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiMzMzQxNTU7Zm9udC13ZWlnaHQ6NjAwIj5TcGFyc2UgKyBzeW5jaHJvbm91czo8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iOTAiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5hbiBpdGVtIG1pc3NpbmcgYW4gaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTA2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+a2V5IGlzIG5vdCBpbiB0aGUgaW5kZXg7PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjEyMiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkZpcmVzdG9yZSBtYWludGFpbnMgaXQ8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTM4IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+d2l0aCB0aGUgaXRlbSB3cml0ZS48L3RleHQ+Cjwvc3ZnPg==)

![A base write stores the item's fields. Firestore updates composite indexes over those fields with the write, so a GSI query runs its key conditions, order, cursor and limit in Firestore.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGJhc2Ugd3JpdGUgc3RvcmVzIHRoZSBpdGVtJ3MgZmllbGRzLiBGaXJlc3RvcmUgdXBkYXRlcyBjb21wb3NpdGUgaW5kZXhlcyBvdmVyIHRob3NlIGZpZWxkcyB3aXRoIHRoZSB3cml0ZSwgc28gYSBHU0kgcXVlcnkgcnVucyBpdHMga2V5IGNvbmRpdGlvbnMsIG9yZGVyLCBjdXJzb3IgYW5kIGxpbWl0IGluIEZpcmVzdG9yZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZmE2IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZmE2cSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojYTViNGZjIi8+PC9tYXJrZXI+PC9kZWZzPgo8cmVjdCB4PSIyNiIgeT0iNDAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNTgiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTAxIiB5PSI2NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlB1dEl0ZW08L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5zdGF0dXMgPSBTSElQUEVEPC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNjkiIHgyPSIyMzIiIHkyPSI2OSIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2ZhNikiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIyMDQiIHk9IjYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPndyaXRlPC90ZXh0Pgo8cmVjdCB4PSIyMzYiIHk9IjM0IiB3aWR0aD0iMTgwIiBoZWlnaHQ9IjcwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjMyNiIgeT0iNjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTJweCI+YmFzZSBkb2N1bWVudDwvdGV4dD4KPHRleHQgeD0iMzI2IiB5PSI3OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+dGhlIGl0ZW0ncyBkb2N1bWVudDwvdGV4dD4KPHRleHQgeD0iMzI2IiB5PSI5MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+aXRlbS5zdGF0dXMuUyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSIzMjYiIHkxPSIxMDQiIHgyPSIzMjYiIHkyPSIxMzIiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNmYTYpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzM4IiB5PSIxMjIiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+aW5kZXhlZDwvdGV4dD4KPHJlY3QgeD0iMjM2IiB5PSIxMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzI2IiB5PSIxNTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTEuNXB4Ij5GaXJlc3RvcmUgY29tcG9zaXRlIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+X3RibCwgaXRlbS5zdGF0dXMuUywgaWQ8L3RleHQ+CjxyZWN0IHg9IjUwMCIgeT0iNDAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNTgiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTc1IiB5PSI2NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlF1ZXJ5IEdTSTwvdGV4dD4KPHRleHQgeD0iNTc1IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnN0YXR1cyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSI1NzUiIHkxPSI5OCIgeDI9IjU3NSIgeTI9IjE2NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIHN0eWxlPSJzdHJva2U6I2E1YjRmYyIvPgo8bGluZSB4MT0iNTc1IiB5MT0iMTY0IiB4Mj0iNDE4IiB5Mj0iMTY0IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNmYTZxKSIgc3R5bGU9InN0cm9rZTojYTViNGZjIi8+Cjx0ZXh0IHg9IjQ5NiIgeT0iMTU3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojYTViNGZjIj5lcXVhbGl0eSBsb29rdXA8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iNzAiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNjYmQ1ZTE7Zm9udC13ZWlnaHQ6NjAwIj5TcGFyc2UgKyBzeW5jaHJvbm91czo8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iOTAiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5hbiBpdGVtIG1pc3NpbmcgYW4gaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTA2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+a2V5IGlzIG5vdCBpbiB0aGUgaW5kZXg7PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjEyMiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkZpcmVzdG9yZSBtYWludGFpbnMgaXQ8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTM4IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+d2l0aCB0aGUgaXRlbSB3cml0ZS48L3RleHQ+Cjwvc3ZnPg==)

Each declared GSI is a Firestore composite index over the item's own fields, and the query runs in Firestore.

#### Transactions

`TransactWriteItems` runs as a Firestore read-write transaction. The adapter reads each target document inside the transaction, evaluates each DynamoDB condition itself, and commits all the writes atomically. If any condition fails, nothing is written. If the commit loses a race with another writer, the SDK retries it as a temporary conflict.

A transaction can span documents, tables and partition keys, up to DynamoDB's 100-action limit. A cancelled transaction returns a single condition-failure error without per-item `CancellationReasons`, so your application cannot tell which condition failed.

![A TransactWriteItems whose items span two different partition keys commits as one atomic Firestore transaction across documents; both the debit and credit commit, or neither does.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA2IiB2aWV3Qm94PSIwIDAgODM2IDIwNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIFRyYW5zYWN0V3JpdGVJdGVtcyB3aG9zZSBpdGVtcyBzcGFuIHR3byBkaWZmZXJlbnQgcGFydGl0aW9uIGtleXMgY29tbWl0cyBhcyBvbmUgYXRvbWljIEZpcmVzdG9yZSB0cmFuc2FjdGlvbiBhY3Jvc3MgZG9jdW1lbnRzOyBib3RoIHRoZSBkZWJpdCBhbmQgY3JlZGl0IGNvbW1pdCwgb3IgbmVpdGhlciBkb2VzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJmYTciIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzA0Nzg1NyIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI4IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5BQ1JPU1MgUEFSVElUSU9OIEtFWVMg4oaSIEFUT01JQzwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTc2IiBoZWlnaHQ9Ijk0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjExNCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+VHJhbnNhY3RXcml0ZTwvdGV4dD4KPHRleHQgeD0iMTE0IiB5PSI4NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+YWNjb3VudHN8QSAgZGViaXQ8L3RleHQ+Cjx0ZXh0IHg9IjExNCIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5hY2NvdW50c3xCICBjcmVkaXQ8L3RleHQ+Cjx0ZXh0IHg9IjExNCIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dHdvIGRpZmZlcmVudCBrZXlzPC90ZXh0Pgo8bGluZSB4MT0iMjAyIiB5MT0iODciIHgyPSIyNTYiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2ZhNykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSIyNjAiIHk9IjUyIiB3aWR0aD0iMTk2IiBoZWlnaHQ9IjcwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS43IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjM1OCIgeT0iODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTIuNXB4Ij5GaXJlc3RvcmUgdHJhbnNhY3Rpb248L3RleHQ+Cjx0ZXh0IHg9IjM1OCIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmFjcm9zcyBkb2N1bWVudHMgwrcgYWxsLW9yLW5vdGhpbmc8L3RleHQ+CjxsaW5lIHgxPSI0NTYiIHkxPSI4NyIgeDI9IjUxMCIgeTI9Ijg3IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZmE3KSIgc3R5bGU9InN0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjUxNCIgeT0iNTIiIHdpZHRoPSIxNjAiIGhlaWdodD0iNzAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iNTk0IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5ib3RoIGNvbW1pdDwvdGV4dD4KPHRleHQgeD0iNTk0IiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj50cmFuc2ZlciBiZXR3ZWVuIEEgYW5kIEI8L3RleHQ+Cjx0ZXh0IHg9IjY5MiIgeT0iNzIiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiMzMzQxNTU7Zm9udC13ZWlnaHQ6NjAwIj5BY3Jvc3MgZG9jdW1lbnRzOzwvdGV4dD4KPHRleHQgeD0iNjkyIiB5PSI5MiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkFkYXB0ZXIgZW5mb3JjZXMgMTAwLTwvdGV4dD4KPHRleHQgeD0iNjkyIiB5PSIxMDgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5hY3Rpb24gdHJhbnNhY3Rpb25zLjwvdGV4dD4KPC9zdmc+)

![A TransactWriteItems whose items span two different partition keys commits as one atomic Firestore transaction across documents; both the debit and credit commit, or neither does.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA2IiB2aWV3Qm94PSIwIDAgODM2IDIwNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIFRyYW5zYWN0V3JpdGVJdGVtcyB3aG9zZSBpdGVtcyBzcGFuIHR3byBkaWZmZXJlbnQgcGFydGl0aW9uIGtleXMgY29tbWl0cyBhcyBvbmUgYXRvbWljIEZpcmVzdG9yZSB0cmFuc2FjdGlvbiBhY3Jvc3MgZG9jdW1lbnRzOyBib3RoIHRoZSBkZWJpdCBhbmQgY3JlZGl0IGNvbW1pdCwgb3IgbmVpdGhlciBkb2VzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJmYTciIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzZlZTdiNyIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI4IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5BQ1JPU1MgUEFSVElUSU9OIEtFWVMg4oaSIEFUT01JQzwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTc2IiBoZWlnaHQ9Ijk0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjExNCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTJweCI+VHJhbnNhY3RXcml0ZTwvdGV4dD4KPHRleHQgeD0iMTE0IiB5PSI4NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+YWNjb3VudHN8QSAgZGViaXQ8L3RleHQ+Cjx0ZXh0IHg9IjExNCIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5hY2NvdW50c3xCICBjcmVkaXQ8L3RleHQ+Cjx0ZXh0IHg9IjExNCIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dHdvIGRpZmZlcmVudCBrZXlzPC90ZXh0Pgo8bGluZSB4MT0iMjAyIiB5MT0iODciIHgyPSIyNTYiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2ZhNykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSIyNjAiIHk9IjUyIiB3aWR0aD0iMTk2IiBoZWlnaHQ9IjcwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS43IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjM1OCIgeT0iODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTIuNXB4Ij5GaXJlc3RvcmUgdHJhbnNhY3Rpb248L3RleHQ+Cjx0ZXh0IHg9IjM1OCIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmFjcm9zcyBkb2N1bWVudHMgwrcgYWxsLW9yLW5vdGhpbmc8L3RleHQ+CjxsaW5lIHgxPSI0NTYiIHkxPSI4NyIgeDI9IjUxMCIgeTI9Ijg3IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZmE3KSIgc3R5bGU9InN0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjUxNCIgeT0iNTIiIHdpZHRoPSIxNjAiIGhlaWdodD0iNzAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNTk0IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5ib3RoIGNvbW1pdDwvdGV4dD4KPHRleHQgeD0iNTk0IiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj50cmFuc2ZlciBiZXR3ZWVuIEEgYW5kIEI8L3RleHQ+Cjx0ZXh0IHg9IjY5MiIgeT0iNzIiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNjYmQ1ZTE7Zm9udC13ZWlnaHQ6NjAwIj5BY3Jvc3MgZG9jdW1lbnRzOzwvdGV4dD4KPHRleHQgeD0iNjkyIiB5PSI5MiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkFkYXB0ZXIgZW5mb3JjZXMgMTAwLTwvdGV4dD4KPHRleHQgeD0iNjkyIiB5PSIxMDgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5hY3Rpb24gdHJhbnNhY3Rpb25zLjwvdGV4dD4KPC9zdmc+)

TransactWriteItems runs as one Firestore transaction across documents: the debit and credit both commit, or neither does.

#### Limitations

* **Numbers beyond 15 significant digits are not supported.** Signed 64-bit integers are stored exactly. Other numbers must fit within 15 significant digits; a number outside that range is rejected, not rounded.
* **Frequent writes to one document behave differently: they can conflict.** Repeated updates to the same document can hit version conflicts or throttling. SDK retries add latency and billed operations, and a finite retry budget can surface an error. Test with your real key distribution.
* **Most updates behave differently: they read the item first.** By default SET reads the item to enforce the 400-KiB limit, as do conditions, arithmetic, nested updates and returned attributes; only eligible REMOVE-only updates write directly. `FIRESTORE_ALLOW_OVERSIZED_BLIND_UPDATES` extends direct writes to eligible SET and REMOVE updates but relaxes the size check.
* **A separate database per table or install is not supported.** All tables share the project's one Firestore database and are kept apart by document ID and a table field, not by a dedicated database or a database-scoped identity.
* **You must declare secondary indexes at compile time.** They come from the `global_secondary_index` blocks on your `aws_dynamodb_table`; adding one means editing your Terraform and releasing again. `CreateTable` may name only the compiled indexes, `UpdateTable` cannot add one, and querying an index that was not declared at compile time returns a validation error.
* **Strongly consistent reads on a global secondary index are not supported.** `ConsistentRead=true` on a GSI is rejected, as on DynamoDB; `ConsistentRead=false` is accepted. Local secondary indexes accept strong reads, and GSI updates are still synchronous.
* **Reads behave differently: they are always strongly consistent.** A single-document read reflects the latest committed write whatever `ConsistentRead` says. Estimate Firestore document and index-entry read charges for your actual queries.
* **Some filters behave differently: they run in the adapter.** Equality, bounded `IN` and type checks run in Firestore. `<>`, `attribute_not_exists`, `contains`, `begins_with`, `NOT` and filters whose Firestore order would conflict with DynamoDB key order run in the adapter over the bounded result; `begins_with` on a GSI sort key still runs in Firestore.
* **You must run one writer per table with Streams enabled.** Stream records are saved in order, in the same transaction as each change. A second instance writing to that table gets a retryable throttling error until the first instance's lease expires. Tables without a stream accept concurrent writers, and reads are unaffected.
* **Deleted-table storage behaves differently: it is cleaned up later.** `DeleteTable` hides the table's documents at once, but they stay stored until a later deletion of a table with the same name removes them in bounded batches. A large deleted table can keep costing storage.
* **Per-item transaction cancellation reasons are not supported.** A cancelled `TransactWriteItems` returns one condition-failure error instead of `CancellationReasons`, so your application cannot tell which item's condition failed.

#### Other considerations

* **Moving data.** The Firestore store starts empty. Move existing DynamoDB data by export and import, backfill or dual writes, and validate it before switching traffic.
* **Operations and ownership.** Google operates Firestore and Tensor9 operates the adapter, which uses workload identity and short-lived credentials. The customer manages the Google Cloud project, cluster maintenance and monitoring.
* **Capacity and cost.** Firestore bills operations and storage, with no provisioned throughput. Estimate charges from the documents and index entries your queries examine, counting every read as strongly consistent, and test contention on frequently updated documents.
* **Change streams.** DynamoDB Streams work through the Streams API with all four view types. Records are kept for a fixed window.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### Monthly cost by DynamoDB point-read rate

Reference monthly service charges by Read operations/s. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![Monthly cost by DynamoDB point-read rate: monthly service charges by Read operations/s. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/92c40e589be8534a152b82457a1d3605305d5f8f82776c784f2caa740ac7bb8f-light.svg)

![Monthly cost by DynamoDB point-read rate: monthly service charges by Read operations/s. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/0255e0fa374ce2d1fc31fde60207c4fcf2691cb5edb436b6fa5ff428c0ff6ba5-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Read operations/s (reads/s) | DynamoDB | Firestore | Difference |
| -: | -: | -: | -: |
| 0 | 25.00 | 15.00 | -10.00 |
| 1 | 25.49 | 16.02 | -9.47 |
| 10 | 29.93 | 25.25 | -4.68 |
| 100 | 74.28 | 117.49 | 43.22 |
| 1,000 | 517.75 | 1,039.92 | 522.17 |
| 10,000 | 4,952.50 | 10,264.20 | 5,311.70 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Representative DynamoDB item size | 1,024 | bytes |
| Strongly consistent origin reads | 1 | 0 = eventual, 1 = strong |
| Origin write-unit amplification | 1 | multiplier |
| Additional document reads per write | 0 | reads/write |
| Document writes per origin write | 1 | writes/write |
| Firestore physical storage / source billed bytes | 1 | multiplier |

* Strong 1 KiB point reads and plain writes; one write per ten reads, no origin index amplification. 730 hours/month; retained source data stays at 100 GiB. Firestore uses one document per item, blind writes, no extra reads and equal billed storage; this is an illustrative storage assumption.
* Monthly AWS source usage in us-east-1, priced at the 2026-10-18 reference list rates before free allowances, discounts, credits and tax; not the uploaded invoice total. Rates as of 2026-10-18: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Firestore Standard edition, regional us-central1. One document read per origin point read; explicit reads/writes per write.
* Plain unconditioned PutItem can use the blind write path; read-modify-write, conditions and retries increase document reads.
* Equal physical storage is an illustrative assumption; tagged item envelopes, metadata and indexes can change billed bytes.
* Source usage is priced at reference rates; source lines are not actual invoice charges. Free or discounted usage still consumes target resources.
* AWS DynamoDB Standard on-demand pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Firestore Standard regional pricing: [https://cloud.google.com/firestore/pricing/](https://cloud.google.com/firestore/pricing/)

Cost scope: Modeled monthly service usage and selected database allocation; adapter hosting and Tensor9 fees only when explicitly supplied.

Excluded costs and workload features:

* Free allowances, negotiated discounts, credits, tax and one-time migration charges.
* Charges not listed in the breakdown, including additional network transfer, backups and encryption/KMS.
* Application compute changes, operational labor and portfolio-wide sharing or deduplication of infrastructure.
* Queries, scans and index-entry reads, transactions, Streams, document deletes/TTL and unsupported item domains.

Rate snapshot: 2026-10-18. Model: `dynamodb-firestore` / `2026-10-18.4`. Curve: `read-rate`.

Sources: [AWS DynamoDB Standard on-demand pricing](https://aws.amazon.com/dynamodb/pricing/), [Firestore Standard regional pricing](https://cloud.google.com/firestore/pricing/).

##### Monthly cost by retained DynamoDB data

Reference monthly service charges by Retained source data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![Monthly cost by retained DynamoDB data: monthly service charges by Retained source data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/47c5f15e345c5a3e32a221b709a192d8a12535f3dffd41cb76286db65a45ff80-light.svg)

![Monthly cost by retained DynamoDB data: monthly service charges by Retained source data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/31717ac2c754518718d596d5cce749577fc58689d4970cb3f26602ab7a0e0dd3-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Retained source data (GiB-month) | DynamoDB | Firestore | Difference |
| -: | -: | -: | -: |
| 0 | 18.75 | 39.00 | 20.25 |
| 10 | 21.25 | 40.50 | 19.25 |
| 100 | 43.75 | 54.00 | 10.25 |
| 1,000 | 268.75 | 189.00 | -79.75 |
| 10,000 | 2,518.75 | 1,539.00 | -979.75 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Representative DynamoDB item size | 1,024 | bytes |
| Strongly consistent origin reads | 1 | 0 = eventual, 1 = strong |
| Origin write-unit amplification | 1 | multiplier |
| Additional document reads per write | 0 | reads/write |
| Document writes per origin write | 1 | writes/write |
| Firestore physical storage / source billed bytes | 1 | multiplier |

* Source traffic stays at 100 million strong 1 KiB read units and 10 million plain write units/month, with no origin index amplification. Firestore assumes equal billed storage, one document per item and blind writes; physical expansion and indexing require separate qualification.
* Monthly AWS source usage in us-east-1, priced at the 2026-10-18 reference list rates before free allowances, discounts, credits and tax; not the uploaded invoice total. Rates as of 2026-10-18: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Firestore Standard edition, regional us-central1. One document read per origin point read; explicit reads/writes per write.
* Plain unconditioned PutItem can use the blind write path; read-modify-write, conditions and retries increase document reads.
* Equal physical storage is an illustrative assumption; tagged item envelopes, metadata and indexes can change billed bytes.
* Source usage is priced at reference rates; source lines are not actual invoice charges. Free or discounted usage still consumes target resources.
* AWS DynamoDB Standard on-demand pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Firestore Standard regional pricing: [https://cloud.google.com/firestore/pricing/](https://cloud.google.com/firestore/pricing/)

Cost scope: Modeled monthly service usage and selected database allocation; adapter hosting and Tensor9 fees only when explicitly supplied.

Excluded costs and workload features:

* Free allowances, negotiated discounts, credits, tax and one-time migration charges.
* Charges not listed in the breakdown, including additional network transfer, backups and encryption/KMS.
* Application compute changes, operational labor and portfolio-wide sharing or deduplication of infrastructure.
* Queries, scans and index-entry reads, transactions, Streams, document deletes/TTL and unsupported item domains.

Rate snapshot: 2026-10-18. Model: `dynamodb-firestore` / `2026-10-18.4`. Curve: `retained-data`.

Sources: [AWS DynamoDB Standard on-demand pricing](https://aws.amazon.com/dynamodb/pricing/), [Firestore Standard regional pricing](https://cloud.google.com/firestore/pricing/).

**DynamoDB → Firestore: Reference monthly workload.** Monthly AWS usage charges at the 2026-10-18 reference list rates in us-east-1, before free allowances, discounts, credits and tax.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 12.50 |
| Origin: DynamoDB write units | 6.25 |
| Origin: DynamoDB stored data | 25.00 |
| Target: Firestore document reads | 30.00 |
| Target: Firestore document writes | 9.00 |
| Target: Firestore physical storage | 15.00 |
| **Origin service subtotal** | **43.75** |
| **Target service subtotal** | **54.00** |

Unestimated components: Allocated adapter hosting, Allocated Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled monthly service usage and selected database allocation; adapter hosting and Tensor9 fees only when explicitly supplied.

Excluded costs and workload features:

* Free allowances, negotiated discounts, credits, tax and one-time migration charges.
* Charges not listed in the breakdown, including additional network transfer, backups and encryption/KMS.
* Application compute changes, operational labor and portfolio-wide sharing or deduplication of infrastructure.
* Queries, scans and index-entry reads, transactions, Streams, document deletes/TTL and unsupported item domains.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| DynamoDB on-demand reads | 12.5 | USD/month |
| DynamoDB on-demand writes | 6.25 | USD/month |
| DynamoDB Standard storage | 25 | USD/month |
| Representative DynamoDB item size | 1,024 | bytes |
| Strongly consistent origin reads | 1 | 0 = eventual, 1 = strong |
| Origin write-unit amplification | 1 | multiplier |
| Additional document reads per write | 0 | reads/write |
| Document writes per origin write | 1 | writes/write |
| Firestore physical storage / source billed bytes | 1 | multiplier |

* Inferred point reads: 100,000,000 calls/month.

* Inferred base item writes: 10,000,000 calls/month.

* Origin billed storage: 100 GiB-month.

* Firestore Standard edition, regional us-central1. One document read per origin point read; explicit reads/writes per write.

* Plain unconditioned PutItem can use the blind write path; read-modify-write, conditions and retries increase document reads.

* Equal physical storage is an illustrative assumption; tagged item envelopes, metadata and indexes can change billed bytes.

Rate snapshot: 2026-10-18. Model: `dynamodb-firestore` / `2026-10-18.4`. Scenario: `dynamodb-firestore-reference`.

Sources: [AWS DynamoDB Standard on-demand pricing](https://aws.amazon.com/dynamodb/pricing/), [Firestore Standard regional pricing](https://cloud.google.com/firestore/pricing/).

### Cloud Spanner

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| BatchGetItem / BatchWriteItem | Batch | Supported | Common | lowered to native Spanner batch reads and mutations rather than issued one row at a time |
| DynamoDB Streams | Indexes + streams | Out of scope | Full surface | the write executor rejects stream-enabled writes; use another backend when the application requires change records |
| Query (GSI) | Indexes + streams | Supported | Most usage | a native index maintained with the row; ConsistentRead=true and ALL\_ATTRIBUTES on an index without all attributes are rejected, matching DynamoDB's GSI restrictions |
| Query (LSI) | Indexes + streams | Supported | Most usage | a local secondary index is interleaved with its table, so the query is an index seek and the index is written inside the same transaction as the row |
| Query | Query + scan | Supported | Common | key conditions, filters, ordering and limits compile into GoogleSQL; selective key ranges reduce work, but filters can still examine rows that are not returned |
| Scan | Query + scan | Supported | Most usage | paged table scan; consumes provisioned compute and competes with point reads and writes, so use selective Query access where possible |
| PutItem / GetItem / UpdateItem / DeleteItem | Single item | Supported | Common | each item is a row; attribute types round-trip exactly, with numbers at their full decimal precision rather than through a float |
| CreateTable / UpdateTable / DeleteTable / ListTables | Table control plane | Supported | Most usage | table and index definitions are applied as Spanner DDL; throughput-mode changes are a no-op because capacity is the instance's processing units, not the table's |
| TransactWriteItems / TransactGetItems | Transactions | Supported | Most usage | a real Spanner read-write transaction spanning tables and partition keys exactly as DynamoDB's does, at external consistency; the 100-action and one-op-per-item limits are enforced and ClientRequestToken gives the same idempotency window |

#### How it works

Your application keeps its AWS SDK, endpoint configuration and DynamoDB item formats. The Tensor9 adapter accepts DynamoDB requests, returns DynamoDB responses and errors, and stores the data in Spanner.

The adapter turns a `Query`'s key condition, filter, ordering and limit into one GoogleSQL statement, and Spanner runs it. A selective key range keeps the work small. A filter can still examine rows it does not return, so the compute a query uses depends on more than the size of its result.

![Before: on AWS your application's DynamoDB SDK calls Amazon DynamoDB. After: on Google Cloud the same application and SDK call a Tensor9 adapter, which stores the data in Google Cloud Spanner.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IG9uIEdvb2dsZSBDbG91ZCB0aGUgc2FtZSBhcHBsaWNhdGlvbiBhbmQgU0RLIGNhbGwgYSBUZW5zb3I5IGFkYXB0ZXIsIHdoaWNoIHN0b3JlcyB0aGUgZGF0YSBpbiBHb29nbGUgQ2xvdWQgU3Bhbm5lci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InNiYTEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0NiIgd2lkdGg9IjM1OCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIzMCIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjgwIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjkwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iOTAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkR5bmFtb0RCIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3NiYTEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iMTgxIiB5PSIxMDQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiOyBmb250LXNpemU6OC41cHgiPkR5bmFtb0RCPC90ZXh0Pgo8cmVjdCB4PSIyMTQiIHk9IjgwIiB3aWR0aD0iMTQ4IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjI4OCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjExLjVweCI+QW1hem9uIER5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiNjYmQ1ZTEiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBHT09HTEUgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ3NCIgeT0iODAiIHdpZHRoPSI5MiIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1MjAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNTIwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c2FtZSBTREs8L3RleHQ+CjxsaW5lIHgxPSI1NjYiIHkxPSIxMTMiIHgyPSI1OTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNzYmExKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzEyIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjc2JhMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSI3MTYiIHk9IjgwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc2NiIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjExcHgiPkNsb3VkIFNwYW5uZXI8L3RleHQ+Cjx0ZXh0IHg9Ijc2NiIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+bWFuYWdlZDwvdGV4dD4KPC9zdmc+)

![Before: on AWS your application's DynamoDB SDK calls Amazon DynamoDB. After: on Google Cloud the same application and SDK call a Tensor9 adapter, which stores the data in Google Cloud Spanner.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB5b3VyIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IG9uIEdvb2dsZSBDbG91ZCB0aGUgc2FtZSBhcHBsaWNhdGlvbiBhbmQgU0RLIGNhbGwgYSBUZW5zb3I5IGFkYXB0ZXIsIHdoaWNoIHN0b3JlcyB0aGUgZGF0YSBpbiBHb29nbGUgQ2xvdWQgU3Bhbm5lci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InNiYTEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0NiIgd2lkdGg9IjM1OCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIzMCIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjgwIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjkwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iOTAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkR5bmFtb0RCIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3NiYTEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iMTgxIiB5PSIxMDQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4OyBmb250LXNpemU6OC41cHgiPkR5bmFtb0RCPC90ZXh0Pgo8cmVjdCB4PSIyMTQiIHk9IjgwIiB3aWR0aD0iMTQ4IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjI4OCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjExLjVweCI+QW1hem9uIER5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiM0NzU1NjkiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PTiBHT09HTEUgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ3NCIgeT0iODAiIHdpZHRoPSI5MiIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1MjAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNTIwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c2FtZSBTREs8L3RleHQ+CjxsaW5lIHgxPSI1NjYiIHkxPSIxMTMiIHgyPSI1OTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNzYmExKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzEyIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjc2JhMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSI3MTYiIHk9IjgwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc2NiIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjExcHgiPkNsb3VkIFNwYW5uZXI8L3RleHQ+Cjx0ZXh0IHg9Ijc2NiIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+bWFuYWdlZDwvdGV4dD4KPC9zdmc+)

Your application keeps calling the DynamoDB JSON API. The adapter turns each call into GoogleSQL for Spanner.

#### Architecture

![How a request is carried out: the adapter checks each DynamoDB request and turns it into Spanner work. A read runs as one GoogleSQL statement and a write commits as Spanner mutations. Spanner holds one database with one table per DynamoDB table and a secondary index per declared index.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJIb3cgYSByZXF1ZXN0IGlzIGNhcnJpZWQgb3V0OiB0aGUgYWRhcHRlciBjaGVja3MgZWFjaCBEeW5hbW9EQiByZXF1ZXN0IGFuZCB0dXJucyBpdCBpbnRvIFNwYW5uZXIgd29yay4gQSByZWFkIHJ1bnMgYXMgb25lIEdvb2dsZVNRTCBzdGF0ZW1lbnQgYW5kIGEgd3JpdGUgY29tbWl0cyBhcyBTcGFubmVyIG11dGF0aW9ucy4gU3Bhbm5lciBob2xkcyBvbmUgZGF0YWJhc2Ugd2l0aCBvbmUgdGFibGUgcGVyIER5bmFtb0RCIHRhYmxlIGFuZCBhIHNlY29uZGFyeSBpbmRleCBwZXIgZGVjbGFyZWQgaW5kZXguIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhaHMyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI2LjUiIG1hcmtlckhlaWdodD0iNi41IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjxtYXJrZXIgaWQ9ImFoczMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDAiIHdpZHRoPSIzOTIiIGhlaWdodD0iMTQwIiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzIiIHk9IjMwIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiOCI+VEhFIEFEQVBURVI8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI2NCIgd2lkdGg9IjEwNiIgaGVpZ2h0PSI0NiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjgzIiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPkR5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj55b3VyIHJlcXVlc3Q8L3RleHQ+CjxsaW5lIHgxPSIxMzYiIHkxPSI4NyIgeDI9IjE1OCIgeTI9Ijg3IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhaHMzKSIgc3R5bGU9InN0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjE2NCIgeT0iNjQiIHdpZHRoPSIxMDYiIGhlaWdodD0iNDYiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyMTciIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+Q2hlY2s8L3RleHQ+Cjx0ZXh0IHg9IjIxNyIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj50eXBlcyBhbmQgbGltaXRzPC90ZXh0Pgo8bGluZSB4MT0iMjcwIiB5MT0iODciIHgyPSIyOTIiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYWhzMykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSIyOTgiIHk9IjY0IiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjQ2IiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzQ4IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPlNwYW5uZXIgY2FsbDwvdGV4dD4KPHRleHQgeD0iMzQ4IiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPlNRTCBvciBtdXRhdGlvbnM8L3RleHQ+Cjx0ZXh0IHg9IjIxMiIgeT0iMTQwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cmVhZHM6IG9uZSBHb29nbGVTUUwgc3RhdGVtZW50IMK3IHdyaXRlczogbXV0YXRpb25zPC90ZXh0Pgo8bGluZSB4MT0iNDEyIiB5MT0iODciIHgyPSI0NTIiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYWhzMikiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSI0NTgiIHk9IjQwIiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjE0MCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ3NCIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5HT09HTEUgQ0xPVUQgU1BBTk5FUjwvdGV4dD4KPHJlY3QgeD0iNDc2IiB5PSI2NCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI0NCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjU1MSIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5TcGFubmVyIHRhYmxlPC90ZXh0Pgo8dGV4dCB4PSI1NTEiIHk9Ijk5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b25lIHBlciBEeW5hbW9EQiB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iNjQyIiB5PSI2NCIgd2lkdGg9IjE2MiIgaGVpZ2h0PSI0NCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjcyMyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5TZWNvbmRhcnkgaW5kZXhlczwvdGV4dD4KPHRleHQgeD0iNzIzIiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm9uZSBwZXIgZGVjbGFyZWQgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjYzOSIgeT0iMTQwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b25lIGRhdGFiYXNlIGZvciB0aGUgc3RhY2s8L3RleHQ+Cjwvc3ZnPg==)

![How a request is carried out: the adapter checks each DynamoDB request and turns it into Spanner work. A read runs as one GoogleSQL statement and a write commits as Spanner mutations. Spanner holds one database with one table per DynamoDB table and a secondary index per declared index.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJIb3cgYSByZXF1ZXN0IGlzIGNhcnJpZWQgb3V0OiB0aGUgYWRhcHRlciBjaGVja3MgZWFjaCBEeW5hbW9EQiByZXF1ZXN0IGFuZCB0dXJucyBpdCBpbnRvIFNwYW5uZXIgd29yay4gQSByZWFkIHJ1bnMgYXMgb25lIEdvb2dsZVNRTCBzdGF0ZW1lbnQgYW5kIGEgd3JpdGUgY29tbWl0cyBhcyBTcGFubmVyIG11dGF0aW9ucy4gU3Bhbm5lciBob2xkcyBvbmUgZGF0YWJhc2Ugd2l0aCBvbmUgdGFibGUgcGVyIER5bmFtb0RCIHRhYmxlIGFuZCBhIHNlY29uZGFyeSBpbmRleCBwZXIgZGVjbGFyZWQgaW5kZXguIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhaHMyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI2LjUiIG1hcmtlckhlaWdodD0iNi41IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjxtYXJrZXIgaWQ9ImFoczMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDAiIHdpZHRoPSIzOTIiIGhlaWdodD0iMTQwIiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzIiIHk9IjMwIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YiI+VEhFIEFEQVBURVI8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI2NCIgd2lkdGg9IjEwNiIgaGVpZ2h0PSI0NiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjgzIiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPkR5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij55b3VyIHJlcXVlc3Q8L3RleHQ+CjxsaW5lIHgxPSIxMzYiIHkxPSI4NyIgeDI9IjE1OCIgeTI9Ijg3IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhaHMzKSIgc3R5bGU9InN0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjE2NCIgeT0iNjQiIHdpZHRoPSIxMDYiIGhlaWdodD0iNDYiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyMTciIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+Q2hlY2s8L3RleHQ+Cjx0ZXh0IHg9IjIxNyIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij50eXBlcyBhbmQgbGltaXRzPC90ZXh0Pgo8bGluZSB4MT0iMjcwIiB5MT0iODciIHgyPSIyOTIiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYWhzMykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSIyOTgiIHk9IjY0IiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjQ2IiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzQ4IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPlNwYW5uZXIgY2FsbDwvdGV4dD4KPHRleHQgeD0iMzQ4IiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPlNRTCBvciBtdXRhdGlvbnM8L3RleHQ+Cjx0ZXh0IHg9IjIxMiIgeT0iMTQwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cmVhZHM6IG9uZSBHb29nbGVTUUwgc3RhdGVtZW50IMK3IHdyaXRlczogbXV0YXRpb25zPC90ZXh0Pgo8bGluZSB4MT0iNDEyIiB5MT0iODciIHgyPSI0NTIiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYWhzMikiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSI0NTgiIHk9IjQwIiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjE0MCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ3NCIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5HT09HTEUgQ0xPVUQgU1BBTk5FUjwvdGV4dD4KPHJlY3QgeD0iNDc2IiB5PSI2NCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI0NCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjU1MSIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5TcGFubmVyIHRhYmxlPC90ZXh0Pgo8dGV4dCB4PSI1NTEiIHk9Ijk5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b25lIHBlciBEeW5hbW9EQiB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iNjQyIiB5PSI2NCIgd2lkdGg9IjE2MiIgaGVpZ2h0PSI0NCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjcyMyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5TZWNvbmRhcnkgaW5kZXhlczwvdGV4dD4KPHRleHQgeD0iNzIzIiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm9uZSBwZXIgZGVjbGFyZWQgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjYzOSIgeT0iMTQwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b25lIGRhdGFiYXNlIGZvciB0aGUgc3RhY2s8L3RleHQ+Cjwvc3ZnPg==)

Spanner runs each query's key condition, filter, ordering and limit itself, as one SQL statement.

#### Rows and keys

Each DynamoDB table becomes a Spanner table. An item is one row, keyed first by its partition key and then by its sort key. Spanner can therefore read a key range in order, and `ScanIndexForward` and paging work through the key.

Attribute values keep their DynamoDB types. Numbers keep their full decimal precision, binary stays binary, and strings and sets keep the distinctions the API requires.

The adapter stores numbers as decimal text that sorts correctly and stores sets in a consistent order. Spanner can then evaluate supported comparisons in GoogleSQL without converting numbers to floating point.

A local secondary index is interleaved with its table, so its entries are stored next to the row they describe. If a table declares a TTL attribute, a generated column holds the expiry time and a Spanner row-deletion policy deletes expired rows. Expired items are physically deleted on Spanner's schedule; the adapter does not hide them on read.

![A DynamoDB item becomes a Spanner row whose primary key is the partition key then the sort key, so a Query over a key range reads one contiguous range of rows.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjIwIiB2aWV3Qm94PSIwIDAgODM2IDIyMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0gYmVjb21lcyBhIFNwYW5uZXIgcm93IHdob3NlIHByaW1hcnkga2V5IGlzIHRoZSBwYXJ0aXRpb24ga2V5IHRoZW4gdGhlIHNvcnQga2V5LCBzbyBhIFF1ZXJ5IG92ZXIgYSBrZXkgcmFuZ2UgcmVhZHMgb25lIGNvbnRpZ3VvdXMgcmFuZ2Ugb2Ygcm93cy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0ic3JvdyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojMDQ3ODU3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8cmVjdCB4PSIyMCIgeT0iMzQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMTIwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjExOCIgeT0iNTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5EeW5hbW9EQiBpdGVtPC90ZXh0Pgo8dGV4dCB4PSIzNiIgeT0iODAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1Ij5wayA9ICJjdXN0IzciPC90ZXh0Pgo8dGV4dCB4PSIzNiIgeT0iOTgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1Ij5zayA9ICIyMDI2LTA5LTA5IjwvdGV4dD4KPHRleHQgeD0iMzYiIHk9IjExNiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTUiPnRvdGFsID0gMTIzLjQ1PC90ZXh0Pgo8dGV4dCB4PSIzNiIgeT0iMTM0IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NSI+dGFncyA9IFNTWyJhIiwiYiJdPC90ZXh0Pgo8bGluZSB4MT0iMjE2IiB5MT0iOTQiIHgyPSIyNjIiIHkyPSI5NCIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3Nyb3cpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iMjY4IiB5PSIyNiIgd2lkdGg9IjMzMCIgaGVpZ2h0PSIxMzYiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNDMzIiB5PSI0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPm9uZSBTcGFubmVyIHJvdzwvdGV4dD4KPHJlY3QgeD0iMjg2IiB5PSI2MCIgd2lkdGg9IjI5NCIgaGVpZ2h0PSIzNCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjQzMyIgeT0iNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1Ij5QUklNQVJZIEtFWSAocGssIHNrKTwvdGV4dD4KPHRleHQgeD0iNDMzIiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPlBhcnRpdGlvbiBrZXkgKyBzb3J0IGtleTwvdGV4dD4KPHRleHQgeD0iNDMzIiB5PSIxMTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnRvdGFsOiBzb3J0YWJsZSBkZWNpbWFsIHRleHQ8L3RleHQ+Cjx0ZXh0IHg9IjQzMyIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5TZXRzIG5vcm1hbGl6ZWQ7IGJpbmFyeSBwcmVzZXJ2ZWQ8L3RleHQ+CjxsaW5lIHgxPSI1OTgiIHkxPSI5NCIgeDI9IjY0NCIgeTI9Ijk0IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjc3JvdykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSI2NTAiIHk9IjU2IiB3aWR0aD0iMTY2IiBoZWlnaHQ9Ijc2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjczMyIgeT0iNzkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+a2V5LXJhbmdlIFF1ZXJ5PC90ZXh0Pgo8dGV4dCB4PSI3MzMiIHk9Ijk3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cmVhZHMgb25lIGNvbnRpZ3VvdXM8L3RleHQ+Cjx0ZXh0IHg9IjczMyIgeT0iMTEzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cmFuZ2Ugb2Ygcm93czwvdGV4dD4KPHRleHQgeD0iNDMzIiB5PSIxOTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5QYXJ0aXRpb24gYW5kIHNvcnQga2V5cyBiZWNvbWUgdGhlIHJvdyBrZXk8L3RleHQ+Cjwvc3ZnPg==)

![A DynamoDB item becomes a Spanner row whose primary key is the partition key then the sort key, so a Query over a key range reads one contiguous range of rows.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjIwIiB2aWV3Qm94PSIwIDAgODM2IDIyMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0gYmVjb21lcyBhIFNwYW5uZXIgcm93IHdob3NlIHByaW1hcnkga2V5IGlzIHRoZSBwYXJ0aXRpb24ga2V5IHRoZW4gdGhlIHNvcnQga2V5LCBzbyBhIFF1ZXJ5IG92ZXIgYSBrZXkgcmFuZ2UgcmVhZHMgb25lIGNvbnRpZ3VvdXMgcmFuZ2Ugb2Ygcm93cy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0ic3JvdyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNmVlN2I3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8cmVjdCB4PSIyMCIgeT0iMzQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMTIwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjExOCIgeT0iNTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5EeW5hbW9EQiBpdGVtPC90ZXh0Pgo8dGV4dCB4PSIzNiIgeT0iODAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxIj5wayA9ICJjdXN0IzciPC90ZXh0Pgo8dGV4dCB4PSIzNiIgeT0iOTgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxIj5zayA9ICIyMDI2LTA5LTA5IjwvdGV4dD4KPHRleHQgeD0iMzYiIHk9IjExNiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTEiPnRvdGFsID0gMTIzLjQ1PC90ZXh0Pgo8dGV4dCB4PSIzNiIgeT0iMTM0IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMSI+dGFncyA9IFNTWyJhIiwiYiJdPC90ZXh0Pgo8bGluZSB4MT0iMjE2IiB5MT0iOTQiIHgyPSIyNjIiIHkyPSI5NCIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3Nyb3cpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iMjY4IiB5PSIyNiIgd2lkdGg9IjMzMCIgaGVpZ2h0PSIxMzYiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNDMzIiB5PSI0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPm9uZSBTcGFubmVyIHJvdzwvdGV4dD4KPHJlY3QgeD0iMjg2IiB5PSI2MCIgd2lkdGg9IjI5NCIgaGVpZ2h0PSIzNCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQzMyIgeT0iNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxIj5QUklNQVJZIEtFWSAocGssIHNrKTwvdGV4dD4KPHRleHQgeD0iNDMzIiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPlBhcnRpdGlvbiBrZXkgKyBzb3J0IGtleTwvdGV4dD4KPHRleHQgeD0iNDMzIiB5PSIxMTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnRvdGFsOiBzb3J0YWJsZSBkZWNpbWFsIHRleHQ8L3RleHQ+Cjx0ZXh0IHg9IjQzMyIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5TZXRzIG5vcm1hbGl6ZWQ7IGJpbmFyeSBwcmVzZXJ2ZWQ8L3RleHQ+CjxsaW5lIHgxPSI1OTgiIHkxPSI5NCIgeDI9IjY0NCIgeTI9Ijk0IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjc3JvdykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSI2NTAiIHk9IjU2IiB3aWR0aD0iMTY2IiBoZWlnaHQ9Ijc2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjczMyIgeT0iNzkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+a2V5LXJhbmdlIFF1ZXJ5PC90ZXh0Pgo8dGV4dCB4PSI3MzMiIHk9Ijk3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cmVhZHMgb25lIGNvbnRpZ3VvdXM8L3RleHQ+Cjx0ZXh0IHg9IjczMyIgeT0iMTEzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cmFuZ2Ugb2Ygcm93czwvdGV4dD4KPHRleHQgeD0iNDMzIiB5PSIxOTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5QYXJ0aXRpb24gYW5kIHNvcnQga2V5cyBiZWNvbWUgdGhlIHJvdyBrZXk8L3RleHQ+Cjwvc3ZnPg==)

Partition and sort keys form the Spanner primary key, which supports ordered range reads.

#### Transactions and consistency

`TransactWriteItems` runs as one Spanner read-write transaction, across tables and partition keys. Spanner's external consistency also orders transactions in real time. The adapter enforces DynamoDB's 100-action limit, one operation per item and the `ClientRequestToken` idempotency window.

The adapter reads and locks the items whose conditions or changes need their current values, checks the conditions, then commits. A failed condition and a conflict with another transaction return different errors, so the client can decide whether to retry. If the request asks for the failed item, it comes back with the condition error.

An unconditional `Put` can skip reading the item because it supplies the whole replacement. Conditions, returned old values, updates computed from existing attributes and the size check on a delete all need the existing item to be read.

DynamoDB's limits apply, not Spanner's. Each resulting item must fit DynamoDB's 400 KiB item limit, and the whole transaction must fit DynamoDB's 4 MiB limit on total item data. A request over either limit fails the way it fails on AWS.

Normal reads are strongly consistent, including requests with `ConsistentRead=false`; that flag does not select a cheaper or faster read. Strongly consistent reads on a global secondary index are still rejected, as on DynamoDB.

![One TransactWriteItems becomes one Spanner transaction. Conditional actions read the current items before their conditions are checked; an unconditional put can skip the read. All writes commit together.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjE0IiB2aWV3Qm94PSIwIDAgODM2IDIxNCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbmUgVHJhbnNhY3RXcml0ZUl0ZW1zIGJlY29tZXMgb25lIFNwYW5uZXIgdHJhbnNhY3Rpb24uIENvbmRpdGlvbmFsIGFjdGlvbnMgcmVhZCB0aGUgY3VycmVudCBpdGVtcyBiZWZvcmUgdGhlaXIgY29uZGl0aW9ucyBhcmUgY2hlY2tlZDsgYW4gdW5jb25kaXRpb25hbCBwdXQgY2FuIHNraXAgdGhlIHJlYWQuIEFsbCB3cml0ZXMgY29tbWl0IHRvZ2V0aGVyLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJzdHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzA0Nzg1NyIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjAiIHk9IjY2IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijk1IiB5PSI5MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlRyYW5zYWN0V3JpdGVJdGVtczwvdGV4dD4KPHRleHQgeD0iOTUiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPjIgaXRlbXMsIDIgdGFibGVzPC90ZXh0Pgo8bGluZSB4MT0iMTcwIiB5MT0iOTciIHgyPSIyMTYiIHkyPSI5NyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3N0eCkiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSIyMjIiIHk9IjI2IiB3aWR0aD0iMzM2IiBoZWlnaHQ9IjE0NiIgcng9IjEzIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzOTAiIHk9IjQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+b25lIFNwYW5uZXIgcmVhZC13cml0ZSB0cmFuc2FjdGlvbjwvdGV4dD4KPHJlY3QgeD0iMjQwIiB5PSI2MiIgd2lkdGg9IjE0MCIgaGVpZ2h0PSI0MiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjMxMCIgeT0iODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1Ij5vcmRlcnMgLyBvIzQyPC90ZXh0Pgo8dGV4dCB4PSIzMTAiIHk9Ijk1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+cmVhZCB3aGVuIG5lZWRlZDwvdGV4dD4KPHJlY3QgeD0iMzk4IiB5PSI2MiIgd2lkdGg9IjE0MiIgaGVpZ2h0PSI0MiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjQ2OSIgeT0iODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1Ij5zdG9jayAvIHNrdS03PC90ZXh0Pgo8dGV4dCB4PSI0NjkiIHk9Ijk1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+cmVhZCB3aGVuIG5lZWRlZDwvdGV4dD4KPHRleHQgeD0iMzkwIiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+ZXZhbHVhdGUgZXZlcnkgY29uZGl0aW9uPC90ZXh0Pgo8dGV4dCB4PSIzOTAiIHk9IjE0NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+dGhlbiBjb21taXQgYm90aCByb3dzLCBvciBuZWl0aGVyPC90ZXh0Pgo8bGluZSB4MT0iNTU4IiB5MT0iOTciIHgyPSI2MDQiIHkyPSI5NyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3N0eCkiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSI2MTAiIHk9IjYwIiB3aWR0aD0iMjA2IiBoZWlnaHQ9Ijc0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjcxMyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+ZXh0ZXJuYWwgY29uc2lzdGVuY3k8L3RleHQ+Cjx0ZXh0IHg9IjcxMyIgeT0iMTAxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+VHJhbnNhY3Rpb25zIGZvbGxvdzwvdGV4dD4KPHRleHQgeD0iNzEzIiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5yZWFsLXRpbWUgb3JkZXI8L3RleHQ+Cjx0ZXh0IHg9IjM5MCIgeT0iMTk2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+Q2hlY2sgY29uZGl0aW9ucywgdGhlbiBjb21taXQgdGhlIHRyYW5zYWN0aW9uPC90ZXh0Pgo8L3N2Zz4=)

![One TransactWriteItems becomes one Spanner transaction. Conditional actions read the current items before their conditions are checked; an unconditional put can skip the read. All writes commit together.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjE0IiB2aWV3Qm94PSIwIDAgODM2IDIxNCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbmUgVHJhbnNhY3RXcml0ZUl0ZW1zIGJlY29tZXMgb25lIFNwYW5uZXIgdHJhbnNhY3Rpb24uIENvbmRpdGlvbmFsIGFjdGlvbnMgcmVhZCB0aGUgY3VycmVudCBpdGVtcyBiZWZvcmUgdGhlaXIgY29uZGl0aW9ucyBhcmUgY2hlY2tlZDsgYW4gdW5jb25kaXRpb25hbCBwdXQgY2FuIHNraXAgdGhlIHJlYWQuIEFsbCB3cml0ZXMgY29tbWl0IHRvZ2V0aGVyLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJzdHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzZlZTdiNyIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjAiIHk9IjY2IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjYyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijk1IiB5PSI5MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlRyYW5zYWN0V3JpdGVJdGVtczwvdGV4dD4KPHRleHQgeD0iOTUiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPjIgaXRlbXMsIDIgdGFibGVzPC90ZXh0Pgo8bGluZSB4MT0iMTcwIiB5MT0iOTciIHgyPSIyMTYiIHkyPSI5NyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3N0eCkiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSIyMjIiIHk9IjI2IiB3aWR0aD0iMzM2IiBoZWlnaHQ9IjE0NiIgcng9IjEzIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzOTAiIHk9IjQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+b25lIFNwYW5uZXIgcmVhZC13cml0ZSB0cmFuc2FjdGlvbjwvdGV4dD4KPHJlY3QgeD0iMjQwIiB5PSI2MiIgd2lkdGg9IjE0MCIgaGVpZ2h0PSI0MiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjMxMCIgeT0iODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxIj5vcmRlcnMgLyBvIzQyPC90ZXh0Pgo8dGV4dCB4PSIzMTAiIHk9Ijk1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+cmVhZCB3aGVuIG5lZWRlZDwvdGV4dD4KPHJlY3QgeD0iMzk4IiB5PSI2MiIgd2lkdGg9IjE0MiIgaGVpZ2h0PSI0MiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ2OSIgeT0iODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxIj5zdG9jayAvIHNrdS03PC90ZXh0Pgo8dGV4dCB4PSI0NjkiIHk9Ijk1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+cmVhZCB3aGVuIG5lZWRlZDwvdGV4dD4KPHRleHQgeD0iMzkwIiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+ZXZhbHVhdGUgZXZlcnkgY29uZGl0aW9uPC90ZXh0Pgo8dGV4dCB4PSIzOTAiIHk9IjE0NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+dGhlbiBjb21taXQgYm90aCByb3dzLCBvciBuZWl0aGVyPC90ZXh0Pgo8bGluZSB4MT0iNTU4IiB5MT0iOTciIHgyPSI2MDQiIHkyPSI5NyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3N0eCkiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSI2MTAiIHk9IjYwIiB3aWR0aD0iMjA2IiBoZWlnaHQ9Ijc0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjcxMyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+ZXh0ZXJuYWwgY29uc2lzdGVuY3k8L3RleHQ+Cjx0ZXh0IHg9IjcxMyIgeT0iMTAxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+VHJhbnNhY3Rpb25zIGZvbGxvdzwvdGV4dD4KPHRleHQgeD0iNzEzIiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5yZWFsLXRpbWUgb3JkZXI8L3RleHQ+Cjx0ZXh0IHg9IjM5MCIgeT0iMTk2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+Q2hlY2sgY29uZGl0aW9ucywgdGhlbiBjb21taXQgdGhlIHRyYW5zYWN0aW9uPC90ZXh0Pgo8L3N2Zz4=)

Transactions can span tables and partition keys. External consistency preserves transaction order in real time.

#### Secondary indexes

A global secondary index becomes a Spanner secondary index, and a local secondary index becomes an index interleaved with its table. A `Query` on either looks up the index; it does not scan the table.

Spanner updates the index in the same commit as the row, so the next strongly consistent index read includes the change. On DynamoDB a GSI catches up asynchronously; an application that already tolerates that delay needs no change here.

Because the index is a real Spanner index, Spanner applies the key condition, ordering, paging and limit while it reads the index. A selective index query reads close to what it returns instead of filtering a wider read afterwards. An item missing the index's key attribute has no index entry, as in DynamoDB's sparse indexes.

Two DynamoDB rules still apply. `ConsistentRead=true` on a global secondary index is rejected, as DynamoDB rejects it. A query that asks for attributes the index does not include is rejected, instead of fetching them from the table. These return the same errors as on AWS, so code that handles them there works unchanged.

![Spanner updates the row and secondary index in one transaction. A subsequent strong index read includes the committed update.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA4IiB2aWV3Qm94PSIwIDAgODM2IDIwOCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJTcGFubmVyIHVwZGF0ZXMgdGhlIHJvdyBhbmQgc2Vjb25kYXJ5IGluZGV4IGluIG9uZSB0cmFuc2FjdGlvbi4gQSBzdWJzZXF1ZW50IHN0cm9uZyBpbmRleCByZWFkIGluY2x1ZGVzIHRoZSBjb21taXR0ZWQgdXBkYXRlLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJzaWR4IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj4KPG1hcmtlciBpZD0ic2lkeHEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzRmNDZlNSIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjIiIHk9IjQwIiB3aWR0aD0iMTQwIiBoZWlnaHQ9IjU2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjkyIiB5PSI2MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlVwZGF0ZUl0ZW08L3RleHQ+Cjx0ZXh0IHg9IjkyIiB5PSI4MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnN0YXR1cyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSIxNjIiIHkxPSI2OCIgeDI9IjIwOCIgeTI9IjY4IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjc2lkeCkiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSIyMTQiIHk9IjI2IiB3aWR0aD0iMzMwIiBoZWlnaHQ9IjEwNiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzNzkiIHk9IjQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPm9uZSB3cml0ZSwgb25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8cmVjdCB4PSIyMzAiIHk9IjU2IiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMzAyIiB5PSI3MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTUiPmJhc2Ugcm93PC90ZXh0Pgo8dGV4dCB4PSIzMDIiIHk9Ijg4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+b3JkZXJzIC8gbyM0MjwvdGV4dD4KPHJlY3QgeD0iMzg2IiB5PSI1NiIgd2lkdGg9IjE0NCIgaGVpZ2h0PSI0MCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjQ1OCIgeT0iNzMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1Ij5zZWNvbmRhcnkgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjQ1OCIgeT0iODgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5zdGF0dXMsIGlkPC90ZXh0Pgo8dGV4dCB4PSIzNzkiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+Um93IGFuZCBpbmRleCBjb21taXQgdG9nZXRoZXI8L3RleHQ+CjxyZWN0IHg9IjU5NiIgeT0iMzQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNTYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzA2IiB5PSI1NyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlF1ZXJ5IHRoZSBHU0k8L3RleHQ+Cjx0ZXh0IHg9IjcwNiIgeT0iNzUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5zdGF0dXMgPSBTSElQUEVEPC90ZXh0Pgo8bGluZSB4MT0iNzA2IiB5MT0iOTAiIHgyPSI3MDYiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBzdHlsZT0ic3Ryb2tlOiM0ZjQ2ZTUiLz4KPGxpbmUgeDE9IjcwNiIgeTE9IjExMiIgeDI9IjU0NiIgeTI9IjExMiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjc2lkeHEpIiBzdHlsZT0ic3Ryb2tlOiM0ZjQ2ZTUiLz4KPHRleHQgeD0iNjI2IiB5PSIxMDUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM0ZjQ2ZTUiPkluZGV4IGxvb2t1cDwvdGV4dD4KPHRleHQgeD0iMzc5IiB5PSIxNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5Sb3cgYW5kIGluZGV4IHVwZGF0ZSBpbiBvbmUgdHJhbnNhY3Rpb248L3RleHQ+Cjwvc3ZnPg==)

![Spanner updates the row and secondary index in one transaction. A subsequent strong index read includes the committed update.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA4IiB2aWV3Qm94PSIwIDAgODM2IDIwOCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJTcGFubmVyIHVwZGF0ZXMgdGhlIHJvdyBhbmQgc2Vjb25kYXJ5IGluZGV4IGluIG9uZSB0cmFuc2FjdGlvbi4gQSBzdWJzZXF1ZW50IHN0cm9uZyBpbmRleCByZWFkIGluY2x1ZGVzIHRoZSBjb21taXR0ZWQgdXBkYXRlLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJzaWR4IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj4KPG1hcmtlciBpZD0ic2lkeHEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2E1YjRmYyIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjIiIHk9IjQwIiB3aWR0aD0iMTQwIiBoZWlnaHQ9IjU2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjkyIiB5PSI2MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlVwZGF0ZUl0ZW08L3RleHQ+Cjx0ZXh0IHg9IjkyIiB5PSI4MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnN0YXR1cyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSIxNjIiIHkxPSI2OCIgeDI9IjIwOCIgeTI9IjY4IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjc2lkeCkiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSIyMTQiIHk9IjI2IiB3aWR0aD0iMzMwIiBoZWlnaHQ9IjEwNiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzNzkiIHk9IjQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPm9uZSB3cml0ZSwgb25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8cmVjdCB4PSIyMzAiIHk9IjU2IiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzAyIiB5PSI3MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTEiPmJhc2Ugcm93PC90ZXh0Pgo8dGV4dCB4PSIzMDIiIHk9Ijg4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+b3JkZXJzIC8gbyM0MjwvdGV4dD4KPHJlY3QgeD0iMzg2IiB5PSI1NiIgd2lkdGg9IjE0NCIgaGVpZ2h0PSI0MCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ1OCIgeT0iNzMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxIj5zZWNvbmRhcnkgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjQ1OCIgeT0iODgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5zdGF0dXMsIGlkPC90ZXh0Pgo8dGV4dCB4PSIzNzkiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+Um93IGFuZCBpbmRleCBjb21taXQgdG9nZXRoZXI8L3RleHQ+CjxyZWN0IHg9IjU5NiIgeT0iMzQiIHdpZHRoPSIyMjAiIGhlaWdodD0iNTYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzA2IiB5PSI1NyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlF1ZXJ5IHRoZSBHU0k8L3RleHQ+Cjx0ZXh0IHg9IjcwNiIgeT0iNzUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5zdGF0dXMgPSBTSElQUEVEPC90ZXh0Pgo8bGluZSB4MT0iNzA2IiB5MT0iOTAiIHgyPSI3MDYiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBzdHlsZT0ic3Ryb2tlOiNhNWI0ZmMiLz4KPGxpbmUgeDE9IjcwNiIgeTE9IjExMiIgeDI9IjU0NiIgeTI9IjExMiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjc2lkeHEpIiBzdHlsZT0ic3Ryb2tlOiNhNWI0ZmMiLz4KPHRleHQgeD0iNjI2IiB5PSIxMDUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNhNWI0ZmMiPkluZGV4IGxvb2t1cDwvdGV4dD4KPHRleHQgeD0iMzc5IiB5PSIxNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5Sb3cgYW5kIGluZGV4IHVwZGF0ZSBpbiBvbmUgdHJhbnNhY3Rpb248L3RleHQ+Cjwvc3ZnPg==)

Spanner commits row and index updates together. A subsequent strong index read includes the update.

#### Limitations

Where DynamoDB and Spanner differ

* **Cost behaves differently: provisioned compute bills through quiet periods.** Both services charge for stored data; Spanner also charges for provisioned compute. Steady use can spread that cost, but any saving depends on workload, capacity, region and replication topology.
* **Hot items behave differently: one busy item still contends.** The adapter spreads independent keys by hashing their partition keys, but repeated updates to one item still compete. A benchmark with evenly spread keys says nothing about hot-item performance.
* **Full-item reads from a partial index are not supported.** `Select=ALL_ATTRIBUTES` on a global secondary index that does not include every attribute is rejected, instead of fetching the missing attributes from the table. The error names the index: query only the attributes it has, or declare it with all of them.
* **Scan behaves differently: it uses provisioned compute.** Paging limits the response size, but a broad scan still reads the table and competes with point reads and writes. Use a selective `Query` where you can.
* **DynamoDB Streams are not supported.** Writes to a stream-enabled table are rejected. Use another backend if the application needs a DynamoDB change log saved atomically with each write.
* **Some updates behave differently: they read the item first.** Conditions, responses that need the existing item, nested updates, arithmetic, changes to secondary-index keys and updates to tables with an LSI read the item, check and compute the change, then commit it in the same Spanner transaction. A transaction conflict can repeat that work. Eligible top-level SET and REMOVE updates skip the read, including `UPDATED_NEW` responses that follow from the assigned values.
* **Latency behaves differently by request type.** The 2026-08-31 run measured simple unconditional updates, not the extra read or conflict retries of read-then-write updates. It used 1,000 processing units in us-west1, 100,000 records and a 50/50 read/update workload. With 16 worker threads, steady median throughput was 2,403.0 operations/s through Spanner and 5,929.5 on native DynamoDB in us-west-2, over three 200,000-operation repetitions after warm-up. Spanner returned strong reads and DynamoDB eventual reads. The adapter-only run left out Cloud Adapter deployment authorization and control-plane logging. These are end-to-end results with different regions and consistency, not the adapter's own overhead, and they do not measure transactions or hot-item contention.

#### Other considerations

* **Moving from AWS.** The Spanner database starts empty, and existing DynamoDB items are not moved for you. Load them through the adapter's DynamoDB API, then validate the data and representative queries before switching application traffic. For an online migration, coordinate the backfill with ongoing writes so changes made during the copy reach Spanner before cutover.
* **Capacity planning.** Size Spanner compute in processing units. Start from the read and write rates the DynamoDB table was provisioned for, not its storage size, and expect to tune under real load. Throughput per unit depends heavily on how evenly the primary key spreads.
* **Who runs what.** Google operates Spanner, including replication, backups and failover. Tensor9 operates the adapter, which runs beside your application.
* **Authentication.** The adapter connects to Spanner with the workload's own identity through GKE Workload Identity. There is no key file and no secret to rotate.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/5be9179bb760cc12cf951e6f0a5732208b0f004d12893f3843c6690bfaa96e33-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/15448b6151da1c858ec2092fff4a0f4709cf0c6fa345454e659ddb33d1e9672a-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Target scenario | Cloud Spanner | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Spanner (one copy) | 65.70 | 65.70 |
| 0 | 0.00 | Cloud Spanner (two copies) | 65.70 | 65.70 |
| 1 | 0.33 | Cloud Spanner (one copy) | 65.70 | 65.37 |
| 1 | 0.33 | Cloud Spanner (two copies) | 65.70 | 65.37 |
| 10 | 3.29 | Cloud Spanner (one copy) | 65.70 | 62.42 |
| 10 | 3.29 | Cloud Spanner (two copies) | 65.70 | 62.42 |
| 100 | 32.85 | Cloud Spanner (one copy) | 65.70 | 32.85 |
| 100 | 32.85 | Cloud Spanner (two copies) | 65.70 | 32.85 |
| 1,000 | 328.50 | Cloud Spanner (one copy) | 131.40 | -197.10 |
| 1,000 | 328.50 | Cloud Spanner (two copies) | 131.40 | -197.10 |
| 10,000 | 3,285.00 | Cloud Spanner (one copy) | 919.80 | -2,365.20 |
| 10,000 | 3,285.00 | Cloud Spanner (two copies) | 919.80 | -2,365.20 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Spanner (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (one copy) | Representative item size | 1,024 | bytes |
| Cloud Spanner (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (one copy) | Target reads per point read | 1 | operations |
| Cloud Spanner (one copy) | Target writes per item write | 1 | operations |
| Cloud Spanner (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (one copy) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (one copy) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (one copy) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Spanner (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Spanner (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (two copies) | Representative item size | 1,024 | bytes |
| Cloud Spanner (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (two copies) | Target reads per point read | 1 | operations |
| Cloud Spanner (two copies) | Target writes per item write | 1 | operations |
| Cloud Spanner (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (two copies) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (two copies) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (two copies) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Spanner (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Spanner bills compute capacity in processing units (100 PU minimum and steps, 1,000 PU per node) whose price includes the three replicas of a regional configuration, plus SSD storage including all replicas. Capacity is sized from planning-peak reads and writes against Google's per-node throughput; replication is built in, so the standby selection adds no copy. Enterprise (USD 1.23) and Enterprise Plus (1.71 per node-hour) editions, dual- and multi-region configurations and per-node storage limits are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Spanner pricing: [https://cloud.google.com/spanner/pricing](https://cloud.google.com/spanner/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-610b516e23e900c58eeb455757b30a011c363c10` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Spanner pricing](https://cloud.google.com/spanner/pricing).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/c1ab7e70dcf274a35ae2207c296c4f0234c96c95dc36d6049e1f493c12b615ea-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/fde1cf40f9d532fbf958592fe737c419a2c39393206996a0bec2e34822855b2b-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Target scenario | Cloud Spanner | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Spanner (one copy) | 65.70 | 65.70 |
| 0 | 0.00 | Cloud Spanner (two copies) | 65.70 | 65.70 |
| 1 | 1.64 | Cloud Spanner (one copy) | 65.70 | 64.06 |
| 1 | 1.64 | Cloud Spanner (two copies) | 65.70 | 64.06 |
| 10 | 16.43 | Cloud Spanner (one copy) | 65.70 | 49.28 |
| 10 | 16.43 | Cloud Spanner (two copies) | 65.70 | 49.28 |
| 100 | 164.25 | Cloud Spanner (one copy) | 65.70 | -98.55 |
| 100 | 164.25 | Cloud Spanner (two copies) | 65.70 | -98.55 |
| 1,000 | 1,642.50 | Cloud Spanner (one copy) | 591.30 | -1,051.20 |
| 1,000 | 1,642.50 | Cloud Spanner (two copies) | 591.30 | -1,051.20 |
| 10,000 | 16,425.00 | Cloud Spanner (one copy) | 5,781.60 | -10,643.40 |
| 10,000 | 16,425.00 | Cloud Spanner (two copies) | 5,781.60 | -10,643.40 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Spanner (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (one copy) | Representative item size | 1,024 | bytes |
| Cloud Spanner (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (one copy) | Target reads per point read | 1 | operations |
| Cloud Spanner (one copy) | Target writes per item write | 1 | operations |
| Cloud Spanner (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (one copy) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (one copy) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (one copy) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Spanner (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Spanner (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (two copies) | Representative item size | 1,024 | bytes |
| Cloud Spanner (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (two copies) | Target reads per point read | 1 | operations |
| Cloud Spanner (two copies) | Target writes per item write | 1 | operations |
| Cloud Spanner (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (two copies) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (two copies) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (two copies) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Spanner (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Spanner bills compute capacity in processing units (100 PU minimum and steps, 1,000 PU per node) whose price includes the three replicas of a regional configuration, plus SSD storage including all replicas. Capacity is sized from planning-peak reads and writes against Google's per-node throughput; replication is built in, so the standby selection adds no copy. Enterprise (USD 1.23) and Enterprise Plus (1.71 per node-hour) editions, dual- and multi-region configurations and per-node storage limits are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Spanner pricing: [https://cloud.google.com/spanner/pricing](https://cloud.google.com/spanner/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-610b516e23e900c58eeb455757b30a011c363c10` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Spanner pricing](https://cloud.google.com/spanner/pricing).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/9444703ebc91281d5fa979aeadae58b545d0c94303b24f40953e873b9036f02e-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/853cb7b0541452ddb0c1360fae2fc55e387bf4dc82752446e97ca76b8d59d4c8-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Target scenario | Cloud Spanner | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Spanner (one copy) | 65.70 | 65.70 |
| 0 | 0.00 | Cloud Spanner (two copies) | 65.70 | 65.70 |
| 10 | 2.50 | Cloud Spanner (one copy) | 68.70 | 66.20 |
| 10 | 2.50 | Cloud Spanner (two copies) | 68.70 | 66.20 |
| 100 | 25.00 | Cloud Spanner (one copy) | 95.70 | 70.70 |
| 100 | 25.00 | Cloud Spanner (two copies) | 95.70 | 70.70 |
| 1,000 | 250.00 | Cloud Spanner (one copy) | 365.70 | 115.70 |
| 1,000 | 250.00 | Cloud Spanner (two copies) | 365.70 | 115.70 |
| 10,000 | 2,500.00 | Cloud Spanner (one copy) | 3,065.70 | 565.70 |
| 10,000 | 2,500.00 | Cloud Spanner (two copies) | 3,065.70 | 565.70 |
| 100,000 | 25,000.00 | Cloud Spanner (one copy) | 30,065.70 | 5,065.70 |
| 100,000 | 25,000.00 | Cloud Spanner (two copies) | 30,065.70 | 5,065.70 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Spanner (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (one copy) | Representative item size | 1,024 | bytes |
| Cloud Spanner (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (one copy) | Target reads per point read | 1 | operations |
| Cloud Spanner (one copy) | Target writes per item write | 1 | operations |
| Cloud Spanner (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (one copy) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (one copy) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (one copy) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Spanner (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Spanner (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (two copies) | Representative item size | 1,024 | bytes |
| Cloud Spanner (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (two copies) | Target reads per point read | 1 | operations |
| Cloud Spanner (two copies) | Target writes per item write | 1 | operations |
| Cloud Spanner (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (two copies) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (two copies) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (two copies) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Spanner (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Spanner bills compute capacity in processing units (100 PU minimum and steps, 1,000 PU per node) whose price includes the three replicas of a regional configuration, plus SSD storage including all replicas. Capacity is sized from planning-peak reads and writes against Google's per-node throughput; replication is built in, so the standby selection adds no copy. Enterprise (USD 1.23) and Enterprise Plus (1.71 per node-hour) editions, dual- and multi-region configurations and per-node storage limits are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Spanner pricing: [https://cloud.google.com/spanner/pricing](https://cloud.google.com/spanner/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-610b516e23e900c58eeb455757b30a011c363c10` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Spanner pricing](https://cloud.google.com/spanner/pricing).

**DynamoDB → Cloud Spanner: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: nodes at planning peak | 65.70 |
| Target: Target retained physical data | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent managed resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **65.70** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.3 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.9 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 65.7 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Spanner bills compute capacity in processing units (100 PU minimum and steps, 1,000 PU per node) whose price includes the three replicas of a regional configuration, plus SSD storage including all replicas. Capacity is sized from planning-peak reads and writes against Google's per-node throughput; replication is built in, so the standby selection adds no copy. Enterprise (USD 1.23) and Enterprise Plus (1.71 per node-hour) editions, dual- and multi-region configurations and per-node storage limits are not selected.

List prices read: 2026-10-22. Model: `plan-610b516e23e900c58eeb455757b30a011c363c10` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Spanner pricing](https://cloud.google.com/spanner/pricing).

### Cloud Bigtable

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| BatchGetItem / BatchWriteItem | Batch | Supported | Most usage | independent item operations, without atomicity across the batch |
| ConditionExpression | Conditional writes | Supported | Common | read-modify-write under an atomic row-version guard; conflicting writes repeat the read and condition check, up to eight attempts |
| DynamoDB Streams | Indexes + streams | Out of scope | Full surface | no DynamoDB-compatible atomic change log; Bigtable change streams are not exposed as DynamoDB Streams |
| Query (GSI / LSI) | Indexes + streams | Out of scope | Most usage | the adapter does not implement DynamoDB secondary-index behavior; native Bigtable materialized views are not exposed as GSI or LSI queries |
| Query / Scan | Reads | Supported | Common | base-table ordered row ranges with pagination and adapter-side filters; filters can read more rows than they return |
| PutItem / GetItem / DeleteItem | Single item | Supported | Common | exact DynamoDB item types; reads use a verified single-cluster route |
| UpdateItem | Single item | Partial | Common | eligible top-level SET/REMOVE avoids a read but does not enforce the aggregate 400-KiB post-image limit; conditions, returned item images and other update shapes use guarded read-modify-write, except eligible native counters |
| UpdateTimeToLive | TTL | Out of scope | Most usage | column-family garbage collection does not implement a per-item DynamoDB TTL attribute |
| CreateTable / DescribeTable / UpdateTable / DeleteTable / ListTables | Table control plane | Partial | Most usage | logical table lifecycle inside a pre-provisioned physical table; billing-mode metadata does not provision capacity, and indexes, streams and TTL are rejected |
| TransactWriteItems / TransactGetItems / ExecuteTransaction | Transactions | Out of scope | Most usage | Bigtable cannot atomically commit or snapshot multiple item rows; these requests are rejected |

#### How it works

Tensor9 runs a DynamoDB adapter beside your application in the customer's environment and sets `AWS_ENDPOINT_URL_DYNAMODB` so the AWS SDK sends its requests to the adapter over the local network. Your SDK and code stay the same. The adapter accepts DynamoDB requests and data types, returns DynamoDB responses and errors, and stores the data in Google Cloud Bigtable. It connects to Bigtable over pooled gRPC with the workload identity, so no key file is needed.

Bigtable writes are **atomic for one row, not across rows**, and each DynamoDB item is exactly one row. That is why single-item writes, including conditional ones, behave as on DynamoDB, and why multi-item transactions, secondary indexes, DynamoDB Streams and per-item TTL are rejected. The limitations below list what is missing.

![On AWS, your application's DynamoDB SDK calls Amazon DynamoDB. On Google Cloud, the same application and SDK call a Tensor9 adapter, which answers the DynamoDB API and stores the data in Cloud Bigtable.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBBV1MsIHlvdXIgYXBwbGljYXRpb24ncyBEeW5hbW9EQiBTREsgY2FsbHMgQW1hem9uIER5bmFtb0RCLiBPbiBHb29nbGUgQ2xvdWQsIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggYW5zd2VycyB0aGUgRHluYW1vREIgQVBJIGFuZCBzdG9yZXMgdGhlIGRhdGEgaW4gQ2xvdWQgQmlndGFibGUuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJidGEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0NiIgd2lkdGg9IjM1OCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIzMCIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjgwIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjkwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iOTAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkR5bmFtb0RCIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2J0YSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4LjVweCI+RHluYW1vREI8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iODAiIHdpZHRoPSIxNDgiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjg4IiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTEuNXB4Ij5BbWF6b24gRHluYW1vREI8L3RleHQ+Cjx0ZXh0IHg9IjI4OCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+QVdTLW1hbmFnZWQ8L3RleHQ+CjxsaW5lIHgxPSI0MTgiIHkxPSI0MCIgeDI9IjQxOCIgeTI9IjE2MCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6I2NiZDVlMSIvPgo8cmVjdCB4PSI0NjIiIHk9IjQ2IiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ3NiIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPk9OIEdPT0dMRSBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iNDc0IiB5PSI4MCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjUyMCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI1MjAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5zYW1lIFNESzwvdGV4dD4KPGxpbmUgeDE9IjU2NiIgeTE9IjExMyIgeDI9IjU5MCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2J0YSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSI1OTQiIHk9Ijc2IiB3aWR0aD0iMTEwIiBoZWlnaHQ9Ijc0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS43IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjY0OSIgeT0iMTAyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEycHgiPlRlbnNvcjk8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTE3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5zZXJ2aWNlPC90ZXh0Pgo8dGV4dCB4PSI2NDkiIHk9IjEzMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+YWRhcHRlcjwvdGV4dD4KPGxpbmUgeDE9IjcwNCIgeTE9IjExMyIgeDI9IjcxMiIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2J0YSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSI3MTYiIHk9IjgwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc2NiIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjExcHgiPkNsb3VkIEJpZ3RhYmxlPC90ZXh0Pgo8dGV4dCB4PSI3NjYiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnNpbmdsZS1jbHVzdGVyPC90ZXh0Pgo8L3N2Zz4=)

![On AWS, your application's DynamoDB SDK calls Amazon DynamoDB. On Google Cloud, the same application and SDK call a Tensor9 adapter, which answers the DynamoDB API and stores the data in Cloud Bigtable.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBBV1MsIHlvdXIgYXBwbGljYXRpb24ncyBEeW5hbW9EQiBTREsgY2FsbHMgQW1hem9uIER5bmFtb0RCLiBPbiBHb29nbGUgQ2xvdWQsIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggYW5zd2VycyB0aGUgRHluYW1vREIgQVBJIGFuZCBzdG9yZXMgdGhlIGRhdGEgaW4gQ2xvdWQgQmlndGFibGUuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJidGEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0NiIgd2lkdGg9IjM1OCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIzMCIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjgwIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjkwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iOTAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkR5bmFtb0RCIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2J0YSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZvbnQtc2l6ZTo4LjVweCI+RHluYW1vREI8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iODAiIHdpZHRoPSIxNDgiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjg4IiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTEuNXB4Ij5BbWF6b24gRHluYW1vREI8L3RleHQ+Cjx0ZXh0IHg9IjI4OCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+QVdTLW1hbmFnZWQ8L3RleHQ+CjxsaW5lIHgxPSI0MTgiIHkxPSI0MCIgeDI9IjQxOCIgeTI9IjE2MCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6IzQ3NTU2OSIvPgo8cmVjdCB4PSI0NjIiIHk9IjQ2IiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ3NiIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPk9OIEdPT0dMRSBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iNDc0IiB5PSI4MCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjUyMCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI1MjAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5zYW1lIFNESzwvdGV4dD4KPGxpbmUgeDE9IjU2NiIgeTE9IjExMyIgeDI9IjU5MCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2J0YSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSI1OTQiIHk9Ijc2IiB3aWR0aD0iMTEwIiBoZWlnaHQ9Ijc0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS43IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjY0OSIgeT0iMTAyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEycHgiPlRlbnNvcjk8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTE3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5zZXJ2aWNlPC90ZXh0Pgo8dGV4dCB4PSI2NDkiIHk9IjEzMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+YWRhcHRlcjwvdGV4dD4KPGxpbmUgeDE9IjcwNCIgeTE9IjExMyIgeDI9IjcxMiIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2J0YSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSI3MTYiIHk9IjgwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc2NiIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjExcHgiPkNsb3VkIEJpZ3RhYmxlPC90ZXh0Pgo8dGV4dCB4PSI3NjYiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnNpbmdsZS1jbHVzdGVyPC90ZXh0Pgo8L3N2Zz4=)

Your application keeps using the DynamoDB API; an adapter in the target environment stores the data in Bigtable.

#### Architecture

The adapter translates DynamoDB keys and operations into Bigtable row keys, row ranges and mutations. Base-table queries become ordered key ranges. DynamoDB attribute filters run in the adapter over the rows it read.

A conditional write reads the item, evaluates the DynamoDB condition and uses `CheckAndMutateRow` to write only if the item has not changed since it was read. If another writer changed it, the adapter reads and checks the condition again.

![The adapter turns each DynamoDB request into Bigtable calls: one ReadRows range for a read, or a MutateRow or CheckAndMutateRow for a write. Bigtable stores one row per item and is atomic for one row, not across rows.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciB0dXJucyBlYWNoIER5bmFtb0RCIHJlcXVlc3QgaW50byBCaWd0YWJsZSBjYWxsczogb25lIFJlYWRSb3dzIHJhbmdlIGZvciBhIHJlYWQsIG9yIGEgTXV0YXRlUm93IG9yIENoZWNrQW5kTXV0YXRlUm93IGZvciBhIHdyaXRlLiBCaWd0YWJsZSBzdG9yZXMgb25lIHJvdyBwZXIgaXRlbSBhbmQgaXMgYXRvbWljIGZvciBvbmUgcm93LCBub3QgYWNyb3NzIHJvd3MuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhYnQxIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI2LjUiIG1hcmtlckhlaWdodD0iNi41IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjxtYXJrZXIgaWQ9ImFidDIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDAiIHdpZHRoPSIzOTIiIGhlaWdodD0iMTQwIiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzIiIHk9IjMwIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiOCI+VEhFIEFEQVBURVI8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI2NCIgd2lkdGg9IjEwNiIgaGVpZ2h0PSI0NiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjgzIiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPkR5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj55b3VyIHJlcXVlc3Q8L3RleHQ+CjxsaW5lIHgxPSIxMzYiIHkxPSI4NyIgeDI9IjE1OCIgeTI9Ijg3IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhYnQyKSIgc3R5bGU9InN0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjE2NCIgeT0iNjQiIHdpZHRoPSIxMDYiIGhlaWdodD0iNDYiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyMTciIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+S2V5IGFuZCBmaWx0ZXI8L3RleHQ+Cjx0ZXh0IHg9IjIxNyIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5jaGVja2VkIGJ5IHRoZSBhZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iMjcwIiB5MT0iODciIHgyPSIyOTIiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYWJ0MikiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSIyOTgiIHk9IjY0IiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjQ2IiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzQ4IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPkJpZ3RhYmxlIGNhbGw8L3RleHQ+Cjx0ZXh0IHg9IjM0OCIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5yb3cgcmFuZ2Ugb3IgbXV0YXRpb248L3RleHQ+Cjx0ZXh0IHg9IjIxMiIgeT0iMTQwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b25lIFJlYWRSb3dzIHJhbmdlIMK3IE11dGF0ZVJvdyBvciBDaGVja0FuZE11dGF0ZVJvdzwvdGV4dD4KPGxpbmUgeDE9IjQxMiIgeTE9Ijg3IiB4Mj0iNDUyIiB5Mj0iODciIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2FidDEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNDU4IiB5PSI0MCIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxNDAiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NzQiIHk9IjMwIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiOCI+Q0xPVUQgQklHVEFCTEU8L3RleHQ+CjxyZWN0IHg9IjQ3NiIgeT0iNjQiIHdpZHRoPSIxNTAiIGhlaWdodD0iNDQiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1NTEiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+T25lIHJvdyBwZXIgaXRlbTwvdGV4dD4KPHRleHQgeD0iNTUxIiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmtleSBzb3J0cyBieSB0YWJsZSwgdGhlbiBzazwvdGV4dD4KPHJlY3QgeD0iNjQyIiB5PSI2NCIgd2lkdGg9IjE2MiIgaGVpZ2h0PSI0NCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjcyMyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5BdG9taWMgcGVyIHJvdzwvdGV4dD4KPHRleHQgeD0iNzIzIiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm5vdCBhY3Jvc3Mgcm93czwvdGV4dD4KPHRleHQgeD0iNjM5IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vbmUgaW5zdGFuY2UsIHNpbmdsZS1jbHVzdGVyIGFwcCBwcm9maWxlPC90ZXh0Pgo8L3N2Zz4=)

![The adapter turns each DynamoDB request into Bigtable calls: one ReadRows range for a read, or a MutateRow or CheckAndMutateRow for a write. Bigtable stores one row per item and is atomic for one row, not across rows.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciB0dXJucyBlYWNoIER5bmFtb0RCIHJlcXVlc3QgaW50byBCaWd0YWJsZSBjYWxsczogb25lIFJlYWRSb3dzIHJhbmdlIGZvciBhIHJlYWQsIG9yIGEgTXV0YXRlUm93IG9yIENoZWNrQW5kTXV0YXRlUm93IGZvciBhIHdyaXRlLiBCaWd0YWJsZSBzdG9yZXMgb25lIHJvdyBwZXIgaXRlbSBhbmQgaXMgYXRvbWljIGZvciBvbmUgcm93LCBub3QgYWNyb3NzIHJvd3MuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhYnQxIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI2LjUiIG1hcmtlckhlaWdodD0iNi41IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjxtYXJrZXIgaWQ9ImFidDIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjYuNSIgbWFya2VySGVpZ2h0PSI2LjUiIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDAiIHdpZHRoPSIzOTIiIGhlaWdodD0iMTQwIiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzIiIHk9IjMwIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YiI+VEhFIEFEQVBURVI8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI2NCIgd2lkdGg9IjEwNiIgaGVpZ2h0PSI0NiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjgzIiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPkR5bmFtb0RCPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij55b3VyIHJlcXVlc3Q8L3RleHQ+CjxsaW5lIHgxPSIxMzYiIHkxPSI4NyIgeDI9IjE1OCIgeTI9Ijg3IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhYnQyKSIgc3R5bGU9InN0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjE2NCIgeT0iNjQiIHdpZHRoPSIxMDYiIGhlaWdodD0iNDYiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyMTciIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+S2V5IGFuZCBmaWx0ZXI8L3RleHQ+Cjx0ZXh0IHg9IjIxNyIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5jaGVja2VkIGJ5IHRoZSBhZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iMjcwIiB5MT0iODciIHgyPSIyOTIiIHkyPSI4NyIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYWJ0MikiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSIyOTgiIHk9IjY0IiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjQ2IiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzQ4IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPkJpZ3RhYmxlIGNhbGw8L3RleHQ+Cjx0ZXh0IHg9IjM0OCIgeT0iOTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5yb3cgcmFuZ2Ugb3IgbXV0YXRpb248L3RleHQ+Cjx0ZXh0IHg9IjIxMiIgeT0iMTQwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b25lIFJlYWRSb3dzIHJhbmdlIMK3IE11dGF0ZVJvdyBvciBDaGVja0FuZE11dGF0ZVJvdzwvdGV4dD4KPGxpbmUgeDE9IjQxMiIgeTE9Ijg3IiB4Mj0iNDUyIiB5Mj0iODciIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2FidDEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNDU4IiB5PSI0MCIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxNDAiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NzQiIHk9IjMwIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YiI+Q0xPVUQgQklHVEFCTEU8L3RleHQ+CjxyZWN0IHg9IjQ3NiIgeT0iNjQiIHdpZHRoPSIxNTAiIGhlaWdodD0iNDQiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1NTEiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+T25lIHJvdyBwZXIgaXRlbTwvdGV4dD4KPHRleHQgeD0iNTUxIiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmtleSBzb3J0cyBieSB0YWJsZSwgdGhlbiBzazwvdGV4dD4KPHJlY3QgeD0iNjQyIiB5PSI2NCIgd2lkdGg9IjE2MiIgaGVpZ2h0PSI0NCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjcyMyIgeT0iODMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5BdG9taWMgcGVyIHJvdzwvdGV4dD4KPHRleHQgeD0iNzIzIiB5PSI5OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm5vdCBhY3Jvc3Mgcm93czwvdGV4dD4KPHRleHQgeD0iNjM5IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vbmUgaW5zdGFuY2UsIHNpbmdsZS1jbHVzdGVyIGFwcCBwcm9maWxlPC90ZXh0Pgo8L3N2Zz4=)

Each DynamoDB request becomes one Bigtable row-range read or one row mutation.

#### One row per item

All your DynamoDB tables live in one Bigtable table that you provision, and each item is one row in it. A metadata row records each DynamoDB table's schema, so the tables stay separate inside the shared Bigtable table.

The row key is laid out as the DynamoDB table, then the partition, then the sort key encoded in DynamoDB's own order, then an item digest. A table that is deleted and re-created gets a new key prefix, so it starts empty and cannot read the old table's rows. Because the sort key keeps DynamoDB's order, one partition is one **contiguous** Bigtable range, and a `Query` over a key range is a range read in the right order rather than a filter over unrelated rows.

Item data is stored in a plain column family, `d`. A second family, `n`, is an INT64 SUM aggregate, so Bigtable itself can add to an integer counter in one round trip instead of the adapter reading, adding and writing back. See the next section.

![Each DynamoDB item is one Bigtable row. Its row key is the table, the partition, the sort key in DynamoDB order and an item digest, so one DynamoDB partition is one contiguous Bigtable range in sort-key order.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA4IiB2aWV3Qm94PSIwIDAgODM2IDIwOCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFYWNoIER5bmFtb0RCIGl0ZW0gaXMgb25lIEJpZ3RhYmxlIHJvdy4gSXRzIHJvdyBrZXkgaXMgdGhlIHRhYmxlLCB0aGUgcGFydGl0aW9uLCB0aGUgc29ydCBrZXkgaW4gRHluYW1vREIgb3JkZXIgYW5kIGFuIGl0ZW0gZGlnZXN0LCBzbyBvbmUgRHluYW1vREIgcGFydGl0aW9uIGlzIG9uZSBjb250aWd1b3VzIEJpZ3RhYmxlIHJhbmdlIGluIHNvcnQta2V5IG9yZGVyLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJidHIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzA0Nzg1NyIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjAiIHk9IjM0IiB3aWR0aD0iMTgwIiBoZWlnaHQ9IjEwNCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIxMTAiIHk9IjU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEyLjVweCI+RHluYW1vREIgaXRlbTwvdGV4dD4KPHRleHQgeD0iMzQiIHk9IjgwIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NSI+cGsgPSAiY3VzdCM3IjwvdGV4dD4KPHRleHQgeD0iMzQiIHk9Ijk4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NSI+c2sgPSAiMjAyNi0wOS0wOSI8L3RleHQ+Cjx0ZXh0IHg9IjM0IiB5PSIxMTYiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1Ij50b3RhbCA9IDEyMy40NTwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9Ijg2IiB4Mj0iMjQ2IiB5Mj0iODYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNidHIpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iMjUyIiB5PSIyNiIgd2lkdGg9IjM2OCIgaGVpZ2h0PSIxMjAiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNDM2IiB5PSI0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPm9uZSBCaWd0YWJsZSByb3c8L3RleHQ+CjxyZWN0IHg9IjI2OCIgeT0iNjAiIHdpZHRoPSIzMzYiIGhlaWdodD0iMzQiIHJ4PSI4IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2E3ZjNkMCIvPgo8dGV4dCB4PSI0MzYiIHk9Ijc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZm9udC1zaXplOjEwLjVweCI+dGFibGUgfCByb3V0ZSB8IGNvbGxhdGVkIHNvcnQga2V5IHwgZGlnZXN0PC90ZXh0Pgo8dGV4dCB4PSI0MzYiIHk9Ijg4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+bmV3IHByZWZpeCBwZXIgcmUtY3JlYXRlPC90ZXh0Pgo8dGV4dCB4PSI0MzYiIHk9IjExNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+cmF3IGZhbWlseSBkIGZvciBpdGVtIGRhdGE8L3RleHQ+Cjx0ZXh0IHg9IjQzNiIgeT0iMTMyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5JTlQ2NCBTVU0gZmFtaWx5IG4gZm9yIGNvdW50ZXJzPC90ZXh0Pgo8bGluZSB4MT0iNjIwIiB5MT0iODYiIHgyPSI2NjYiIHkyPSI4NiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2J0cikiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSI2NzIiIHk9IjQ4IiB3aWR0aD0iMTQ2IiBoZWlnaHQ9Ijc2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc0NSIgeT0iNzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+b25lIHBhcnRpdGlvbiA9PC90ZXh0Pgo8dGV4dCB4PSI3NDUiIHk9Ijg5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+b25lIGNvbnRpZ3VvdXMgcmFuZ2UsPC90ZXh0Pgo8dGV4dCB4PSI3NDUiIHk9IjEwNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmluIHNvcnQta2V5IG9yZGVyPC90ZXh0Pgo8dGV4dCB4PSI0MzYiIHk9IjE4NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjgiPkVWRVJZIExPR0lDQUwgVEFCTEUgU0hBUkVTIE9ORSBQUk9WSVNJT05FRCBCSUdUQUJMRSBUQUJMRTwvdGV4dD4KPC9zdmc+)

![Each DynamoDB item is one Bigtable row. Its row key is the table, the partition, the sort key in DynamoDB order and an item digest, so one DynamoDB partition is one contiguous Bigtable range in sort-key order.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA4IiB2aWV3Qm94PSIwIDAgODM2IDIwOCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFYWNoIER5bmFtb0RCIGl0ZW0gaXMgb25lIEJpZ3RhYmxlIHJvdy4gSXRzIHJvdyBrZXkgaXMgdGhlIHRhYmxlLCB0aGUgcGFydGl0aW9uLCB0aGUgc29ydCBrZXkgaW4gRHluYW1vREIgb3JkZXIgYW5kIGFuIGl0ZW0gZGlnZXN0LCBzbyBvbmUgRHluYW1vREIgcGFydGl0aW9uIGlzIG9uZSBjb250aWd1b3VzIEJpZ3RhYmxlIHJhbmdlIGluIHNvcnQta2V5IG9yZGVyLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJidHIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzZlZTdiNyIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjAiIHk9IjM0IiB3aWR0aD0iMTgwIiBoZWlnaHQ9IjEwNCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIxMTAiIHk9IjU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEyLjVweCI+RHluYW1vREIgaXRlbTwvdGV4dD4KPHRleHQgeD0iMzQiIHk9IjgwIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMSI+cGsgPSAiY3VzdCM3IjwvdGV4dD4KPHRleHQgeD0iMzQiIHk9Ijk4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMSI+c2sgPSAiMjAyNi0wOS0wOSI8L3RleHQ+Cjx0ZXh0IHg9IjM0IiB5PSIxMTYiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxIj50b3RhbCA9IDEyMy40NTwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9Ijg2IiB4Mj0iMjQ2IiB5Mj0iODYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNidHIpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iMjUyIiB5PSIyNiIgd2lkdGg9IjM2OCIgaGVpZ2h0PSIxMjAiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNDM2IiB5PSI0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPm9uZSBCaWd0YWJsZSByb3c8L3RleHQ+CjxyZWN0IHg9IjI2OCIgeT0iNjAiIHdpZHRoPSIzMzYiIGhlaWdodD0iMzQiIHJ4PSI4IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0MzYiIHk9Ijc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZm9udC1zaXplOjEwLjVweCI+dGFibGUgfCByb3V0ZSB8IGNvbGxhdGVkIHNvcnQga2V5IHwgZGlnZXN0PC90ZXh0Pgo8dGV4dCB4PSI0MzYiIHk9Ijg4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+bmV3IHByZWZpeCBwZXIgcmUtY3JlYXRlPC90ZXh0Pgo8dGV4dCB4PSI0MzYiIHk9IjExNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+cmF3IGZhbWlseSBkIGZvciBpdGVtIGRhdGE8L3RleHQ+Cjx0ZXh0IHg9IjQzNiIgeT0iMTMyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5JTlQ2NCBTVU0gZmFtaWx5IG4gZm9yIGNvdW50ZXJzPC90ZXh0Pgo8bGluZSB4MT0iNjIwIiB5MT0iODYiIHgyPSI2NjYiIHkyPSI4NiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2J0cikiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSI2NzIiIHk9IjQ4IiB3aWR0aD0iMTQ2IiBoZWlnaHQ9Ijc2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc0NSIgeT0iNzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+b25lIHBhcnRpdGlvbiA9PC90ZXh0Pgo8dGV4dCB4PSI3NDUiIHk9Ijg5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+b25lIGNvbnRpZ3VvdXMgcmFuZ2UsPC90ZXh0Pgo8dGV4dCB4PSI3NDUiIHk9IjEwNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmluIHNvcnQta2V5IG9yZGVyPC90ZXh0Pgo8dGV4dCB4PSI0MzYiIHk9IjE4NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGIiPkVWRVJZIExPR0lDQUwgVEFCTEUgU0hBUkVTIE9ORSBQUk9WSVNJT05FRCBCSUdUQUJMRSBUQUJMRTwvdGV4dD4KPC9zdmc+)

The row key is built so a DynamoDB partition is one contiguous Bigtable range, in the origin's sort order.

#### Writes and atomicity

An unconditional `PutItem` or `DeleteItem`, and an `UpdateItem` with only top-level SET/REMOVE, is a single `MutateRow`: one round trip, with no read of the old item. A single integer `ADD`, or a SET computed from the attribute's own value, uses the INT64 SUM cell, so Bigtable does the addition in one call.

Conditions, returned item values, nested changes and other arithmetic need a read. The adapter computes the change and writes it with `CheckAndMutateRow` only if the item's version cell is unchanged. On a conflict it repeats the read and condition check, up to eight attempts.

Every write is atomic for one item and linearizable because the app profile routes to a single cluster. Multi-cluster routing would break that, so at startup, before it accepts any requests, the adapter checks through the Bigtable Admin API that the app profile uses single-cluster routing with transactional writes allowed and that both column families exist as expected. A misconfiguration stops the adapter instead of showing up under load.

A top-level SET/REMOVE that skips the read cannot check the size of the item it produces, so DynamoDB's 400 KiB item limit is not enforced on that path. If your application depends on that limit being enforced exactly, use a backend that reads before writing.

![There are three write paths. An unconditional write is one MutateRow. An integer counter addition uses the aggregate cell in one call. Everything else reads the item and writes it with CheckAndMutateRow only if its version is unchanged.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjMwIiB2aWV3Qm94PSIwIDAgODM2IDIzMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGVyZSBhcmUgdGhyZWUgd3JpdGUgcGF0aHMuIEFuIHVuY29uZGl0aW9uYWwgd3JpdGUgaXMgb25lIE11dGF0ZVJvdy4gQW4gaW50ZWdlciBjb3VudGVyIGFkZGl0aW9uIHVzZXMgdGhlIGFnZ3JlZ2F0ZSBjZWxsIGluIG9uZSBjYWxsLiBFdmVyeXRoaW5nIGVsc2UgcmVhZHMgdGhlIGl0ZW0gYW5kIHdyaXRlcyBpdCB3aXRoIENoZWNrQW5kTXV0YXRlUm93IG9ubHkgaWYgaXRzIHZlcnNpb24gaXMgdW5jaGFuZ2VkLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJidHciIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzA0Nzg1NyIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJidHcyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiNiNDUzMDkiLz48L21hcmtlcj48L2RlZnM+CjxyZWN0IHg9IjIwIiB5PSIzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIxMTgiIHk9IjQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPnVuY29uZGl0aW9uYWwgd3JpdGU8L3RleHQ+Cjx0ZXh0IHg9IjExOCIgeT0iNjUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5QdXQsIERlbGV0ZSwgdG9wLWxldmVsIFNFVC9SRU1PVkU8L3RleHQ+CjxsaW5lIHgxPSIyMTYiIHkxPSI1MiIgeDI9IjI4NiIgeTI9IjUyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYnR3KSIgc3R5bGU9InN0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjI5MiIgeT0iMzAiIHdpZHRoPSIxODAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzgyIiB5PSI1MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMnB4Ij5NdXRhdGVSb3c8L3RleHQ+Cjx0ZXh0IHg9IjM4MiIgeT0iNjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPm9uZSBSUEMsIG5vIHJlYWQ8L3RleHQ+CjxyZWN0IHg9IjIwIiB5PSI5MiIgd2lkdGg9IjE5NiIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIxMTgiIHk9IjExMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5pbnRlZ3JhbCBjb3VudGVyIEFERDwvdGV4dD4KPHRleHQgeD0iMTE4IiB5PSIxMjciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vciBzZWxmLWFyaXRobWV0aWMgU0VUPC90ZXh0Pgo8bGluZSB4MT0iMjE2IiB5MT0iMTE0IiB4Mj0iMjg2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYnR3KSIgc3R5bGU9InN0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjI5MiIgeT0iOTIiIHdpZHRoPSIxODAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzgyIiB5PSIxMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTJweCI+YWdncmVnYXRlIGNlbGw8L3RleHQ+Cjx0ZXh0IHg9IjM4MiIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5CaWd0YWJsZSBzdW1zIGl0LCBvbmUgUlBDPC90ZXh0Pgo8cmVjdCB4PSIyMCIgeT0iMTU0IiB3aWR0aD0iMTk2IiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjExOCIgeT0iMTczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPmV2ZXJ5dGhpbmcgZWxzZTwvdGV4dD4KPHRleHQgeD0iMTE4IiB5PSIxODkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5jb25kaXRpb25zLCByZXR1cm4gaW1hZ2VzLDwvdGV4dD4KPHRleHQgeD0iMTE4IiB5PSIyMDEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5uZXN0ZWQgb3IgYXJpdGhtZXRpYyB1cGRhdGVzPC90ZXh0Pgo8bGluZSB4MT0iMjE2IiB5MT0iMTc4IiB4Mj0iMjg2IiB5Mj0iMTc4IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYnR3MikiIHN0eWxlPSJzdHJva2U6I2I0NTMwOSIvPgo8cmVjdCB4PSIyOTIiIHk9IjE1MCIgd2lkdGg9IjE4MCIgaGVpZ2h0PSI1NiIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmJlYjtzdHJva2U6I2I0NTMwOSIvPgo8dGV4dCB4PSIzODIiIHk9IjE3MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4O2ZpbGw6I2I0NTMwOSI+cmVhZCwgdGhlbjwvdGV4dD4KPHRleHQgeD0iMzgyIiB5PSIxODYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweDtmaWxsOiNiNDUzMDkiPkNoZWNrQW5kTXV0YXRlUm93PC90ZXh0Pgo8dGV4dCB4PSIzODIiIHk9IjIwMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmd1YXJkZWQgYnkgYSB2ZXJzaW9uIGNlbGw8L3RleHQ+CjxyZWN0IHg9IjUwMCIgeT0iNjYiIHdpZHRoPSIzMTYiIGhlaWdodD0iOTgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjU4IiB5PSI5MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5hdG9taWMgZm9yIE9ORSByb3c8L3RleHQ+Cjx0ZXh0IHg9IjY1OCIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+YW5kIGxpbmVhcml6YWJsZSwgYmVjYXVzZSB0aGUgYXBwIHByb2ZpbGU8L3RleHQ+Cjx0ZXh0IHg9IjY1OCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cm91dGVzIHRvIGEgc2luZ2xlIGNsdXN0ZXIuIHZlcmlmaWVkIHRocm91Z2g8L3RleHQ+Cjx0ZXh0IHg9IjY1OCIgeT0iMTQ0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dGhlIEFkbWluIEFQSSBhdCBzdGFydHVwPC90ZXh0Pgo8L3N2Zz4=)

![There are three write paths. An unconditional write is one MutateRow. An integer counter addition uses the aggregate cell in one call. Everything else reads the item and writes it with CheckAndMutateRow only if its version is unchanged.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjMwIiB2aWV3Qm94PSIwIDAgODM2IDIzMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGVyZSBhcmUgdGhyZWUgd3JpdGUgcGF0aHMuIEFuIHVuY29uZGl0aW9uYWwgd3JpdGUgaXMgb25lIE11dGF0ZVJvdy4gQW4gaW50ZWdlciBjb3VudGVyIGFkZGl0aW9uIHVzZXMgdGhlIGFnZ3JlZ2F0ZSBjZWxsIGluIG9uZSBjYWxsLiBFdmVyeXRoaW5nIGVsc2UgcmVhZHMgdGhlIGl0ZW0gYW5kIHdyaXRlcyBpdCB3aXRoIENoZWNrQW5kTXV0YXRlUm93IG9ubHkgaWYgaXRzIHZlcnNpb24gaXMgdW5jaGFuZ2VkLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJidHciIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzZlZTdiNyIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJidHcyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiNmYmJmMjQiLz48L21hcmtlcj48L2RlZnM+CjxyZWN0IHg9IjIwIiB5PSIzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIxMTgiIHk9IjQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPnVuY29uZGl0aW9uYWwgd3JpdGU8L3RleHQ+Cjx0ZXh0IHg9IjExOCIgeT0iNjUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5QdXQsIERlbGV0ZSwgdG9wLWxldmVsIFNFVC9SRU1PVkU8L3RleHQ+CjxsaW5lIHgxPSIyMTYiIHkxPSI1MiIgeDI9IjI4NiIgeTI9IjUyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYnR3KSIgc3R5bGU9InN0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjI5MiIgeT0iMzAiIHdpZHRoPSIxODAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzgyIiB5PSI1MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMnB4Ij5NdXRhdGVSb3c8L3RleHQ+Cjx0ZXh0IHg9IjM4MiIgeT0iNjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPm9uZSBSUEMsIG5vIHJlYWQ8L3RleHQ+CjxyZWN0IHg9IjIwIiB5PSI5MiIgd2lkdGg9IjE5NiIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIxMTgiIHk9IjExMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5pbnRlZ3JhbCBjb3VudGVyIEFERDwvdGV4dD4KPHRleHQgeD0iMTE4IiB5PSIxMjciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vciBzZWxmLWFyaXRobWV0aWMgU0VUPC90ZXh0Pgo8bGluZSB4MT0iMjE2IiB5MT0iMTE0IiB4Mj0iMjg2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYnR3KSIgc3R5bGU9InN0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjI5MiIgeT0iOTIiIHdpZHRoPSIxODAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzgyIiB5PSIxMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTJweCI+YWdncmVnYXRlIGNlbGw8L3RleHQ+Cjx0ZXh0IHg9IjM4MiIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5CaWd0YWJsZSBzdW1zIGl0LCBvbmUgUlBDPC90ZXh0Pgo8cmVjdCB4PSIyMCIgeT0iMTU0IiB3aWR0aD0iMTk2IiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjExOCIgeT0iMTczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPmV2ZXJ5dGhpbmcgZWxzZTwvdGV4dD4KPHRleHQgeD0iMTE4IiB5PSIxODkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5jb25kaXRpb25zLCByZXR1cm4gaW1hZ2VzLDwvdGV4dD4KPHRleHQgeD0iMTE4IiB5PSIyMDEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5uZXN0ZWQgb3IgYXJpdGhtZXRpYyB1cGRhdGVzPC90ZXh0Pgo8bGluZSB4MT0iMjE2IiB5MT0iMTc4IiB4Mj0iMjg2IiB5Mj0iMTc4IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYnR3MikiIHN0eWxlPSJzdHJva2U6I2ZiYmYyNCIvPgo8cmVjdCB4PSIyOTIiIHk9IjE1MCIgd2lkdGg9IjE4MCIgaGVpZ2h0PSI1NiIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzQyMjAwNjtzdHJva2U6I2ZiYmYyNCIvPgo8dGV4dCB4PSIzODIiIHk9IjE3MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4O2ZpbGw6I2ZiYmYyNCI+cmVhZCwgdGhlbjwvdGV4dD4KPHRleHQgeD0iMzgyIiB5PSIxODYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTJweDtmaWxsOiNmYmJmMjQiPkNoZWNrQW5kTXV0YXRlUm93PC90ZXh0Pgo8dGV4dCB4PSIzODIiIHk9IjIwMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmd1YXJkZWQgYnkgYSB2ZXJzaW9uIGNlbGw8L3RleHQ+CjxyZWN0IHg9IjUwMCIgeT0iNjYiIHdpZHRoPSIzMTYiIGhlaWdodD0iOTgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjU4IiB5PSI5MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5hdG9taWMgZm9yIE9ORSByb3c8L3RleHQ+Cjx0ZXh0IHg9IjY1OCIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+YW5kIGxpbmVhcml6YWJsZSwgYmVjYXVzZSB0aGUgYXBwIHByb2ZpbGU8L3RleHQ+Cjx0ZXh0IHg9IjY1OCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cm91dGVzIHRvIGEgc2luZ2xlIGNsdXN0ZXIuIHZlcmlmaWVkIHRocm91Z2g8L3RleHQ+Cjx0ZXh0IHg9IjY1OCIgeT0iMTQ0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dGhlIEFkbWluIEFQSSBhdCBzdGFydHVwPC90ZXh0Pgo8L3N2Zz4=)

Simple mutations and supported counters can avoid a read; other writes read the item and use a version guard.

#### Reads and filters

A `Query` is a range read. Because the row key keeps DynamoDB's sort order, the key condition, the direction and the page position all map to the row range, and results come back in DynamoDB's order without re-sorting.

**A `FilterExpression` runs in the adapter, not in Bigtable.** Bigtable's row filters work on column families, qualifiers and versions, not on DynamoDB's typed attributes, so the adapter reads the range and filters the items it read. A filtered read can *read more rows than it returns*, and a selective filter over a wide range costs what the range costs. Prefer a selective key condition to a broad range plus a filter.

`Scan` pages through the table the same way. Paging limits the response size, but a broad scan still reads every row it passes and competes with single-item requests for the instance's provisioned capacity.

Reads are strongly consistent through the single-cluster app profile. `ConsistentRead=false` does not pick a cheaper or staler read; a request that would be eventually consistent on DynamoDB is strongly consistent here.

![A Query's key condition becomes a Bigtable row range, and Bigtable returns every row in it. The adapter then applies the FilterExpression, so a filtered read can examine many more rows than it returns.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIFF1ZXJ5J3Mga2V5IGNvbmRpdGlvbiBiZWNvbWVzIGEgQmlndGFibGUgcm93IHJhbmdlLCBhbmQgQmlndGFibGUgcmV0dXJucyBldmVyeSByb3cgaW4gaXQuIFRoZSBhZGFwdGVyIHRoZW4gYXBwbGllcyB0aGUgRmlsdGVyRXhwcmVzc2lvbiwgc28gYSBmaWx0ZXJlZCByZWFkIGNhbiBleGFtaW5lIG1hbnkgbW9yZSByb3dzIHRoYW4gaXQgcmV0dXJucy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImJyZiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojMDQ3ODU3Ii8+PC9tYXJrZXI+CjxtYXJrZXIgaWQ9ImJycyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjwvZGVmcz4KPHRleHQgeD0iMjQiIHk9IjI2IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiOCI+SU4gQklHVEFCTEU8L3RleHQ+CjxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyOCIgaGVpZ2h0PSIxNDgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTM4IiB5PSI1OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPmtleSBjb25kaXRpb24gJiM4NTk0OyByb3cgcmFuZ2U8L3RleHQ+CjxyZWN0IHg9IjQyIiB5PSI3MCIgd2lkdGg9IjE5MiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMTM4IiB5PSI4NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+Y3VzdCM3IHwgMjAyNi0wOS0wMTwvdGV4dD4KPHJlY3QgeD0iNDIiIHk9Ijk0IiB3aWR0aD0iMTkyIiBoZWlnaHQ9IjIwIiByeD0iNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6I2E3ZjNkMCIvPgo8dGV4dCB4PSIxMzgiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+Y3VzdCM3IHwgMjAyNi0wOS0wMjwvdGV4dD4KPHJlY3QgeD0iNDIiIHk9IjExOCIgd2lkdGg9IjE5MiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMTM4IiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPmN1c3QjNyB8IDIwMjYtMDktMDM8L3RleHQ+CjxyZWN0IHg9IjQyIiB5PSIxNDIiIHdpZHRoPSIxOTIiIGhlaWdodD0iMjAiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjEzOCIgeT0iMTU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij5jdXN0IzcgfCAyMDI2LTA5LTA0PC90ZXh0Pgo8dGV4dCB4PSIxMzgiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPlJlYWRSb3dzIHJldHVybnMgYWxsIGZvdXI8L3RleHQ+CjxsaW5lIHgxPSIyNTIiIHkxPSIxMTAiIHgyPSIzMDgiIHkyPSIxMTAiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNicnMpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iMjgwIiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj40IHJvd3M8L3RleHQ+CjxyZWN0IHg9IjMxMiIgeT0iNTYiIHdpZHRoPSIyMTIiIGhlaWdodD0iMTA4IiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS42IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNDE4IiB5PSI0NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjgiPklOIFRIRSBBREFQVEVSPC90ZXh0Pgo8dGV4dCB4PSI0MTgiIHk9Ijg2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEyLjVweCI+RmlsdGVyRXhwcmVzc2lvbjwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj50b3RhbCAmZ3Q7IDEwMDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIxMzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmFwcGxpZWQgaGVyZSwgbm90IGluIHN0b3JhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQxOCIgeT0iMTUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U2Nhbm5lZENvdW50IDQ8L3RleHQ+CjxsaW5lIHgxPSI1MjQiIHkxPSIxMTAiIHgyPSI1ODAiIHkyPSIxMTAiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNicmYpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNTUyIiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj4xIHJvdzwvdGV4dD4KPHJlY3QgeD0iNTg0IiB5PSI3MCIgd2lkdGg9IjIyOCIgaGVpZ2h0PSI4MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI2OTgiIHk9Ijk2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEyLjVweCI+eW91ciByZXN1bHQ8L3RleHQ+CjxyZWN0IHg9IjYwMiIgeT0iMTA2IiB3aWR0aD0iMTkyIiBoZWlnaHQ9IjIwIiByeD0iNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6I2E3ZjNkMCIvPgo8dGV4dCB4PSI2OTgiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+Y3VzdCM3IHwgMjAyNi0wOS0wMzwvdGV4dD4KPHRleHQgeD0iNjk4IiB5PSIxNDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5Db3VudCAxPC90ZXh0Pgo8L3N2Zz4=)

![A Query's key condition becomes a Bigtable row range, and Bigtable returns every row in it. The adapter then applies the FilterExpression, so a filtered read can examine many more rows than it returns.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIFF1ZXJ5J3Mga2V5IGNvbmRpdGlvbiBiZWNvbWVzIGEgQmlndGFibGUgcm93IHJhbmdlLCBhbmQgQmlndGFibGUgcmV0dXJucyBldmVyeSByb3cgaW4gaXQuIFRoZSBhZGFwdGVyIHRoZW4gYXBwbGllcyB0aGUgRmlsdGVyRXhwcmVzc2lvbiwgc28gYSBmaWx0ZXJlZCByZWFkIGNhbiBleGFtaW5lIG1hbnkgbW9yZSByb3dzIHRoYW4gaXQgcmV0dXJucy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImJyZiIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNmVlN2I3Ii8+PC9tYXJrZXI+CjxtYXJrZXIgaWQ9ImJycyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjwvZGVmcz4KPHRleHQgeD0iMjQiIHk9IjI2IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YiI+SU4gQklHVEFCTEU8L3RleHQ+CjxyZWN0IHg9IjI0IiB5PSIzNiIgd2lkdGg9IjIyOCIgaGVpZ2h0PSIxNDgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTM4IiB5PSI1OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPmtleSBjb25kaXRpb24gJiM4NTk0OyByb3cgcmFuZ2U8L3RleHQ+CjxyZWN0IHg9IjQyIiB5PSI3MCIgd2lkdGg9IjE5MiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMTM4IiB5PSI4NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+Y3VzdCM3IHwgMjAyNi0wOS0wMTwvdGV4dD4KPHJlY3QgeD0iNDIiIHk9Ijk0IiB3aWR0aD0iMTkyIiBoZWlnaHQ9IjIwIiByeD0iNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIxMzgiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+Y3VzdCM3IHwgMjAyNi0wOS0wMjwvdGV4dD4KPHJlY3QgeD0iNDIiIHk9IjExOCIgd2lkdGg9IjE5MiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMTM4IiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPmN1c3QjNyB8IDIwMjYtMDktMDM8L3RleHQ+CjxyZWN0IHg9IjQyIiB5PSIxNDIiIHdpZHRoPSIxOTIiIGhlaWdodD0iMjAiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjEzOCIgeT0iMTU2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij5jdXN0IzcgfCAyMDI2LTA5LTA0PC90ZXh0Pgo8dGV4dCB4PSIxMzgiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPlJlYWRSb3dzIHJldHVybnMgYWxsIGZvdXI8L3RleHQ+CjxsaW5lIHgxPSIyNTIiIHkxPSIxMTAiIHgyPSIzMDgiIHkyPSIxMTAiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNicnMpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iMjgwIiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij40IHJvd3M8L3RleHQ+CjxyZWN0IHg9IjMxMiIgeT0iNTYiIHdpZHRoPSIyMTIiIGhlaWdodD0iMTA4IiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS42IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNDE4IiB5PSI0NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGIiPklOIFRIRSBBREFQVEVSPC90ZXh0Pgo8dGV4dCB4PSI0MTgiIHk9Ijg2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEyLjVweCI+RmlsdGVyRXhwcmVzc2lvbjwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIxMDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij50b3RhbCAmZ3Q7IDEwMDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIxMzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmFwcGxpZWQgaGVyZSwgbm90IGluIHN0b3JhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQxOCIgeT0iMTUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U2Nhbm5lZENvdW50IDQ8L3RleHQ+CjxsaW5lIHgxPSI1MjQiIHkxPSIxMTAiIHgyPSI1ODAiIHkyPSIxMTAiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNicmYpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNTUyIiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij4xIHJvdzwvdGV4dD4KPHJlY3QgeD0iNTg0IiB5PSI3MCIgd2lkdGg9IjIyOCIgaGVpZ2h0PSI4MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI2OTgiIHk9Ijk2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEyLjVweCI+eW91ciByZXN1bHQ8L3RleHQ+CjxyZWN0IHg9IjYwMiIgeT0iMTA2IiB3aWR0aD0iMTkyIiBoZWlnaHQ9IjIwIiByeD0iNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI2OTgiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+Y3VzdCM3IHwgMjAyNi0wOS0wMzwvdGV4dD4KPHRleHQgeD0iNjk4IiB5PSIxNDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5Db3VudCAxPC90ZXh0Pgo8L3N2Zz4=)

A filtered read examines every row in the selected key range. The adapter returns only rows that match the filter.

#### Limitations

Where Bigtable and DynamoDB differ

* **Multi-item transactions are not supported.** `TransactWriteItems`, `TransactGetItems` and transactional PartiQL are rejected, because Bigtable cannot commit or read several rows as one unit. For cross-item atomicity, use Spanner or a PostgreSQL backend.
* **Secondary indexes are not supported.** A GSI or LSI query is rejected rather than answered by scanning the table. Bigtable materialized views are not offered as DynamoDB indexes.
* **DynamoDB Streams are not supported.** Bigtable change streams are not compatible with DynamoDB Streams, and a change record cannot be written in the same atomic step as the write it describes.
* **Per-item TTL is not supported.** Bigtable expires data only through a column-family garbage-collection rule (one maximum age or version count for the whole family), not per item from an attribute. Configuring TTL fails instead of applying a different expiry rule.
* **The 400 KiB item limit behaves differently.** A top-level SET/REMOVE that skips the read does not check the resulting item's size, as described above. `PutItem` and updates that read the item still enforce it.
* **Filtered reads behave differently: they can read more rows than they return.** Filters run in the adapter over the whole key range; see the previous section.
* **A frequently updated item behaves differently: its writes queue up.** Different partition keys spread across Bigtable, but repeated updates to one item take turns on that row, and adding nodes does not split it. A benchmark with evenly spread keys does not predict this.

#### Other considerations

**Before going live.** Provision the Bigtable instance, the Bigtable table with its `d` and `n` column families, and a single-cluster app profile with single-row transactions allowed. The adapter checks these at startup and does not start without them.

**Capacity and cost.** Bigtable bills for provisioned nodes and storage, including while your application is idle. Additional clusters add cost without giving this adapter automatic failover between clusters.

**Moving from AWS.** Tables start empty. Existing DynamoDB items are not copied; load them through the DynamoDB API.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/4c58455f30b9a901a569e8583aaf80e093d70ddac4e9511ef869d306691f6a86-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/ba0814bc80862860cf20562ef8afc2473ca46eb284231864beadf71d44476b8b-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Target scenario | Cloud Bigtable | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Bigtable (one copy) | 474.50 | 474.50 |
| 0 | 0.00 | Cloud Bigtable (two copies) | 474.50 | 474.50 |
| 1 | 0.33 | Cloud Bigtable (one copy) | 474.50 | 474.17 |
| 1 | 0.33 | Cloud Bigtable (two copies) | 474.50 | 474.17 |
| 10 | 3.29 | Cloud Bigtable (one copy) | 474.50 | 471.22 |
| 10 | 3.29 | Cloud Bigtable (two copies) | 474.50 | 471.22 |
| 100 | 32.85 | Cloud Bigtable (one copy) | 474.50 | 441.65 |
| 100 | 32.85 | Cloud Bigtable (two copies) | 474.50 | 441.65 |
| 1,000 | 328.50 | Cloud Bigtable (one copy) | 474.50 | 146.00 |
| 1,000 | 328.50 | Cloud Bigtable (two copies) | 474.50 | 146.00 |
| 10,000 | 3,285.00 | Cloud Bigtable (one copy) | 949.00 | -2,336.00 |
| 10,000 | 3,285.00 | Cloud Bigtable (two copies) | 949.00 | -2,336.00 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (one copy) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (one copy) | Target reads per point read | 1 | operations |
| Cloud Bigtable (one copy) | Target writes per item write | 1 | operations |
| Cloud Bigtable (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (one copy) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (one copy) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Bigtable (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (two copies) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (two copies) | Target reads per point read | 1 | operations |
| Cloud Bigtable (two copies) | Target writes per item write | 1 | operations |
| Cloud Bigtable (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (two copies) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (two copies) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Bigtable (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Bigtable bills whole provisioned nodes per hour, not vCPU or RAM, plus SSD storage of the compressed physical data. Nodes are sized from planning-peak reads and writes against Google's per-node SSD throughput, with a one-node minimum. A replicated instance bills every cluster's nodes and its own copy of the data; this profile prices one cluster, so the standby selection does not add a cluster.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Bigtable pricing: [https://cloud.google.com/bigtable/pricing](https://cloud.google.com/bigtable/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-320830a9a89c06c228905dd61fe8054528d71731` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Bigtable pricing](https://cloud.google.com/bigtable/pricing).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/55366a4f63a3f198c5a74a53ea73789e91ab57269876a29e7e75ce4da1806d80-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/ee86a62cd95344baee3f9b95369236c73ac2f070339b544b01ddb04415a89769-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Target scenario | Cloud Bigtable | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Bigtable (one copy) | 474.50 | 474.50 |
| 0 | 0.00 | Cloud Bigtable (two copies) | 474.50 | 474.50 |
| 1 | 1.64 | Cloud Bigtable (one copy) | 474.50 | 472.86 |
| 1 | 1.64 | Cloud Bigtable (two copies) | 474.50 | 472.86 |
| 10 | 16.43 | Cloud Bigtable (one copy) | 474.50 | 458.08 |
| 10 | 16.43 | Cloud Bigtable (two copies) | 474.50 | 458.08 |
| 100 | 164.25 | Cloud Bigtable (one copy) | 474.50 | 310.25 |
| 100 | 164.25 | Cloud Bigtable (two copies) | 474.50 | 310.25 |
| 1,000 | 1,642.50 | Cloud Bigtable (one copy) | 474.50 | -1,168.00 |
| 1,000 | 1,642.50 | Cloud Bigtable (two copies) | 474.50 | -1,168.00 |
| 10,000 | 16,425.00 | Cloud Bigtable (one copy) | 1,423.50 | -15,001.50 |
| 10,000 | 16,425.00 | Cloud Bigtable (two copies) | 1,423.50 | -15,001.50 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (one copy) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (one copy) | Target reads per point read | 1 | operations |
| Cloud Bigtable (one copy) | Target writes per item write | 1 | operations |
| Cloud Bigtable (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (one copy) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (one copy) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Bigtable (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (two copies) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (two copies) | Target reads per point read | 1 | operations |
| Cloud Bigtable (two copies) | Target writes per item write | 1 | operations |
| Cloud Bigtable (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (two copies) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (two copies) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Bigtable (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Bigtable bills whole provisioned nodes per hour, not vCPU or RAM, plus SSD storage of the compressed physical data. Nodes are sized from planning-peak reads and writes against Google's per-node SSD throughput, with a one-node minimum. A replicated instance bills every cluster's nodes and its own copy of the data; this profile prices one cluster, so the standby selection does not add a cluster.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Bigtable pricing: [https://cloud.google.com/bigtable/pricing](https://cloud.google.com/bigtable/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-320830a9a89c06c228905dd61fe8054528d71731` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Bigtable pricing](https://cloud.google.com/bigtable/pricing).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/e1895dd943b66431cc0a2f399c8a95a8e184ef51fa872c86c435844cef24b8ae-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/4e1cf0e2070befb9b73bfe9b6f37f09fdab9985391ea19e411eba58e6101c365-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Target scenario | Cloud Bigtable | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Bigtable (one copy) | 474.50 | 474.50 |
| 0 | 0.00 | Cloud Bigtable (two copies) | 474.50 | 474.50 |
| 10 | 2.50 | Cloud Bigtable (one copy) | 476.20 | 473.70 |
| 10 | 2.50 | Cloud Bigtable (two copies) | 476.20 | 473.70 |
| 100 | 25.00 | Cloud Bigtable (one copy) | 491.50 | 466.50 |
| 100 | 25.00 | Cloud Bigtable (two copies) | 491.50 | 466.50 |
| 1,000 | 250.00 | Cloud Bigtable (one copy) | 644.50 | 394.50 |
| 1,000 | 250.00 | Cloud Bigtable (two copies) | 644.50 | 394.50 |
| 10,000 | 2,500.00 | Cloud Bigtable (one copy) | 2,174.50 | -325.50 |
| 10,000 | 2,500.00 | Cloud Bigtable (two copies) | 2,174.50 | -325.50 |
| 100,000 | 25,000.00 | Cloud Bigtable (one copy) | 17,474.50 | -7,525.50 |
| 100,000 | 25,000.00 | Cloud Bigtable (two copies) | 17,474.50 | -7,525.50 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (one copy) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (one copy) | Target reads per point read | 1 | operations |
| Cloud Bigtable (one copy) | Target writes per item write | 1 | operations |
| Cloud Bigtable (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (one copy) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (one copy) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Bigtable (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (two copies) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (two copies) | Target reads per point read | 1 | operations |
| Cloud Bigtable (two copies) | Target writes per item write | 1 | operations |
| Cloud Bigtable (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (two copies) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (two copies) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Bigtable (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Bigtable bills whole provisioned nodes per hour, not vCPU or RAM, plus SSD storage of the compressed physical data. Nodes are sized from planning-peak reads and writes against Google's per-node SSD throughput, with a one-node minimum. A replicated instance bills every cluster's nodes and its own copy of the data; this profile prices one cluster, so the standby selection does not add a cluster.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Bigtable pricing: [https://cloud.google.com/bigtable/pricing](https://cloud.google.com/bigtable/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-320830a9a89c06c228905dd61fe8054528d71731` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Bigtable pricing](https://cloud.google.com/bigtable/pricing).

**DynamoDB → Cloud Bigtable: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: nodes at planning peak | 474.50 |
| Target: Target retained physical data | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent managed resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **474.50** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.17 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.65 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 474.5 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Bigtable bills whole provisioned nodes per hour, not vCPU or RAM, plus SSD storage of the compressed physical data. Nodes are sized from planning-peak reads and writes against Google's per-node SSD throughput, with a one-node minimum. A replicated instance bills every cluster's nodes and its own copy of the data; this profile prices one cluster, so the standby selection does not add a cluster.

List prices read: 2026-10-22. Model: `plan-320830a9a89c06c228905dd61fe8054528d71731` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Bigtable pricing](https://cloud.google.com/bigtable/pricing).

### Cloud SQL for PostgreSQL

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| DescribeContinuousBackups | Backups | Out of scope | Full surface | use PostgreSQL backup and point-in-time recovery; the DynamoDB PITR API is not implemented |
| On-demand backups (CreateBackup / RestoreTableFromBackup / …) | Backups | Out of scope | Full surface | use PostgreSQL backups and restore procedures; DynamoDB backup APIs are not implemented |
| UpdateContinuousBackups | Backups | Out of scope | Full surface | use PostgreSQL backup and point-in-time recovery; the DynamoDB PITR API is not implemented |
| ConditionExpression | Conditional writes | Supported | Common | evaluated against the live item under a row-level lock; commits atomically |
| Global tables (CreateGlobalTable / UpdateGlobalTable / …) | Global | Out of scope | Full surface | use PostgreSQL replication and failover procedures; DynamoDB global-table APIs are not implemented |
| DescribeStream | Indexes + streams | Supported | Full surface | shard list + stream ARN |
| GetRecords | Indexes + streams | Supported | Full surface | DynamoDB Streams served from an in-transaction outbox co-committed with each write |
| GetShardIterator | Indexes + streams | Supported | Full surface | - |
| ListStreams | Indexes + streams | Supported | Full surface | the streamed-table registry |
| Query (GSI / LSI) | Indexes + streams | Supported | Most usage | indexes declared before deployment and maintained in the item transaction; queries use the index |
| S3 import/export + Kinesis streaming + ContributorInsights + ResourcePolicy | Out of scope | Out of scope | Full surface | these AWS integrations are outside the PostgreSQL adapter mapping |
| BatchExecuteStatement | PartiQL | Partial | Most usage | statements run independently; mixed reads and writes and repeated writes to one item are rejected |
| ExecuteStatement | PartiQL | Partial | Most usage | supported PartiQL statements are lowered to typed item operations; some language forms are unavailable |
| ExecuteTransaction | PartiQL | Partial | Most usage | supported transactional statements use one atomic PostgreSQL transaction or read snapshot |
| BatchGetItem | Reads | Supported | Most usage | executes each item read and reports its result; the batch is not one atomic snapshot |
| BatchWriteItem | Reads | Supported | Most usage | executes each item write and reports its result; the batch is not atomic |
| Query | Reads | Supported | Common | ordering, filters and pagination honored |
| Scan | Reads | Supported | Common | streamed page by page; index-scoped scans are supported |
| DeleteItem | Single item | Supported | Common | - |
| GetItem | Single item | Supported | Common | - |
| PutItem | Single item | Supported | Common | items kept in native shape; numbers at exact decimal precision |
| UpdateItem | Single item | Supported | Common | update expressions evaluated by the adapter |
| DescribeTimeToLive | TTL | Supported | Most usage | returns the table's configured TTL attribute and status |
| UpdateTimeToLive | TTL | Supported | Most usage | configures the TTL attribute and PostgreSQL expiry index; a background reaper deletes expired items |
| CreateTable | Table control plane | Supported | Most usage | creates a PostgreSQL relation, declared indexes and a durable registry entry |
| DeleteTable | Table control plane | Supported | Most usage | drops the PostgreSQL relation and its registry entry |
| DescribeEndpoints | Table control plane | Out of scope | Full surface | the adapter does not serve this DynamoDB API |
| DescribeLimits | Table control plane | Out of scope | Full surface | the adapter does not serve this DynamoDB API |
| DescribeTable | Table control plane | Supported | Most usage | returns the registered table schema and status |
| ListTables | Table control plane | Supported | Most usage | - |
| UpdateTable | Table control plane | Supported | Most usage | records DynamoDB billing metadata; does not resize PostgreSQL or change deployed indexes and streams |
| ListTagsOfResource | Tags | Supported | Full surface | returns tags held in the durable table registry |
| TagResource | Tags | Supported | Full surface | updates table tags in the durable registry |
| UntagResource | Tags | Supported | Full surface | removes table tags from the durable registry |
| TransactGetItems | Transactions | Supported | Most usage | reads all requested items in one PostgreSQL REPEATABLE READ snapshot |
| TransactWriteItems | Transactions | Supported | Most usage | one serializable PostgreSQL transaction across tables; at most 100 actions and one operation per item; ClientRequestToken idempotency; stream-enabled tables excluded |

#### How it works

Your application keeps its AWS SDK and code. Tensor9 runs a DynamoDB adapter beside it in the customer's environment and sets `AWS_ENDPOINT_URL_DYNAMODB`, so the SDK sends its requests to the adapter over the local network. The adapter accepts DynamoDB requests and data types, returns DynamoDB responses and errors, and stores the data in PostgreSQL. Unsupported requests return errors.

DynamoDB's 38-digit numbers, typed sets, conditional writes, secondary indexes and atomic transactions are implemented with PostgreSQL storage and transactions. PostgreSQL adds multi-table transactions and indexes that update with each write, but has different concurrency, capacity and naming limits, described below.

For a base-table `Query` or `Scan`, supported filters run in PostgreSQL as part of the SQL `WHERE` clause, and numbers compare as exact decimals. Results are fetched in batches until the request's `Limit` or 1 MiB of item data is reached. Filters SQL cannot express run in the adapter over the rows PostgreSQL returns. Secondary-index queries work differently, as described below.

![Before: on AWS, the application's DynamoDB SDK calls Amazon DynamoDB. After: on the target cloud, the same application and SDK call a Tensor9 adapter, which stores the data in PostgreSQL.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUywgdGhlIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IG9uIHRoZSB0YXJnZXQgY2xvdWQsIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggc3RvcmVzIHRoZSBkYXRhIGluIFBvc3RncmVTUUwuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhaDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0NiIgd2lkdGg9IjM1OCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIzMCIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjgwIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjkwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iOTAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkR5bmFtb0RCIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4LjVweCI+RHluYW1vREI8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iODAiIHdpZHRoPSIxNDgiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjg4IiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTEuNXB4Ij5BbWF6b24gRHluYW1vREI8L3RleHQ+Cjx0ZXh0IHg9IjI4OCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+QVdTLW1hbmFnZWQ8L3RleHQ+CjxsaW5lIHgxPSI0MTgiIHkxPSI0MCIgeDI9IjQxOCIgeTI9IjE2MCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6I2NiZDVlMSIvPgo8cmVjdCB4PSI0NjIiIHk9IjQ2IiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ3NiIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPk9OIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ3NCIgeT0iODAiIHdpZHRoPSI5MiIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1MjAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNTIwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c2FtZSBTREs8L3RleHQ+CjxsaW5lIHgxPSI1NjYiIHkxPSIxMTMiIHgyPSI1OTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNTk0IiB5PSI3NiIgd2lkdGg9IjExMCIgaGVpZ2h0PSI3NCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI2NDkiIHk9IjEwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMnB4Ij5UZW5zb3I5PC90ZXh0Pgo8dGV4dCB4PSI2NDkiIHk9IjExNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c2VydmljZTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmFkYXB0ZXI8L3RleHQ+CjxsaW5lIHgxPSI3MDQiIHkxPSIxMTMiIHgyPSI3MjgiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iNzMyIiB5PSI4MCIgd2lkdGg9Ijg0IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTA4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjExcHgiPlBvc3RncmVTUUw8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cmVsYXRpb25hbDwvdGV4dD4KPC9zdmc+)

![Before: on AWS, the application's DynamoDB SDK calls Amazon DynamoDB. After: on the target cloud, the same application and SDK call a Tensor9 adapter, which stores the data in PostgreSQL.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUywgdGhlIGFwcGxpY2F0aW9uJ3MgRHluYW1vREIgU0RLIGNhbGxzIEFtYXpvbiBEeW5hbW9EQi4gQWZ0ZXI6IG9uIHRoZSB0YXJnZXQgY2xvdWQsIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggc3RvcmVzIHRoZSBkYXRhIGluIFBvc3RncmVTUUwuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhaDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjE2IiB5PSI0NiIgd2lkdGg9IjM1OCIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIzMCIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjgwIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjkwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iOTAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkR5bmFtb0RCIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZvbnQtc2l6ZTo4LjVweCI+RHluYW1vREI8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iODAiIHdpZHRoPSIxNDgiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjg4IiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTEuNXB4Ij5BbWF6b24gRHluYW1vREI8L3RleHQ+Cjx0ZXh0IHg9IjI4OCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+QVdTLW1hbmFnZWQ8L3RleHQ+CjxsaW5lIHgxPSI0MTgiIHkxPSI0MCIgeDI9IjQxOCIgeTI9IjE2MCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6IzQ3NTU2OSIvPgo8cmVjdCB4PSI0NjIiIHk9IjQ2IiB3aWR0aD0iMzYyIiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ3NiIgeT0iNjQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPk9OIFRIRSBUQVJHRVQgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjQ3NCIgeT0iODAiIHdpZHRoPSI5MiIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1MjAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNTIwIiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c2FtZSBTREs8L3RleHQ+CjxsaW5lIHgxPSI1NjYiIHkxPSIxMTMiIHgyPSI1OTAiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNTk0IiB5PSI3NiIgd2lkdGg9IjExMCIgaGVpZ2h0PSI3NCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI2NDkiIHk9IjEwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMnB4Ij5UZW5zb3I5PC90ZXh0Pgo8dGV4dCB4PSI2NDkiIHk9IjExNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c2VydmljZTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmFkYXB0ZXI8L3RleHQ+CjxsaW5lIHgxPSI3MDQiIHkxPSIxMTMiIHgyPSI3MjgiIHkyPSIxMTMiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhaDEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iNzMyIiB5PSI4MCIgd2lkdGg9Ijg0IiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTA4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjExcHgiPlBvc3RncmVTUUw8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cmVsYXRpb25hbDwvdGV4dD4KPC9zdmc+)

Your application keeps its DynamoDB SDK; an adapter in the target environment stores the data in PostgreSQL.

#### Architecture

The adapter parses DynamoDB requests and expressions, runs the matching PostgreSQL statements and returns DynamoDB responses. It connects through a connection pool with the customer's credentials. All data stays in PostgreSQL, so adapter instances can restart or scale out without sharing local state; tables with Streams enabled have the single-writer limit described below.

Each DynamoDB table is a PostgreSQL table named `ddb_<name>` in one database. The `ddb_tables` registry records each table's PostgreSQL name, key schema, billing mode, time-to-live (TTL) settings, global secondary indexes (GSIs) and stream settings. A write or query for a table missing from the registry returns `ResourceNotFoundException`; writes never create tables. `CreateTable` at run time creates a PostgreSQL index for each declared GSI, and each table with Streams enabled also gets a `_strm` table that stores its change records.

![Your app's DynamoDB SDK calls the Tensor9 adapter, which keeps no data of its own. PostgreSQL holds everything in one database: a table for each DynamoDB table, the ddb\_tables registry, an index for each declared GSI, and a change-record table for each table with Streams enabled.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJZb3VyIGFwcCdzIER5bmFtb0RCIFNESyBjYWxscyB0aGUgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBrZWVwcyBubyBkYXRhIG9mIGl0cyBvd24uIFBvc3RncmVTUUwgaG9sZHMgZXZlcnl0aGluZyBpbiBvbmUgZGF0YWJhc2U6IGEgdGFibGUgZm9yIGVhY2ggRHluYW1vREIgdGFibGUsIHRoZSBkZGJfdGFibGVzIHJlZ2lzdHJ5LCBhbiBpbmRleCBmb3IgZWFjaCBkZWNsYXJlZCBHU0ksIGFuZCBhIGNoYW5nZS1yZWNvcmQgdGFibGUgZm9yIGVhY2ggdGFibGUgd2l0aCBTdHJlYW1zIGVuYWJsZWQuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhciIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iOCIgeT0iMzQiIHdpZHRoPSI4MjAiIGhlaWdodD0iMjA4IiByeD0iMTYiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjYiIHk9IjU0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiOCI+Q1VTVE9NRVInUyBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjExMCIgd2lkdGg9IjExNCIgaGVpZ2h0PSI5MiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI4MyIgeT0iMTUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEzcHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTY4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+RHluYW1vREIgU0RLPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTg0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnVuY2hhbmdlZDwvdGV4dD4KPGxpbmUgeDE9IjE0MCIgeTE9IjE1NiIgeDI9IjE5MiIgeTI9IjE1NiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FyKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+Cjx0ZXh0IHg9IjE2NiIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZm9udC1zaXplOjguNXB4Ij5EeW5hbW9EQjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxMjIiIHdpZHRoPSIxNjgiIGhlaWdodD0iNjgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjgwIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTNweCI+YWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMjgwIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmtlZXBzIG5vIGRhdGE8L3RleHQ+CjxsaW5lIHgxPSIzNjQiIHkxPSIxNTYiIHgyPSI0MzYiIHkyPSIxNTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhcikiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSI0MDAiIHk9IjE0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPlNRTDwvdGV4dD4KPHRleHQgeD0iNDAwIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5wb29sZWQ8L3RleHQ+CjxyZWN0IHg9IjQ0MCIgeT0iODYiIHdpZHRoPSIzNzIiIGhlaWdodD0iMTQ4IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjYyNiIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEyLjVweCI+UG9zdGdyZVNRTCDCtyBvbmUgZGF0YWJhc2U8L3RleHQ+CjxyZWN0IHg9IjQ1NCIgeT0iMTE2IiB3aWR0aD0iMjMwIiBoZWlnaHQ9IjEwOCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1NjkiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+b25lIHRhYmxlIGVhY2g8L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMTQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNjQ3NDhiIj5vbmUgZGRiXyZsdDtuYW1lJmd0OyBwZXIgdGFibGU8L3RleHQ+CjxyZWN0IHg9IjQ2NiIgeT0iMTUyIiB3aWR0aD0iMjA2IiBoZWlnaHQ9IjIwIiByeD0iNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1NjkiIHk9IjE2NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6IzMzNDE1NSI+ZGRiX29yZGVycyAgIChwaywgc2ssIGl0ZW0pPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE3NiIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTY5IiB5PSIxOTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPmRkYl9zZXNzaW9ucyAocGssIHNrLCBpdGVtKTwvdGV4dD4KPHJlY3QgeD0iNDY2IiB5PSIyMDAiIHdpZHRoPSIyMDYiIGhlaWdodD0iMjAiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjU2OSIgeT0iMjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMzM0MTU1Ij5kZGJfdGFibGVzICAg4oaSIHJlZ2lzdHJ5PC90ZXh0Pgo8cmVjdCB4PSI2OTYiIHk9IjExNiIgd2lkdGg9IjEwMiIgaGVpZ2h0PSIxMDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzQ3IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiMzMzQxNTUiPlBvc3RncmVTUUw8L3RleHQ+Cjx0ZXh0IHg9Ijc0NyIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDA7ZmlsbDojMzM0MTU1Ij5pbmRleCAvIEdTSTwvdGV4dD4KPHRleHQgeD0iNzQ3IiB5PSIxNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj4rIGNoYW5nZSByZWNvcmRzPC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjE5MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnBlciBzdHJlYW1lZCB0YWJsZTwvdGV4dD4KPC9zdmc+)

![Your app's DynamoDB SDK calls the Tensor9 adapter, which keeps no data of its own. PostgreSQL holds everything in one database: a table for each DynamoDB table, the ddb\_tables registry, an index for each declared GSI, and a change-record table for each table with Streams enabled.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJZb3VyIGFwcCdzIER5bmFtb0RCIFNESyBjYWxscyB0aGUgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBrZWVwcyBubyBkYXRhIG9mIGl0cyBvd24uIFBvc3RncmVTUUwgaG9sZHMgZXZlcnl0aGluZyBpbiBvbmUgZGF0YWJhc2U6IGEgdGFibGUgZm9yIGVhY2ggRHluYW1vREIgdGFibGUsIHRoZSBkZGJfdGFibGVzIHJlZ2lzdHJ5LCBhbiBpbmRleCBmb3IgZWFjaCBkZWNsYXJlZCBHU0ksIGFuZCBhIGNoYW5nZS1yZWNvcmQgdGFibGUgZm9yIGVhY2ggdGFibGUgd2l0aCBTdHJlYW1zIGVuYWJsZWQuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPgo8bWFya2VyIGlkPSJhciIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iOCIgeT0iMzQiIHdpZHRoPSI4MjAiIGhlaWdodD0iMjA4IiByeD0iMTYiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjYiIHk9IjU0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YiI+Q1VTVE9NRVInUyBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjExMCIgd2lkdGg9IjExNCIgaGVpZ2h0PSI5MiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI4MyIgeT0iMTUwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEzcHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTY4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+RHluYW1vREIgU0RLPC90ZXh0Pgo8dGV4dCB4PSI4MyIgeT0iMTg0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnVuY2hhbmdlZDwvdGV4dD4KPGxpbmUgeDE9IjE0MCIgeTE9IjE1NiIgeDI9IjE5MiIgeTI9IjE1NiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FyKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+Cjx0ZXh0IHg9IjE2NiIgeT0iMTQ4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZm9udC1zaXplOjguNXB4Ij5EeW5hbW9EQjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxMjIiIHdpZHRoPSIxNjgiIGhlaWdodD0iNjgiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjgwIiB5PSIxNTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTNweCI+YWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMjgwIiB5PSIxNjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmtlZXBzIG5vIGRhdGE8L3RleHQ+CjxsaW5lIHgxPSIzNjQiIHkxPSIxNTYiIHgyPSI0MzYiIHkyPSIxNTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhcikiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSI0MDAiIHk9IjE0OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPlNRTDwvdGV4dD4KPHRleHQgeD0iNDAwIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5wb29sZWQ8L3RleHQ+CjxyZWN0IHg9IjQ0MCIgeT0iODYiIHdpZHRoPSIzNzIiIGhlaWdodD0iMTQ4IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjYyNiIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEyLjVweCI+UG9zdGdyZVNRTCDCtyBvbmUgZGF0YWJhc2U8L3RleHQ+CjxyZWN0IHg9IjQ1NCIgeT0iMTE2IiB3aWR0aD0iMjMwIiBoZWlnaHQ9IjEwOCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1NjkiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+b25lIHRhYmxlIGVhY2g8L3RleHQ+Cjx0ZXh0IHg9IjU2OSIgeT0iMTQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojOTRhM2I4Ij5vbmUgZGRiXyZsdDtuYW1lJmd0OyBwZXIgdGFibGU8L3RleHQ+CjxyZWN0IHg9IjQ2NiIgeT0iMTUyIiB3aWR0aD0iMjA2IiBoZWlnaHQ9IjIwIiByeD0iNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1NjkiIHk9IjE2NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6I2NiZDVlMSI+ZGRiX29yZGVycyAgIChwaywgc2ssIGl0ZW0pPC90ZXh0Pgo8cmVjdCB4PSI0NjYiIHk9IjE3NiIgd2lkdGg9IjIwNiIgaGVpZ2h0PSIyMCIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTY5IiB5PSIxOTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPmRkYl9zZXNzaW9ucyAocGssIHNrLCBpdGVtKTwvdGV4dD4KPHJlY3QgeD0iNDY2IiB5PSIyMDAiIHdpZHRoPSIyMDYiIGhlaWdodD0iMjAiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjU2OSIgeT0iMjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojY2JkNWUxIj5kZGJfdGFibGVzICAg4oaSIHJlZ2lzdHJ5PC90ZXh0Pgo8cmVjdCB4PSI2OTYiIHk9IjExNiIgd2lkdGg9IjEwMiIgaGVpZ2h0PSIxMDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzQ3IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMDtmaWxsOiNjYmQ1ZTEiPlBvc3RncmVTUUw8L3RleHQ+Cjx0ZXh0IHg9Ijc0NyIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDA7ZmlsbDojY2JkNWUxIj5pbmRleCAvIEdTSTwvdGV4dD4KPHRleHQgeD0iNzQ3IiB5PSIxNzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij4rIGNoYW5nZSByZWNvcmRzPC90ZXh0Pgo8dGV4dCB4PSI3NDciIHk9IjE5MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnBlciBzdHJlYW1lZCB0YWJsZTwvdGV4dD4KPC9zdmc+)

The adapter keeps no data; each DynamoDB table is its own table in one PostgreSQL database.

#### Item storage

Each DynamoDB item is one PostgreSQL row with columns `pk TEXT`, `sk TEXT`, `okey TEXT` and `item JSONB`. The `PRIMARY KEY (pk, sk)` index serves `GetItem`, and a second index over `pk` and byte-ordered `okey` serves ordered base-table `Query` requests.

The `item` column keeps DynamoDB's typed attributes, such as `{"N":"123.45"}`, `{"B":"<b64>"}` and typed sets. Numbers stay decimal strings, so a 38-digit amount or a Snowflake ID is never rounded, and a number stays distinct from a numeric string. Enabling TTL builds a PostgreSQL expression index over the configured epoch attribute in the item JSONB, and a leader-elected background worker, one adapter instance at a time, deletes expired rows through it in bounded batches. Expired items stay readable until they are deleted, because reads do not filter on TTL.

![A DynamoDB item becomes one row with pk, sk, okey and item columns and PRIMARY KEY (pk, sk). The whole item is stored as JSONB in its DynamoDB form, so a number keeps its exact decimal text. The okey column keeps the sort order, and TTL uses an index over the item.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0gYmVjb21lcyBvbmUgcm93IHdpdGggcGssIHNrLCBva2V5IGFuZCBpdGVtIGNvbHVtbnMgYW5kIFBSSU1BUlkgS0VZIChwaywgc2spLiBUaGUgd2hvbGUgaXRlbSBpcyBzdG9yZWQgYXMgSlNPTkIgaW4gaXRzIER5bmFtb0RCIGZvcm0sIHNvIGEgbnVtYmVyIGtlZXBzIGl0cyBleGFjdCBkZWNpbWFsIHRleHQuIFRoZSBva2V5IGNvbHVtbiBrZWVwcyB0aGUgc29ydCBvcmRlciwgYW5kIFRUTCB1c2VzIGFuIGluZGV4IG92ZXIgdGhlIGl0ZW0uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImEzIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIzMCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+RFlOQU1PREIgSVRFTTwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjE4MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NCIgeT0iNzQiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiYjMTIzOzwvdGV4dD4KPHRleHQgeD0iNjAiIHk9Ijk4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4icGsiOiAgICAmIzEyMzsgIlMiOiAidXNlciM0MiIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTIyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4ic2siOiAgICAmIzEyMzsgIlMiOiAib3JkZXIjNyIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojYjQ1MzA5Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAiMTIzLjQ1IiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxNzAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiJ0YWdzIjogICYjMTIzOyAiU1MiOiBbInZpcCJdICYjMTI1OzwvdGV4dD4KPHRleHQgeD0iNDQiIHk9IjE5NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0NCIgeT0iMjE0IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojYjQ1MzA5Ij5OIGlzIGV4YWN0IGRlY2ltYWwsIG5vdCBhIGZsb2F0PC90ZXh0Pgo8bGluZSB4MT0iMzM0IiB5MT0iMTMyIiB4Mj0iMzg2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTMpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzYwIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+c3RvcmU8L3RleHQ+Cjx0ZXh0IHg9IjM5NiIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPmRkYl9vcmRlcnMgUk9XIMK3IFBSSU1BUlkgS0VZIChwaywgc2spPC90ZXh0Pgo8cmVjdCB4PSIzOTYiIHk9IjQyIiB3aWR0aD0iNDE0IiBoZWlnaHQ9IjE5OCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0MTQiIHk9IjY2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5wayAgICAgICAgPHRzcGFuIHN0eWxlPSJmaWxsOiMzMzQxNTUiPlRFWFQ8L3RzcGFuPiAgICAidXNlciM0MiI8L3RleHQ+Cjx0ZXh0IHg9IjQxNCIgeT0iODgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnNrICAgICAgICA8dHNwYW4gc3R5bGU9ImZpbGw6IzMzNDE1NSI+VEVYVDwvdHNwYW4+ICAgICJvcmRlciM3IjwvdGV4dD4KPHRleHQgeD0iNDE0IiB5PSIxMTAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPml0ZW0gICAgICA8dHNwYW4gc3R5bGU9ImZpbGw6IzMzNDE1NSI+SlNPTkI8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iNDMwIiB5PSIxMjAiIHdpZHRoPSIzNjYiIGhlaWdodD0iNTIiIHJ4PSI3IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTM5IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij4mIzEyMzsgInRvdGFsIjogJiMxMjM7ICJOIjogIjEyMy40NSIgJiMxMjU7LDwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPiAgInRhZ3MiOiAmIzEyMzsgIlNTIjogWyJ2aXAiXSAmIzEyNTssIOKApiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjQxNCIgeT0iMTk0IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5va2V5ICAgICAgPHRzcGFuIHN0eWxlPSJmaWxsOiMzMzQxNTUiPlRFWFQ8L3RzcGFuPiAgICBwcmVzZXJ2ZXMgc29ydCBvcmRlcjwvdGV4dD4KPHRleHQgeD0iNDE0IiB5PSIyMTYiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiMzMzQxNTUiPlRUTDogYW4gaW5kZXggb3ZlciB0aGUgaXRlbSBKU09OQjwvdGV4dD4KPC9zdmc+)

![A DynamoDB item becomes one row with pk, sk, okey and item columns and PRIMARY KEY (pk, sk). The whole item is stored as JSONB in its DynamoDB form, so a number keeps its exact decimal text. The okey column keeps the sort order, and TTL uses an index over the item.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIER5bmFtb0RCIGl0ZW0gYmVjb21lcyBvbmUgcm93IHdpdGggcGssIHNrLCBva2V5IGFuZCBpdGVtIGNvbHVtbnMgYW5kIFBSSU1BUlkgS0VZIChwaywgc2spLiBUaGUgd2hvbGUgaXRlbSBpcyBzdG9yZWQgYXMgSlNPTkIgaW4gaXRzIER5bmFtb0RCIGZvcm0sIHNvIGEgbnVtYmVyIGtlZXBzIGl0cyBleGFjdCBkZWNpbWFsIHRleHQuIFRoZSBva2V5IGNvbHVtbiBrZWVwcyB0aGUgc29ydCBvcmRlciwgYW5kIFRUTCB1c2VzIGFuIGluZGV4IG92ZXIgdGhlIGl0ZW0uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImEzIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIzMCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+RFlOQU1PREIgSVRFTTwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjE4MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NCIgeT0iNzQiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiYjMTIzOzwvdGV4dD4KPHRleHQgeD0iNjAiIHk9Ijk4IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4icGsiOiAgICAmIzEyMzsgIlMiOiAidXNlciM0MiIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTIyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4ic2siOiAgICAmIzEyMzsgIlMiOiAib3JkZXIjNyIgJiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI2MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojZmJiZjI0Ij4idG90YWwiOiAmIzEyMzsgIk4iOiAiMTIzLjQ1IiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjYwIiB5PSIxNzAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiJ0YWdzIjogICYjMTIzOyAiU1MiOiBbInZpcCJdICYjMTI1OzwvdGV4dD4KPHRleHQgeD0iNDQiIHk9IjE5NCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+JiMxMjU7PC90ZXh0Pgo8dGV4dCB4PSI0NCIgeT0iMjE0IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojZmJiZjI0Ij5OIGlzIGV4YWN0IGRlY2ltYWwsIG5vdCBhIGZsb2F0PC90ZXh0Pgo8bGluZSB4MT0iMzM0IiB5MT0iMTMyIiB4Mj0iMzg2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTMpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzYwIiB5PSIxMjMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+c3RvcmU8L3RleHQ+Cjx0ZXh0IHg9IjM5NiIgeT0iMzAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPmRkYl9vcmRlcnMgUk9XIMK3IFBSSU1BUlkgS0VZIChwaywgc2spPC90ZXh0Pgo8cmVjdCB4PSIzOTYiIHk9IjQyIiB3aWR0aD0iNDE0IiBoZWlnaHQ9IjE5OCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI0MTQiIHk9IjY2IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5wayAgICAgICAgPHRzcGFuIHN0eWxlPSJmaWxsOiNjYmQ1ZTEiPlRFWFQ8L3RzcGFuPiAgICAidXNlciM0MiI8L3RleHQ+Cjx0ZXh0IHg9IjQxNCIgeT0iODgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnNrICAgICAgICA8dHNwYW4gc3R5bGU9ImZpbGw6I2NiZDVlMSI+VEVYVDwvdHNwYW4+ICAgICJvcmRlciM3IjwvdGV4dD4KPHRleHQgeD0iNDE0IiB5PSIxMTAiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPml0ZW0gICAgICA8dHNwYW4gc3R5bGU9ImZpbGw6I2NiZDVlMSI+SlNPTkI8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iNDMwIiB5PSIxMjAiIHdpZHRoPSIzNjYiIGhlaWdodD0iNTIiIHJ4PSI3IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTM5IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj4mIzEyMzsgInRvdGFsIjogJiMxMjM7ICJOIjogIjEyMy40NSIgJiMxMjU7LDwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPiAgInRhZ3MiOiAmIzEyMzsgIlNTIjogWyJ2aXAiXSAmIzEyNTssIOKApiAmIzEyNTs8L3RleHQ+Cjx0ZXh0IHg9IjQxNCIgeT0iMTk0IiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5va2V5ICAgICAgPHRzcGFuIHN0eWxlPSJmaWxsOiNjYmQ1ZTEiPlRFWFQ8L3RzcGFuPiAgICBwcmVzZXJ2ZXMgc29ydCBvcmRlcjwvdGV4dD4KPHRleHQgeD0iNDE0IiB5PSIyMTYiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNjYmQ1ZTEiPlRUTDogYW4gaW5kZXggb3ZlciB0aGUgaXRlbSBKU09OQjwvdGV4dD4KPC9zdmc+)

Each attribute keeps its DynamoDB type tag inside item JSONB , so \{"N":"123.45"} keeps its exact decimal string.

#### Tables

Each DynamoDB table has its own PostgreSQL table, indexes and, when Streams is on, a `_strm` change-record table. `CreateTable` creates those objects and the registry entry, and `DeleteTable` drops them. You can tune storage, indexes and vacuum settings per table.

When it creates a table, the adapter checks a limit of 500 DynamoDB tables per namespace. Concurrent creates of different tables can exceed it; it is a safeguard, not a PostgreSQL quota. Tables are not spread across database instances automatically, so plan database capacity and table placement for larger deployments. A provisioned instance costs compute while idle.

![Each DynamoDB table is its own PostgreSQL table in one database, next to the ddb\_tables registry and each table's indexes. The adapter allows 500 tables per namespace; larger deployments need capacity and placement planning.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjI2IiB2aWV3Qm94PSIwIDAgODM2IDIyNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFYWNoIER5bmFtb0RCIHRhYmxlIGlzIGl0cyBvd24gUG9zdGdyZVNRTCB0YWJsZSBpbiBvbmUgZGF0YWJhc2UsIG5leHQgdG8gdGhlIGRkYl90YWJsZXMgcmVnaXN0cnkgYW5kIGVhY2ggdGFibGUncyBpbmRleGVzLiBUaGUgYWRhcHRlciBhbGxvd3MgNTAwIHRhYmxlcyBwZXIgbmFtZXNwYWNlOyBsYXJnZXIgZGVwbG95bWVudHMgbmVlZCBjYXBhY2l0eSBhbmQgcGxhY2VtZW50IHBsYW5uaW5nLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPk9ORSBQT1NUR1JFU1FMIERBVEFCQVNFIMK3IGEgdGFibGUgcGVyIER5bmFtb0RCIHRhYmxlPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iNDAiIHdpZHRoPSI1MjAiIGhlaWdodD0iMTY2IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjQ0IiB5PSI2NiIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMjQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMTE5IiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+ZGRiX29yZGVyczwvdGV4dD4KPHJlY3QgeD0iNTgiIHk9IjEwMCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTE5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnJvd3MgKHBrLCBzayk8L3RleHQ+CjxyZWN0IHg9IjU4IiB5PSIxMzIiIHdpZHRoPSIxMjIiIGhlaWdodD0iMjYiIHJ4PSI2IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjExOSIgeT0iMTQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5HU0kgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjExOSIgeT0iMTc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+aXRzIG93biB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iMjA2IiB5PSI2NiIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMjQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMjgxIiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+ZGRiX3Nlc3Npb25zPC90ZXh0Pgo8cmVjdCB4PSIyMjAiIHk9IjEwMCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMjgxIiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnJvd3MgKHBrLCBzayk8L3RleHQ+CjxyZWN0IHg9IjIyMCIgeT0iMTMyIiB3aWR0aD0iMTIyIiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyODEiIHk9IjE0OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+X3N0cm0gcmVjb3JkczwvdGV4dD4KPHRleHQgeD0iMjgxIiB5PSIxNzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5jcmVhdGVkIGF0IHJ1bnRpbWU8L3RleHQ+CjxyZWN0IHg9IjM2OCIgeT0iNjYiIHdpZHRoPSIxNjAiIGhlaWdodD0iMTI0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjQ0OCIgeT0iODgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPmRkYl90YWJsZXM8L3RleHQ+CjxyZWN0IHg9IjM4MiIgeT0iMTAwIiB3aWR0aD0iMTMyIiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NDgiIHk9IjExNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+b3JkZXJzIOKGkiB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iMzgyIiB5PSIxMzIiIHdpZHRoPSIxMzIiIGhlaWdodD0iMjYiIHJ4PSI2IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5zZXNzaW9ucyDihpIgdGFibGU8L3RleHQ+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dGFibGUgcmVnaXN0cnk8L3RleHQ+Cjx0ZXh0IHg9IjU3NiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPkxhcmdlciB0YWJsZSBzZXRzPC90ZXh0Pgo8cmVjdCB4PSI1NzYiIHk9IjQwIiB3aWR0aD0iMjM2IiBoZWlnaHQ9IjE2NiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNCA0IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjY5NCIgeT0iNjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmb250LXdlaWdodDo3MDA7ZmlsbDojMzM0MTU1Ij5QbGFuIGNhcGFjaXR5IGFuZCB0YWJsZSBwbGFjZW1lbnQ8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5MaW1pdDogNTAwIHRhYmxlcyBwZXIgbmFtZXNwYWNlPC90ZXh0Pgo8cmVjdCB4PSI1OTYiIHk9IjEwMCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjMwIiByeD0iNyIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI2NDIiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+Y2FwYWNpdHk8L3RleHQ+CjxyZWN0IHg9IjcwMCIgeT0iMTAwIiB3aWR0aD0iOTIiIGhlaWdodD0iMzAiIHJ4PSI3IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc0NiIgeT0iMTIwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij50YWJsZSBjb3VudDwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxNTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5ObyBhdXRvbWF0aWMgcGxhY2VtZW50PC90ZXh0Pgo8dGV4dCB4PSI2OTQiIHk9IjE2OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmFjcm9zcyBkYXRhYmFzZSBpbnN0YW5jZXM8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iMTkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+cHJvdmlzaW9uZWQgLyBhbHdheXMtb248L3RleHQ+Cjwvc3ZnPg==)

![Each DynamoDB table is its own PostgreSQL table in one database, next to the ddb\_tables registry and each table's indexes. The adapter allows 500 tables per namespace; larger deployments need capacity and placement planning.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjI2IiB2aWV3Qm94PSIwIDAgODM2IDIyNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFYWNoIER5bmFtb0RCIHRhYmxlIGlzIGl0cyBvd24gUG9zdGdyZVNRTCB0YWJsZSBpbiBvbmUgZGF0YWJhc2UsIG5leHQgdG8gdGhlIGRkYl90YWJsZXMgcmVnaXN0cnkgYW5kIGVhY2ggdGFibGUncyBpbmRleGVzLiBUaGUgYWRhcHRlciBhbGxvd3MgNTAwIHRhYmxlcyBwZXIgbmFtZXNwYWNlOyBsYXJnZXIgZGVwbG95bWVudHMgbmVlZCBjYXBhY2l0eSBhbmQgcGxhY2VtZW50IHBsYW5uaW5nLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPk9ORSBQT1NUR1JFU1FMIERBVEFCQVNFIMK3IGEgdGFibGUgcGVyIER5bmFtb0RCIHRhYmxlPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iNDAiIHdpZHRoPSI1MjAiIGhlaWdodD0iMTY2IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjQ0IiB5PSI2NiIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMjQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMTE5IiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+ZGRiX29yZGVyczwvdGV4dD4KPHJlY3QgeD0iNTgiIHk9IjEwMCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTE5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnJvd3MgKHBrLCBzayk8L3RleHQ+CjxyZWN0IHg9IjU4IiB5PSIxMzIiIHdpZHRoPSIxMjIiIGhlaWdodD0iMjYiIHJ4PSI2IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjExOSIgeT0iMTQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5HU0kgaW5kZXg8L3RleHQ+Cjx0ZXh0IHg9IjExOSIgeT0iMTc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+aXRzIG93biB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iMjA2IiB5PSI2NiIgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxMjQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjgxIiB5PSI4OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+ZGRiX3Nlc3Npb25zPC90ZXh0Pgo8cmVjdCB4PSIyMjAiIHk9IjEwMCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMjgxIiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnJvd3MgKHBrLCBzayk8L3RleHQ+CjxyZWN0IHg9IjIyMCIgeT0iMTMyIiB3aWR0aD0iMTIyIiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyODEiIHk9IjE0OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+X3N0cm0gcmVjb3JkczwvdGV4dD4KPHRleHQgeD0iMjgxIiB5PSIxNzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5jcmVhdGVkIGF0IHJ1bnRpbWU8L3RleHQ+CjxyZWN0IHg9IjM2OCIgeT0iNjYiIHdpZHRoPSIxNjAiIGhlaWdodD0iMTI0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ0OCIgeT0iODgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPmRkYl90YWJsZXM8L3RleHQ+CjxyZWN0IHg9IjM4MiIgeT0iMTAwIiB3aWR0aD0iMTMyIiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NDgiIHk9IjExNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+b3JkZXJzIOKGkiB0YWJsZTwvdGV4dD4KPHJlY3QgeD0iMzgyIiB5PSIxMzIiIHdpZHRoPSIxMzIiIGhlaWdodD0iMjYiIHJ4PSI2IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTQ5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5zZXNzaW9ucyDihpIgdGFibGU8L3RleHQ+Cjx0ZXh0IHg9IjQ0OCIgeT0iMTc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dGFibGUgcmVnaXN0cnk8L3RleHQ+Cjx0ZXh0IHg9IjU3NiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPkxhcmdlciB0YWJsZSBzZXRzPC90ZXh0Pgo8cmVjdCB4PSI1NzYiIHk9IjQwIiB3aWR0aD0iMjM2IiBoZWlnaHQ9IjE2NiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNCA0IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjY5NCIgeT0iNjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmb250LXdlaWdodDo3MDA7ZmlsbDojY2JkNWUxIj5QbGFuIGNhcGFjaXR5IGFuZCB0YWJsZSBwbGFjZW1lbnQ8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iODQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5MaW1pdDogNTAwIHRhYmxlcyBwZXIgbmFtZXNwYWNlPC90ZXh0Pgo8cmVjdCB4PSI1OTYiIHk9IjEwMCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjMwIiByeD0iNyIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI2NDIiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+Y2FwYWNpdHk8L3RleHQ+CjxyZWN0IHg9IjcwMCIgeT0iMTAwIiB3aWR0aD0iOTIiIGhlaWdodD0iMzAiIHJ4PSI3IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc0NiIgeT0iMTIwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj50YWJsZSBjb3VudDwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxNTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5ObyBhdXRvbWF0aWMgcGxhY2VtZW50PC90ZXh0Pgo8dGV4dCB4PSI2OTQiIHk9IjE2OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmFjcm9zcyBkYXRhYmFzZSBpbnN0YW5jZXM8L3RleHQ+Cjx0ZXh0IHg9IjY5NCIgeT0iMTkwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+cHJvdmlzaW9uZWQgLyBhbHdheXMtb248L3RleHQ+Cjwvc3ZnPg==)

Each DynamoDB table is its own PostgreSQL table; CreateTable and DeleteTable create and drop them.

#### Conditional writes

For a conditional write, the adapter locks the item's row with `SELECT … FOR UPDATE`, checks the `ConditionExpression` against it, then writes and commits. The lock stops another writer from changing the item between the check and the write, at the cost of one extra round trip. For `attribute_not_exists(pk)`, the primary key ensures that only one of two concurrent creates succeeds.

A false condition returns the non-retryable `ConditionalCheckFailed` error and can return the item that failed it. A PostgreSQL serialization failure or lock timeout (`40001` or lock-not-available) returns a retryable throughput error instead, so the SDK backs off and retries. Concurrency failures are never reported as failed conditions.

Some unconditional writes skip the read: a top-level SET or REMOVE update, or an integer counter add, runs as one statement when it has no condition, asks for no returned item and touches no secondary index or stream.

![A conditional write locks the row with SELECT … FOR UPDATE, evaluates the DynamoDB condition in the adapter against the locked row, then writes and commits. A false condition returns ConditionalCheckFailed; a concurrency conflict returns a retryable error, never a condition failure. The primary key prevents duplicate creates.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGNvbmRpdGlvbmFsIHdyaXRlIGxvY2tzIHRoZSByb3cgd2l0aCBTRUxFQ1Qg4oCmIEZPUiBVUERBVEUsIGV2YWx1YXRlcyB0aGUgRHluYW1vREIgY29uZGl0aW9uIGluIHRoZSBhZGFwdGVyIGFnYWluc3QgdGhlIGxvY2tlZCByb3csIHRoZW4gd3JpdGVzIGFuZCBjb21taXRzLiBBIGZhbHNlIGNvbmRpdGlvbiByZXR1cm5zIENvbmRpdGlvbmFsQ2hlY2tGYWlsZWQ7IGEgY29uY3VycmVuY3kgY29uZmxpY3QgcmV0dXJucyBhIHJldHJ5YWJsZSBlcnJvciwgbmV2ZXIgYSBjb25kaXRpb24gZmFpbHVyZS4gVGhlIHByaW1hcnkga2V5IHByZXZlbnRzIGR1cGxpY2F0ZSBjcmVhdGVzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJhNSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPkxvY2sgY3VycmVudCByb3c8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSI3OSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPjx0c3BhbiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5TRUxFQ1Qg4oCmIEZPUiBVUERBVEU8L3RzcGFuPjwvdGV4dD4KPGxpbmUgeDE9IjE3MiIgeTE9IjkwIiB4Mj0iMTcyIiB5Mj0iMTEyIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjEzNCIgcj0iMTMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+PHRleHQgeD0iNDAiIHk9IjEzOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj4yPC90ZXh0Pgo8cmVjdCB4PSI2MiIgeT0iMTE2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSIxMzYiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTIuNXB4Ij5FdmFsdWF0ZSBjb25kaXRpb248L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIxNTMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmFnYWluc3QgdGhlIGxvY2tlZCByb3c8L3RleHQ+CjxsaW5lIHgxPSIxNzIiIHkxPSIxNjQiIHgyPSIxNzIiIHkyPSIxODYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2E1KSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMjA4IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iMjEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPjM8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxOTAiIHdpZHRoPSIyMjAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzYiIHk9IjIxMCIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPldyaXRlICZhbXA7IENPTU1JVDwvdGV4dD4KPHRleHQgeD0iNzYiIHk9IjIyNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmxvY2sgcmVsZWFzZWQgb24gY29tbWl0PC90ZXh0Pgo8bGluZSB4MT0iMjgyIiB5MT0iMTQwIiB4Mj0iMzU0IiB5Mj0iMTQwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSIzNTYiIHk9IjExOCIgd2lkdGg9IjM0MCIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI1MjYiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMnB4Ij5jb25kaXRpb24gZmFsc2Ug4oaSPC90ZXh0Pgo8dGV4dCB4PSI1MjYiIHk9IjE1MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+Q29uZGl0aW9uYWxDaGVja0ZhaWxlZDwvdGV4dD4KPGxpbmUgeDE9IjI4MiIgeTE9IjIxNCIgeDI9IjM1NCIgeTI9IjIxNCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYTUpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iMzU2IiB5PSIxOTIiIHdpZHRoPSIzNDAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZiZWI7c3Ryb2tlOiNmZGU2OGEiLz4KPHRleHQgeD0iNTI2IiB5PSIyMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMnB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojYjQ1MzA5Ij5sb2NrIHRpbWVvdXQgLyA0MDAwMSDihpI8L3RleHQ+Cjx0ZXh0IHg9IjUyNiIgeT0iMjI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojYjQ1MzA5Ij5yZXRyeWFibGUgY29uZmxpY3Q8L3RleHQ+Cjwvc3ZnPg==)

![A conditional write locks the row with SELECT … FOR UPDATE, evaluates the DynamoDB condition in the adapter against the locked row, then writes and commits. A false condition returns ConditionalCheckFailed; a concurrency conflict returns a retryable error, never a condition failure. The primary key prevents duplicate creates.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIGNvbmRpdGlvbmFsIHdyaXRlIGxvY2tzIHRoZSByb3cgd2l0aCBTRUxFQ1Qg4oCmIEZPUiBVUERBVEUsIGV2YWx1YXRlcyB0aGUgRHluYW1vREIgY29uZGl0aW9uIGluIHRoZSBhZGFwdGVyIGFnYWluc3QgdGhlIGxvY2tlZCByb3csIHRoZW4gd3JpdGVzIGFuZCBjb21taXRzLiBBIGZhbHNlIGNvbmRpdGlvbiByZXR1cm5zIENvbmRpdGlvbmFsQ2hlY2tGYWlsZWQ7IGEgY29uY3VycmVuY3kgY29uZmxpY3QgcmV0dXJucyBhIHJldHJ5YWJsZSBlcnJvciwgbmV2ZXIgYSBjb25kaXRpb24gZmFpbHVyZS4gVGhlIHByaW1hcnkga2V5IHByZXZlbnRzIGR1cGxpY2F0ZSBjcmVhdGVzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJhNSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPkxvY2sgY3VycmVudCByb3c8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSI3OSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPjx0c3BhbiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5TRUxFQ1Qg4oCmIEZPUiBVUERBVEU8L3RzcGFuPjwvdGV4dD4KPGxpbmUgeDE9IjE3MiIgeTE9IjkwIiB4Mj0iMTcyIiB5Mj0iMTEyIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjEzNCIgcj0iMTMiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+PHRleHQgeD0iNDAiIHk9IjEzOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj4yPC90ZXh0Pgo8cmVjdCB4PSI2MiIgeT0iMTE2IiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSIxMzYiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTIuNXB4Ij5FdmFsdWF0ZSBjb25kaXRpb248L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIxNTMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmFnYWluc3QgdGhlIGxvY2tlZCByb3c8L3RleHQ+CjxsaW5lIHgxPSIxNzIiIHkxPSIxNjQiIHgyPSIxNzIiIHkyPSIxODYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2E1KSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMjA4IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iMjEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPjM8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxOTAiIHdpZHRoPSIyMjAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzYiIHk9IjIxMCIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPldyaXRlICZhbXA7IENPTU1JVDwvdGV4dD4KPHRleHQgeD0iNzYiIHk9IjIyNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmxvY2sgcmVsZWFzZWQgb24gY29tbWl0PC90ZXh0Pgo8bGluZSB4MT0iMjgyIiB5MT0iMTQwIiB4Mj0iMzU0IiB5Mj0iMTQwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSIzNTYiIHk9IjExOCIgd2lkdGg9IjM0MCIgaGVpZ2h0PSI0NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI1MjYiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMnB4Ij5jb25kaXRpb24gZmFsc2Ug4oaSPC90ZXh0Pgo8dGV4dCB4PSI1MjYiIHk9IjE1MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+Q29uZGl0aW9uYWxDaGVja0ZhaWxlZDwvdGV4dD4KPGxpbmUgeDE9IjI4MiIgeTE9IjIxNCIgeDI9IjM1NCIgeTI9IjIxNCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjYTUpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iMzU2IiB5PSIxOTIiIHdpZHRoPSIzNDAiIGhlaWdodD0iNDQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiM0MjIwMDY7c3Ryb2tlOiM5MjQwMGUiLz4KPHRleHQgeD0iNTI2IiB5PSIyMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMnB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojZmJiZjI0Ij5sb2NrIHRpbWVvdXQgLyA0MDAwMSDihpI8L3RleHQ+Cjx0ZXh0IHg9IjUyNiIgeT0iMjI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojZmJiZjI0Ij5yZXRyeWFibGUgY29uZmxpY3Q8L3RleHQ+Cjwvc3ZnPg==)

Failed conditions and PostgreSQL concurrency conflicts return different error types.

#### Secondary indexes

On each write, the adapter adds two index fields to the item's JSONB. `_idx_<name>_h` holds the index partition key and treats equal numbers such as `1` and `1.0` as the same; `_idx_<name>_o` holds the sort key in sort order, with the base key breaking ties. A PostgreSQL index over these fields finds the items with a matching partition key, and the adapter then applies sort-key conditions, ordering, pagination and any `FilterExpression`.

The index fields are saved in the same transaction as the item, so GSI queries are strongly consistent; DynamoDB's own GSIs update asynchronously. One index lookup can examine at most 10,000 items for a single partition-key value, and a lookup beyond that returns an error, so choose index keys with this limit in mind.

![On each write, the adapter adds two index fields to the item's JSONB, and PostgreSQL keeps an index over them. A GSI query looks up the index, then the adapter filters and orders the results. The index fields are saved with the item, so the index is strongly consistent.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBlYWNoIHdyaXRlLCB0aGUgYWRhcHRlciBhZGRzIHR3byBpbmRleCBmaWVsZHMgdG8gdGhlIGl0ZW0ncyBKU09OQiwgYW5kIFBvc3RncmVTUUwga2VlcHMgYW4gaW5kZXggb3ZlciB0aGVtLiBBIEdTSSBxdWVyeSBsb29rcyB1cCB0aGUgaW5kZXgsIHRoZW4gdGhlIGFkYXB0ZXIgZmlsdGVycyBhbmQgb3JkZXJzIHRoZSByZXN1bHRzLiBUaGUgaW5kZXggZmllbGRzIGFyZSBzYXZlZCB3aXRoIHRoZSBpdGVtLCBzbyB0aGUgaW5kZXggaXMgc3Ryb25nbHkgY29uc2lzdGVudC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iYTYiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzA0Nzg1NyIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJhNnEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzRmNDZlNSIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjEwMSIgeT0iNjUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5QdXRJdGVtPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+c3RhdHVzID0gU0hJUFBFRDwvdGV4dD4KPGxpbmUgeDE9IjE3NiIgeTE9IjY5IiB4Mj0iMjMyIiB5Mj0iNjkiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhNikiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIyMDQiIHk9IjYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmluZGV4IGtleXM8L3RleHQ+CjxyZWN0IHg9IjIzNiIgeT0iMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNzAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzI2IiB5PSI1OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMnB4Ij5pdGVtIEpTT05CPC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9Ijc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij4rIF9pZHhfeF9oIChwYXJ0aXRpb24ga2V5KTwvdGV4dD4KPHRleHQgeD0iMzI2IiB5PSI5MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+KyBfaWR4X3hfbyAoc29ydCBrZXkpPC90ZXh0Pgo8bGluZSB4MT0iMzI2IiB5MT0iMTA0IiB4Mj0iMzI2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTYpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzM4IiB5PSIxMjIiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+c2FtZSB0cmFuc2FjdGlvbjwvdGV4dD4KPHJlY3QgeD0iMjM2IiB5PSIxMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMzI2IiB5PSIxNTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTEuNXB4Ij5Qb3N0Z3JlU1FMIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+b24gKF9pZHhfeF9oLCBfaWR4X3hfbyk8L3RleHQ+CjxyZWN0IHg9IjUwMCIgeT0iNDAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNTgiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTc1IiB5PSI2NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlF1ZXJ5IEdTSTwvdGV4dD4KPHRleHQgeD0iNTc1IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnN0YXR1cyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSI1NzUiIHkxPSI5OCIgeDI9IjU3NSIgeTI9IjE2NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIHN0eWxlPSJzdHJva2U6IzRmNDZlNSIvPgo8bGluZSB4MT0iNTc1IiB5MT0iMTY0IiB4Mj0iNDE4IiB5Mj0iMTY0IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNnEpIiBzdHlsZT0ic3Ryb2tlOiM0ZjQ2ZTUiLz4KPHRleHQgeD0iNDk2IiB5PSIxNTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiM0ZjQ2ZTUiPmluZGV4IGxvb2t1cCArIGZpbHRlcjwvdGV4dD4KPHRleHQgeD0iNjkwIiB5PSI3MCIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NTtmb250LXdlaWdodDo2MDAiPlN0cm9uZ2x5IGNvbnNpc3RlbnQ6PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjkwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dGhlIGl0ZW0gYW5kIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjEwNiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmNvbW1pdCB0b2dldGhlci48L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTMwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+RHluYW1vREIgR1NJcyBhcmU8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+ZXZlbnR1YWxseSBjb25zaXN0ZW50LjwvdGV4dD4KPC9zdmc+)

![On each write, the adapter adds two index fields to the item's JSONB, and PostgreSQL keeps an index over them. A GSI query looks up the index, then the adapter filters and orders the results. The index fields are saved with the item, so the index is strongly consistent.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBlYWNoIHdyaXRlLCB0aGUgYWRhcHRlciBhZGRzIHR3byBpbmRleCBmaWVsZHMgdG8gdGhlIGl0ZW0ncyBKU09OQiwgYW5kIFBvc3RncmVTUUwga2VlcHMgYW4gaW5kZXggb3ZlciB0aGVtLiBBIEdTSSBxdWVyeSBsb29rcyB1cCB0aGUgaW5kZXgsIHRoZW4gdGhlIGFkYXB0ZXIgZmlsdGVycyBhbmQgb3JkZXJzIHRoZSByZXN1bHRzLiBUaGUgaW5kZXggZmllbGRzIGFyZSBzYXZlZCB3aXRoIHRoZSBpdGVtLCBzbyB0aGUgaW5kZXggaXMgc3Ryb25nbHkgY29uc2lzdGVudC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iYTYiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzZlZTdiNyIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJhNnEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2E1YjRmYyIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjEwMSIgeT0iNjUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5QdXRJdGVtPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjgzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+c3RhdHVzID0gU0hJUFBFRDwvdGV4dD4KPGxpbmUgeDE9IjE3NiIgeTE9IjY5IiB4Mj0iMjMyIiB5Mj0iNjkiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhNikiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIyMDQiIHk9IjYwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmluZGV4IGtleXM8L3RleHQ+CjxyZWN0IHg9IjIzNiIgeT0iMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNzAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzI2IiB5PSI1OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMnB4Ij5pdGVtIEpTT05CPC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9Ijc2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij4rIF9pZHhfeF9oIChwYXJ0aXRpb24ga2V5KTwvdGV4dD4KPHRleHQgeD0iMzI2IiB5PSI5MSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+KyBfaWR4X3hfbyAoc29ydCBrZXkpPC90ZXh0Pgo8bGluZSB4MT0iMzI2IiB5MT0iMTA0IiB4Mj0iMzI2IiB5Mj0iMTMyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTYpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzM4IiB5PSIxMjIiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+c2FtZSB0cmFuc2FjdGlvbjwvdGV4dD4KPHJlY3QgeD0iMjM2IiB5PSIxMzQiIHdpZHRoPSIxODAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzI2IiB5PSIxNTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTEuNXB4Ij5Qb3N0Z3JlU1FMIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSIzMjYiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+b24gKF9pZHhfeF9oLCBfaWR4X3hfbyk8L3RleHQ+CjxyZWN0IHg9IjUwMCIgeT0iNDAiIHdpZHRoPSIxNTAiIGhlaWdodD0iNTgiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTc1IiB5PSI2NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlF1ZXJ5IEdTSTwvdGV4dD4KPHRleHQgeD0iNTc1IiB5PSI4MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnN0YXR1cyA9IFNISVBQRUQ8L3RleHQ+CjxsaW5lIHgxPSI1NzUiIHkxPSI5OCIgeDI9IjU3NSIgeTI9IjE2NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIHN0eWxlPSJzdHJva2U6I2E1YjRmYyIvPgo8bGluZSB4MT0iNTc1IiB5MT0iMTY0IiB4Mj0iNDE4IiB5Mj0iMTY0IiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNhNnEpIiBzdHlsZT0ic3Ryb2tlOiNhNWI0ZmMiLz4KPHRleHQgeD0iNDk2IiB5PSIxNTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNhNWI0ZmMiPmluZGV4IGxvb2t1cCArIGZpbHRlcjwvdGV4dD4KPHRleHQgeD0iNjkwIiB5PSI3MCIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMTtmb250LXdlaWdodDo2MDAiPlN0cm9uZ2x5IGNvbnNpc3RlbnQ6PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjkwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dGhlIGl0ZW0gYW5kIGluZGV4PC90ZXh0Pgo8dGV4dCB4PSI2OTAiIHk9IjEwNiIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmNvbW1pdCB0b2dldGhlci48L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTMwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+RHluYW1vREIgR1NJcyBhcmU8L3RleHQ+Cjx0ZXh0IHg9IjY5MCIgeT0iMTQ2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+ZXZlbnR1YWxseSBjb25zaXN0ZW50LjwvdGV4dD4KPC9zdmc+)

A GSI uses a PostgreSQL index to find candidates, which the adapter filters and orders; the index updates with the item.

#### Transactions

`TransactWriteItems` runs in one PostgreSQL transaction at `SERIALIZABLE` isolation: a debit in one table and a credit in another both commit or both fail, as in DynamoDB. DynamoDB's 100-action limit and one-operation-per-item rule apply.

The adapter saves the `ClientRequestToken` in the same transaction, so within DynamoDB's idempotency window a retry with the same token returns the earlier success without writing again. Row locks are taken in a fixed order so opposite transfers do not deadlock, and serialization or deadlock failures return retryable conflicts. A transaction that touches a table with Streams enabled returns `ValidationException` before it runs, because transactions do not write stream records.

![A TransactWriteItems request with a debit in one table and a credit in another commits atomically in one PostgreSQL transaction at SERIALIZABLE isolation, as on DynamoDB.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA2IiB2aWV3Qm94PSIwIDAgODM2IDIwNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIFRyYW5zYWN0V3JpdGVJdGVtcyByZXF1ZXN0IHdpdGggYSBkZWJpdCBpbiBvbmUgdGFibGUgYW5kIGEgY3JlZGl0IGluIGFub3RoZXIgY29tbWl0cyBhdG9taWNhbGx5IGluIG9uZSBQb3N0Z3JlU1FMIHRyYW5zYWN0aW9uIGF0IFNFUklBTElaQUJMRSBpc29sYXRpb24sIGFzIG9uIER5bmFtb0RCLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJhNyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojMDQ3ODU3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPkNST1NTLVRBQkxFIOKGkiBPTkUgQVRPTUlDIENPTU1JVDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjEyNiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIxMDEiIHk9IjY0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPlRyYW5zYWN0V3JpdGU8L3RleHQ+CjxyZWN0IHg9IjQwIiB5PSI3OCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIzNCIgcng9IjciIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTAxIiB5PSI5MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+ZGViaXQ8L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij5kZGJfYWNjb3VudHM8L3RleHQ+CjxyZWN0IHg9IjQwIiB5PSIxMTgiIHdpZHRoPSIxMjIiIGhlaWdodD0iMzQiIHJ4PSI3IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjEwMSIgeT0iMTMzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5jcmVkaXQ8L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iMTQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij5kZGJfbGVkZ2VyPC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iMTAzIiB4Mj0iMjM2IiB5Mj0iMTAzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTcpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjA2IiB5PSI5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj5vbmUgdHhuPC90ZXh0Pgo8cmVjdCB4PSIyNDAiIHk9IjUyIiB3aWR0aD0iMjI4IiBoZWlnaHQ9IjEwMiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzNTQiIHk9Ijc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEycHgiPkJFR0lOIOKApiBDT01NSVQ8L3RleHQ+Cjx0ZXh0IHg9IjM1NCIgeT0iOTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPlNFUklBTElaQUJMRSBpc29sYXRpb248L3RleHQ+Cjx0ZXh0IHg9IjM1NCIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5ib3RoIHRhYmxlcywgYXRvbWljYWxseTwvdGV4dD4KPHRleHQgeD0iMzU0IiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZpbGw6IzMzNDE1NSI+bG9ja3MgdGFrZW4gaW4gYSBmaXhlZCBvcmRlcjwvdGV4dD4KPHRleHQgeD0iMzU0IiB5PSIxNDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZpbGw6IzMzNDE1NSI+Q2xpZW50UmVxdWVzdFRva2VuIOKGkiBjb21taXRzIG9uY2U8L3RleHQ+CjxsaW5lIHgxPSI0ODQiIHkxPSIzNCIgeDI9IjQ4NCIgeTI9IjE3MiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1MDgiIHk9IjY2IiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHg7ZmlsbDojMDQ3ODU3Ij5Dcm9zcy10YWJsZSBBQ0lEPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjkwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMzM0MTU1Ij5EeW5hbW9EQiBhbmQgdGhpcyBiYWNrZW5kPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjEwNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NSI+Y29tbWl0IGFjcm9zcyB0YWJsZXMuPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjEyNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NSI+U3RyZWFtLWVuYWJsZWQgdGFibGVzPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjE0NCIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NSI+cmVqZWN0IHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjE2MSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzMzNDE1NSI+cmVxdWVzdHMuPC90ZXh0Pgo8L3N2Zz4=)

![A TransactWriteItems request with a debit in one table and a credit in another commits atomically in one PostgreSQL transaction at SERIALIZABLE isolation, as on DynamoDB.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjA2IiB2aWV3Qm94PSIwIDAgODM2IDIwNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIFRyYW5zYWN0V3JpdGVJdGVtcyByZXF1ZXN0IHdpdGggYSBkZWJpdCBpbiBvbmUgdGFibGUgYW5kIGEgY3JlZGl0IGluIGFub3RoZXIgY29tbWl0cyBhdG9taWNhbGx5IGluIG9uZSBQb3N0Z3JlU1FMIHRyYW5zYWN0aW9uIGF0IFNFUklBTElaQUJMRSBpc29sYXRpb24sIGFzIG9uIER5bmFtb0RCLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJhNyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNmVlN2I3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8dGV4dCB4PSIyNiIgeT0iMjgiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPkNST1NTLVRBQkxFIOKGkiBPTkUgQVRPTUlDIENPTU1JVDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjQwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjEyNiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIxMDEiIHk9IjY0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPlRyYW5zYWN0V3JpdGU8L3RleHQ+CjxyZWN0IHg9IjQwIiB5PSI3OCIgd2lkdGg9IjEyMiIgaGVpZ2h0PSIzNCIgcng9IjciIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTAxIiB5PSI5MyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+ZGViaXQ8L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iMTA2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij5kZGJfYWNjb3VudHM8L3RleHQ+CjxyZWN0IHg9IjQwIiB5PSIxMTgiIHdpZHRoPSIxMjIiIGhlaWdodD0iMzQiIHJ4PSI3IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjEwMSIgeT0iMTMzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5jcmVkaXQ8L3RleHQ+Cjx0ZXh0IHg9IjEwMSIgeT0iMTQ2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij5kZGJfbGVkZ2VyPC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iMTAzIiB4Mj0iMjM2IiB5Mj0iMTAzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYTcpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjA2IiB5PSI5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj5vbmUgdHhuPC90ZXh0Pgo8cmVjdCB4PSIyNDAiIHk9IjUyIiB3aWR0aD0iMjI4IiBoZWlnaHQ9IjEwMiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzNTQiIHk9Ijc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEycHgiPkJFR0lOIOKApiBDT01NSVQ8L3RleHQ+Cjx0ZXh0IHg9IjM1NCIgeT0iOTYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPlNFUklBTElaQUJMRSBpc29sYXRpb248L3RleHQ+Cjx0ZXh0IHg9IjM1NCIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5ib3RoIHRhYmxlcywgYXRvbWljYWxseTwvdGV4dD4KPHRleHQgeD0iMzU0IiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZpbGw6I2NiZDVlMSI+bG9ja3MgdGFrZW4gaW4gYSBmaXhlZCBvcmRlcjwvdGV4dD4KPHRleHQgeD0iMzU0IiB5PSIxNDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZpbGw6I2NiZDVlMSI+Q2xpZW50UmVxdWVzdFRva2VuIOKGkiBjb21taXRzIG9uY2U8L3RleHQ+CjxsaW5lIHgxPSI0ODQiIHkxPSIzNCIgeDI9IjQ4NCIgeTI9IjE3MiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1MDgiIHk9IjY2IiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHg7ZmlsbDojNmVlN2I3Ij5Dcm9zcy10YWJsZSBBQ0lEPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjkwIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojY2JkNWUxIj5EeW5hbW9EQiBhbmQgdGhpcyBiYWNrZW5kPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjEwNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMSI+Y29tbWl0IGFjcm9zcyB0YWJsZXMuPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjEyNyIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMSI+U3RyZWFtLWVuYWJsZWQgdGFibGVzPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjE0NCIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMSI+cmVqZWN0IHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI1MDgiIHk9IjE2MSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjg7IGZpbGw6I2NiZDVlMSI+cmVxdWVzdHMuPC90ZXh0Pgo8L3N2Zz4=)

TransactWriteItems runs in one PostgreSQL transaction at SERIALIZABLE isolation, atomic across tables.

#### Limitations

* **Hot keys behave differently: one PostgreSQL instance holds each table.** Heavy contention on one key causes serialization failures and row-lock conflicts. The adapter returns retryable errors, but sustained contention can use up the SDK's retry budget and appear as throttling.
* **You must run one writer per table with Streams enabled.** A writer lease of about 90 seconds keeps stream records in order; a second adapter instance writing during the lease gets a retryable `ThrottlingException`. Throughput depends on the writer, database and workload. Tables without streams accept concurrent writers.
* **Listing more than 100 shards in `DescribeStream` is not supported.** A stream with more shards is not fully listed in one call.
* **Transactions on tables with Streams enabled are not supported.** A `TransactWriteItems` request touching one returns `ValidationException`, because transactions do not write stream records.
* **DynamoDB backup and global-table APIs are not supported.** On-demand backup and restore, point-in-time recovery (PITR) and global-table replication APIs are not available. Use PostgreSQL backups, snapshots, PITR and replica failover instead.
* **Capacity behaves differently: it is provisioned and billed while idle.** Size PostgreSQL capacity ahead of demand. More tables need more instances and table-placement planning.
* **Index lookups over 10,000 items are not supported.** A lookup that examines more than 10,000 items for one index partition-key value returns an error.
* **You must plan around the 500-table limit.** The adapter checks 500 DynamoDB tables per namespace. Larger deployments need database capacity and table-placement planning.
* **Expired items behave differently: they stay readable until deleted.** A background job deletes expired rows through the TTL index in bounded batches. Until then, `GetItem`, `Query` and `Scan` can return the item, and it still uses storage.

#### Other considerations

* **Stream records.** Each change record is saved in the table's `_strm` table in the same transaction as the write, so a record exists only if its write committed. The single-writer lease keeps record order equal to commit order, so a reader can resume without skipping records.
* **Connections.** The adapter pools PostgreSQL connections. With many adapter instances, you may need a separate pooler to keep total connections under the database's limit.
* **Moving data.** Move and test one table at a time, by export and import, dual writes or backfill and switch. Application code keeps using the DynamoDB API.
* **Operations.** Monitor SQL activity, maintain indexes, vacuum tables and run backups, PITR and failover with your usual PostgreSQL tools.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### Monthly cost by DynamoDB point-read rate

Reference monthly service charges by Read operations/s. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![Monthly cost by DynamoDB point-read rate: monthly service charges by Read operations/s. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/cf2a4e1abb3405b33519d47b51b1e2c6a50db394e593ed31b36c560f71d2061d-light.svg)

![Monthly cost by DynamoDB point-read rate: monthly service charges by Read operations/s. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/2e7ed433f987ddf36fe845381cc0b58d3a25dabdb5d8292a1d10a1252ca7aa2d-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Read operations/s (reads/s) | DynamoDB | Target scenario | Cloud SQL for PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 25.00 | Cloud SQL for PostgreSQL (HA) | 270.36 | 245.36 |
| 0 | 25.00 | Cloud SQL for PostgreSQL (zonal) | 135.18 | 110.18 |
| 1 | 25.49 | Cloud SQL for PostgreSQL (HA) | 270.36 | 244.86 |
| 1 | 25.49 | Cloud SQL for PostgreSQL (zonal) | 135.18 | 109.69 |
| 10 | 29.93 | Cloud SQL for PostgreSQL (HA) | 270.36 | 240.43 |
| 10 | 29.93 | Cloud SQL for PostgreSQL (zonal) | 135.18 | 105.25 |
| 100 | 74.28 | Cloud SQL for PostgreSQL (HA) | 270.36 | 196.08 |
| 100 | 74.28 | Cloud SQL for PostgreSQL (zonal) | 135.18 | 60.90 |
| 1,000 | 517.75 | Cloud SQL for PostgreSQL (HA) | 270.36 | -247.39 |
| 1,000 | 517.75 | Cloud SQL for PostgreSQL (zonal) | 135.18 | -382.57 |
| 10,000 | 4,952.50 | Cloud SQL for PostgreSQL (HA) | 270.36 | -4,682.14 |
| 10,000 | 4,952.50 | Cloud SQL for PostgreSQL (zonal) | 135.18 | -4,817.32 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud SQL for PostgreSQL (HA) | Representative DynamoDB item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (HA) | Strongly consistent origin reads | 1 | 0 = eventual, 1 = strong |
| Cloud SQL for PostgreSQL (HA) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (HA) | Cloud SQL vCPUs | 2 | vCPU |
| Cloud SQL for PostgreSQL (HA) | Cloud SQL memory | 8 | GiB |
| Cloud SQL for PostgreSQL (HA) | Provisioned Cloud SQL SSD | 200 | GiB |
| Cloud SQL for PostgreSQL (HA) | Cloud SQL high availability | 1 | 0 = zonal, 1 = HA |
| Cloud SQL for PostgreSQL (HA) | Share of database cost allocated here | 1 | fraction |
| Cloud SQL for PostgreSQL (zonal) | Representative DynamoDB item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (zonal) | Strongly consistent origin reads | 1 | 0 = eventual, 1 = strong |
| Cloud SQL for PostgreSQL (zonal) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (zonal) | Cloud SQL vCPUs | 2 | vCPU |
| Cloud SQL for PostgreSQL (zonal) | Cloud SQL memory | 8 | GiB |
| Cloud SQL for PostgreSQL (zonal) | Provisioned Cloud SQL SSD | 200 | GiB |
| Cloud SQL for PostgreSQL (zonal) | Cloud SQL high availability | 0 | 0 = zonal, 1 = HA |
| Cloud SQL for PostgreSQL (zonal) | Share of database cost allocated here | 1 | fraction |

* Strong 1 KiB point reads and plain writes; one write per ten reads, no origin index amplification. 730 hours/month; retained source data stays at 100 GiB. Cloud SQL has 2 vCPU, 8 GiB memory and 200 GiB SSD. Twice source storage is an authored reserve, not a measured sizing rule; throughput remains unqualified.
* Monthly AWS source usage in us-east-1, priced at the 2026-10-18 reference list rates before free allowances, discounts, credits and tax; not the uploaded invoice total. Rates as of 2026-10-18: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Cloud SQL configuration pricing only: throughput, peak load, latency and storage suitability are unqualified. No capacity benchmark is implied.
* 730 running hours per modeled month. Dedicated database compute and disk cost money even with zero origin traffic.
* Shared database allocation is a caller assumption. Do not sum a full database charge for every adapter sharing that database.
* Origin workload is point GetItem and plain PutItem on Standard on-demand tables. Queries, transactions and Streams are not modeled.
* Source usage is priced at reference rates; source lines are not actual invoice charges. Free or discounted usage still consumes target resources.
* AWS DynamoDB Standard on-demand pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Cloud SQL Enterprise PostgreSQL pricing: [https://cloud.google.com/sql/pricing/](https://cloud.google.com/sql/pricing/)

Cost scope: Modeled monthly service usage and selected database allocation; adapter hosting and Tensor9 fees only when explicitly supplied.

Excluded costs and workload features:

* Free allowances, negotiated discounts, credits, tax and one-time migration charges.
* Charges not listed in the breakdown, including additional network transfer, backups and encryption/KMS.
* Application compute changes, operational labor and portfolio-wide sharing or deduplication of infrastructure.
* DynamoDB provisioned capacity, global replicas, transactions, queries/scans and Streams; unqualified database sizing.

Rate snapshot: 2026-10-18. Model: `dynamodb-cloudsql` / `2026-10-18.4`. Curve: `read-rate`.

Sources: [AWS DynamoDB Standard on-demand pricing](https://aws.amazon.com/dynamodb/pricing/), [Cloud SQL Enterprise PostgreSQL pricing](https://cloud.google.com/sql/pricing/).

##### Monthly cost by retained DynamoDB data

Reference monthly service charges by Retained source data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![Monthly cost by retained DynamoDB data: monthly service charges by Retained source data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/21eed1eca1b0d370ddb2846f1fa42374e38eba406ca5691f76c2c6159b570559-light.svg)

![Monthly cost by retained DynamoDB data: monthly service charges by Retained source data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/d4b3080d083c763aefbe42d5e2adc883ad8c518ced91c8486027c82f18d07816-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Retained source data (GiB-month) | DynamoDB | Target scenario | Cloud SQL for PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 18.75 | Cloud SQL for PostgreSQL (HA) | 205.76 | 187.01 |
| 0 | 18.75 | Cloud SQL for PostgreSQL (zonal) | 102.88 | 84.13 |
| 10 | 21.25 | Cloud SQL for PostgreSQL (HA) | 209.16 | 187.91 |
| 10 | 21.25 | Cloud SQL for PostgreSQL (zonal) | 104.58 | 83.33 |
| 100 | 43.75 | Cloud SQL for PostgreSQL (HA) | 270.36 | 226.61 |
| 100 | 43.75 | Cloud SQL for PostgreSQL (zonal) | 135.18 | 91.43 |
| 1,000 | 268.75 | Cloud SQL for PostgreSQL (HA) | 882.36 | 613.61 |
| 1,000 | 268.75 | Cloud SQL for PostgreSQL (zonal) | 441.18 | 172.43 |
| 10,000 | 2,518.75 | Cloud SQL for PostgreSQL (HA) | 7,002.36 | 4,483.61 |
| 10,000 | 2,518.75 | Cloud SQL for PostgreSQL (zonal) | 3,501.18 | 982.43 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud SQL for PostgreSQL (HA) | Representative DynamoDB item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (HA) | Strongly consistent origin reads | 1 | 0 = eventual, 1 = strong |
| Cloud SQL for PostgreSQL (HA) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (HA) | Cloud SQL vCPUs | 2 | vCPU |
| Cloud SQL for PostgreSQL (HA) | Cloud SQL memory | 8 | GiB |
| Cloud SQL for PostgreSQL (HA) | Provisioned Cloud SQL SSD | 10 | GiB |
| Cloud SQL for PostgreSQL (HA) | Cloud SQL high availability | 1 | 0 = zonal, 1 = HA |
| Cloud SQL for PostgreSQL (HA) | Share of database cost allocated here | 1 | fraction |
| Cloud SQL for PostgreSQL (zonal) | Representative DynamoDB item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (zonal) | Strongly consistent origin reads | 1 | 0 = eventual, 1 = strong |
| Cloud SQL for PostgreSQL (zonal) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (zonal) | Cloud SQL vCPUs | 2 | vCPU |
| Cloud SQL for PostgreSQL (zonal) | Cloud SQL memory | 8 | GiB |
| Cloud SQL for PostgreSQL (zonal) | Provisioned Cloud SQL SSD | 10 | GiB |
| Cloud SQL for PostgreSQL (zonal) | Cloud SQL high availability | 0 | 0 = zonal, 1 = HA |
| Cloud SQL for PostgreSQL (zonal) | Share of database cost allocated here | 1 | fraction |

* Source traffic stays at 100 million strong 1 KiB read units and 10 million plain write units/month, with no origin index amplification. Cloud SQL uses 2 vCPU and 8 GiB memory; SSD provision is twice source GiB, rounded up to whole GiB with a 10 GiB minimum. This reserve is an authored assumption, not a measured expansion factor or capacity qualification.
* Monthly AWS source usage in us-east-1, priced at the 2026-10-18 reference list rates before free allowances, discounts, credits and tax; not the uploaded invoice total. Rates as of 2026-10-18: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Cloud SQL configuration pricing only: throughput, peak load, latency and storage suitability are unqualified. No capacity benchmark is implied.
* 730 running hours per modeled month. Dedicated database compute and disk cost money even with zero origin traffic.
* Shared database allocation is a caller assumption. Do not sum a full database charge for every adapter sharing that database.
* Origin workload is point GetItem and plain PutItem on Standard on-demand tables. Queries, transactions and Streams are not modeled.
* Source usage is priced at reference rates; source lines are not actual invoice charges. Free or discounted usage still consumes target resources.
* AWS DynamoDB Standard on-demand pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Cloud SQL Enterprise PostgreSQL pricing: [https://cloud.google.com/sql/pricing/](https://cloud.google.com/sql/pricing/)

Cost scope: Modeled monthly service usage and selected database allocation; adapter hosting and Tensor9 fees only when explicitly supplied.

Excluded costs and workload features:

* Free allowances, negotiated discounts, credits, tax and one-time migration charges.
* Charges not listed in the breakdown, including additional network transfer, backups and encryption/KMS.
* Application compute changes, operational labor and portfolio-wide sharing or deduplication of infrastructure.
* DynamoDB provisioned capacity, global replicas, transactions, queries/scans and Streams; unqualified database sizing.

Rate snapshot: 2026-10-18. Model: `dynamodb-cloudsql` / `2026-10-18.4`. Curve: `retained-data`.

Sources: [AWS DynamoDB Standard on-demand pricing](https://aws.amazon.com/dynamodb/pricing/), [Cloud SQL Enterprise PostgreSQL pricing](https://cloud.google.com/sql/pricing/).

**DynamoDB → Cloud SQL for PostgreSQL: Reference monthly workload.** Monthly AWS usage charges at the 2026-10-18 reference list rates in us-east-1, before free allowances, discounts, credits and tax.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 12.50 |
| Origin: DynamoDB write units | 6.25 |
| Origin: DynamoDB stored data | 25.00 |
| Target: Allocated Cloud SQL Enterprise CPU | 120.60 |
| Target: Allocated Cloud SQL Enterprise memory | 81.76 |
| Target: Allocated Cloud SQL SSD | 34.00 |
| **Origin service subtotal** | **43.75** |
| **Target service subtotal** | **236.36** |

Unestimated components: Allocated adapter hosting, Allocated Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled monthly service usage and selected database allocation; adapter hosting and Tensor9 fees only when explicitly supplied.

Excluded costs and workload features:

* Free allowances, negotiated discounts, credits, tax and one-time migration charges.
* Charges not listed in the breakdown, including additional network transfer, backups and encryption/KMS.
* Application compute changes, operational labor and portfolio-wide sharing or deduplication of infrastructure.
* DynamoDB provisioned capacity, global replicas, transactions, queries/scans and Streams; unqualified database sizing.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| DynamoDB on-demand reads | 12.5 | USD/month |
| DynamoDB on-demand writes | 6.25 | USD/month |
| DynamoDB Standard storage | 25 | USD/month |
| Representative DynamoDB item size | 1,024 | bytes |
| Strongly consistent origin reads | 1 | 0 = eventual, 1 = strong |
| Origin write-unit amplification | 1 | multiplier |
| Cloud SQL vCPUs | 2 | vCPU |
| Cloud SQL memory | 8 | GiB |
| Provisioned Cloud SQL SSD | 100 | GiB |
| Cloud SQL high availability | 1 | 0 = zonal, 1 = HA |
| Share of database cost allocated here | 1 | fraction |

* Inferred point reads: 100,000,000 calls/month.

* Inferred base item writes: 10,000,000 calls/month.

* Origin billed storage: 100 GiB-month.

* Cloud SQL configuration pricing only: throughput, peak load, latency and storage suitability are unqualified. No capacity benchmark is implied.

* 730 running hours per modeled month. Dedicated database compute and disk cost money even with zero origin traffic.

* Shared database allocation is a caller assumption. Do not sum a full database charge for every adapter sharing that database.

* Origin workload is point GetItem and plain PutItem on Standard on-demand tables. Queries, transactions and Streams are not modeled.

Rate snapshot: 2026-10-18. Model: `dynamodb-cloudsql` / `2026-10-18.4`. Scenario: `dynamodb-cloudsql-reference`.

Sources: [AWS DynamoDB Standard on-demand pricing](https://aws.amazon.com/dynamodb/pricing/), [Cloud SQL Enterprise PostgreSQL pricing](https://cloud.google.com/sql/pricing/).

## On OCI

### OCI NoSQL Database

| Capability | Area | Support | Operations | Notes |
| - | - | - | - | - |
| aws\_dynamodb\_table provisioning | Infrastructure | Partial | - | creates oci\_nosql\_table with the mapped key schema and capacity settings; review storage, index, TTL and integration differences |
| DynamoDB item and table-management requests | Runtime API | Out of scope | - | this OCI NoSQL mapping has no DynamoDB API translator; use OCI NoSQL APIs and SDKs |

#### Infrastructure mapping

Tensor9 converts the declared aws\_dynamodb\_table to an oci\_nosql\_table in the customer's OCI compartment. This is the infrastructure-only adaptation: it provisions storage but does not provide an AWS DynamoDB endpoint. Application reads, writes, queries and runtime table administration use OCI NoSQL APIs. The table and control pages describe this same backend choice.

#### Keys and item data

The DynamoDB partition key becomes the OCI SHARD key. An optional sort key becomes the second primary-key column. String, number and binary key types become corresponding OCI column types; other item attributes occupy a value JSON column. Adapt queries and serialization to that layout rather than sending DynamoDB attribute documents directly.

#### Capacity and storage

PAY\_PER\_REQUEST selects OCI ON\_DEMAND; provisioned DynamoDB capacity selects OCI PROVISIONED settings. OCI read and write units differ from DynamoDB units, so validate them against the workload. OCI also requires an explicit storage cap. Increase that cap before data reaches it; the source DynamoDB table had no equivalent fixed cap.

#### Indexes, expiry and integrations

The current infrastructure mapping does not create declared GSIs or LSIs. Configure native OCI indexes and update the application's access patterns. A source TTL declaration produces a no-expiry default; its per-item epoch attribute is not translated into automatic expiry. DynamoDB Streams, AWS PITR configuration, source KMS key references and replica settings are not reproduced by this table resource. Configure the corresponding backend data-protection and event requirements separately.

#### Migration and operation

The new table starts empty. Convert application access, load the data, and test key lookups, queries, expiry and recovery before switching traffic. Oracle operates the NoSQL service; the customer manages compartment access, capacity, storage limits and the chosen recovery procedures. Use a different listed adaptation when the application must keep runtime DynamoDB API calls.

#### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

**Native or deployment mapping.** The application uses the OCI NoSQL API on this mapping. It does not provide a DynamoDB request translator, so DynamoDB fabric latency does not apply. Cost estimates describe the selected service resources; operation coverage remains separate.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-ashburn-1 (global list); currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/e9d4806414954cdb8a28cb7522acca37b5c68defb92c2f8a67d3719216681f41-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/17ea672e2636885eb1d9b047ef059e2705bb624788a1033478ae353d0d90cafe-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | OCI NoSQL Database | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 0.33 | 0.16 | -0.17 |
| 10 | 3.29 | 1.57 | -1.72 |
| 100 | 32.85 | 15.70 | -17.15 |
| 1,000 | 328.50 | 156.99 | -171.51 |
| 10,000 | 3,285.00 | 1,569.89 | -1,715.11 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000000597 | USD/read |
| Target list price · write | 0.0000011705 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.066 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-ashburn-1 (global list), USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Native/deployment comparison scope: The application uses the OCI NoSQL API on this mapping. It does not provide a DynamoDB request translator, so DynamoDB fabric latency does not apply.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Oracle NoSQL Database Cloud on-demand capacity bills consumed 1 KB read and write units and stored GB. Absolute-consistency reads cost two read units; larger records cost one unit per KB. Provisioned capacity (USD 0.0064 per read unit-month and 0.1254 per write unit-month, parts B89738 and B89737) and the Always Free tables are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* OCI price list API: [https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-d4b2a3538a1c61e563246f36c48dc1568328d822` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [OCI price list API](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-ashburn-1 (global list); currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/326071fedd417ddf54e87be9f953dec36c14e43713aaa431690dbdc2bae8069e-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/ba040c83d26b707872951942a219f9e1b4bf07849b5bb8e9d10ba31ea6378657-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | OCI NoSQL Database | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 1.64 | 3.08 | 1.43 |
| 10 | 16.43 | 30.76 | 14.34 |
| 100 | 164.25 | 307.60 | 143.35 |
| 1,000 | 1,642.50 | 3,076.01 | 1,433.51 |
| 10,000 | 16,425.00 | 30,760.08 | 14,335.08 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000000597 | USD/read |
| Target list price · write | 0.0000011705 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.066 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-ashburn-1 (global list), USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Native/deployment comparison scope: The application uses the OCI NoSQL API on this mapping. It does not provide a DynamoDB request translator, so DynamoDB fabric latency does not apply.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Oracle NoSQL Database Cloud on-demand capacity bills consumed 1 KB read and write units and stored GB. Absolute-consistency reads cost two read units; larger records cost one unit per KB. Provisioned capacity (USD 0.0064 per read unit-month and 0.1254 per write unit-month, parts B89738 and B89737) and the Always Free tables are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* OCI price list API: [https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-d4b2a3538a1c61e563246f36c48dc1568328d822` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [OCI price list API](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-ashburn-1 (global list); currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/75c9397485a9166de32d73b4ecad392b7dee9224c3061c5cbde880ac1ad5b55c-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/8adc345c56e772d47603c2eb55ee6ea7be8335491d7b9e3f07e2590a801dee93-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | OCI NoSQL Database | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 10 | 2.50 | 0.66 | -1.84 |
| 100 | 25.00 | 6.60 | -18.40 |
| 1,000 | 250.00 | 66.00 | -184.00 |
| 10,000 | 2,500.00 | 660.00 | -1,840.00 |
| 100,000 | 25,000.00 | 6,600.00 | -18,400.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000000597 | USD/read |
| Target list price · write | 0.0000011705 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.066 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-ashburn-1 (global list), USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Native/deployment comparison scope: The application uses the OCI NoSQL API on this mapping. It does not provide a DynamoDB request translator, so DynamoDB fabric latency does not apply.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Oracle NoSQL Database Cloud on-demand capacity bills consumed 1 KB read and write units and stored GB. Absolute-consistency reads cost two read units; larger records cost one unit per KB. Provisioned capacity (USD 0.0064 per read unit-month and 0.1254 per write unit-month, parts B89738 and B89737) and the Always Free tables are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* OCI price list API: [https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-d4b2a3538a1c61e563246f36c48dc1568328d822` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [OCI price list API](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/).

**DynamoDB → OCI NoSQL Database: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-ashburn-1 (global list). Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Target read operations | 0.00 |
| Target: Target write operations | 0.00 |
| Target: Target retained physical data | 0.00 |
| Target: Additional broker replica storage | 0.00 |
| Target: Execution or worker CPU | 0.00 |
| Target: Execution or worker RAM | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent native resources | 0.00 |
| Target: Independent native resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **0.00** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000000597 | USD/read |
| Target list price · write | 0.0000011705 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.066 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Native/deployment comparison scope: The application uses the OCI NoSQL API on this mapping. It does not provide a DynamoDB request translator, so DynamoDB fabric latency does not apply.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Oracle NoSQL Database Cloud on-demand capacity bills consumed 1 KB read and write units and stored GB. Absolute-consistency reads cost two read units; larger records cost one unit per KB. Provisioned capacity (USD 0.0064 per read unit-month and 0.1254 per write unit-month, parts B89738 and B89737) and the Always Free tables are not selected.

List prices read: 2026-10-22. Model: `plan-d4b2a3538a1c61e563246f36c48dc1568328d822` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [OCI price list API](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/).

## Table administration

Table administration and item operations use separate adapter surfaces, but they select the same target backend.

### On Akamai, DigitalOcean, Private Kubernetes, and Scaleway

#### PostgreSQL

##### Table administration on Tensor9-managed PostgreSQL

The application's DynamoDB client sends table-management requests to the Tensor9 adapter in the target environment. The control endpoint and the table endpoint use the same backend database. Tensor9 deploys PostgreSQL with the Cloud Adapter deployment and serves the DynamoDB control API through the adapter. CreateTable creates the item table, secondary indexes and registry metadata inside that database. Applications continue to use DynamoDB table names and key definitions.

##### Capacity settings

Capacity comes from the database resources allocated in the target environment. DynamoDB billing-mode changes remain table metadata and do not resize the deployment. The adapter applies a 500-table guardrail per namespace, so deployments with larger table fleets need a different layout or backend.

##### Deletion and durable state

Creation writes the table schema and registry together in a PostgreSQL transaction. Deletion drops the item table and its stream change log and removes table metadata and stream-owner records in the same transaction. ListTables reports the surviving registry entries.

##### Configuration and retry constraints

Time-to-live configuration builds the required index before enabling expiry. Table creation, deletion and index work consume the same database resources used by item requests. Size the deployment for both schema changes and steady application traffic.

##### Operating the backend

Tensor9 operates this database within the Cloud Adapter deployment, including disconnected deployments, rather than relying on a cloud-managed PostgreSQL service. Storage durability, backup and recovery depend on the Cloud Adapter deployment configuration and available customer infrastructure. The DynamoDB table contract remains the same PostgreSQL-backed contract described for the managed backend. Registry version 1.0.0 is not the database version. Qualify the selected PostgreSQL image/version, DynamoDB SIP revision, schema and coupled control/table configuration; this profile does not establish an installed version or Kubernetes readiness, and SQS qualification does not qualify DynamoDB.

##### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/7de6a41211e0eb618cd1964828b7df7f98da447b28efe9a51f93524e99b6c14b-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/613f28a3398f525db420f29c15b2ca728dcc7429f5d01ff38de313b762dec45c-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Target scenario | PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | PostgreSQL (one copy) | 80.90 | 80.90 |
| 0 | 0.00 | PostgreSQL (two copies) | 161.79 | 161.79 |
| 1 | 0.33 | PostgreSQL (one copy) | 80.90 | 80.57 |
| 1 | 0.33 | PostgreSQL (two copies) | 161.79 | 161.46 |
| 10 | 3.29 | PostgreSQL (one copy) | 80.90 | 77.61 |
| 10 | 3.29 | PostgreSQL (two copies) | 161.79 | 158.51 |
| 100 | 32.85 | PostgreSQL (one copy) | 80.90 | 48.05 |
| 100 | 32.85 | PostgreSQL (two copies) | 161.79 | 128.94 |
| 1,000 | 328.50 | PostgreSQL (one copy) | 80.90 | -247.60 |
| 1,000 | 328.50 | PostgreSQL (two copies) | 161.79 | -166.71 |
| 10,000 | 3,285.00 | PostgreSQL (one copy) | 1,144.34 | -2,140.66 |
| 10,000 | 3,285.00 | PostgreSQL (two copies) | 2,288.68 | -996.32 |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 32 vCPU, 128 GiB memory and 100 GiB SSD at 10,000 per second.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| PostgreSQL (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (one copy) | Representative item size | 1,024 | bytes |
| PostgreSQL (one copy) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (one copy) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (one copy) | Target reads per point read | 1 | operations |
| PostgreSQL (one copy) | Target writes per item write | 1 | operations |
| PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (one copy) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (one copy) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (one copy) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (one copy) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| PostgreSQL (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (two copies) | Representative item size | 1,024 | bytes |
| PostgreSQL (two copies) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (two copies) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (two copies) | Target reads per point read | 1 | operations |
| PostgreSQL (two copies) | Target writes per item write | 1 | operations |
| PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (two copies) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (two copies) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (two copies) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (two copies) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Self-hosted target: PostgreSQL (PostgreSQL License, [https://www.postgresql.org/about/licence/](https://www.postgresql.org/about/licence/)). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer's Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.
* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.
* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
* Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB ([https://docs.cloud.google.com/compute/docs/general-purpose-machines](https://docs.cloud.google.com/compute/docs/general-purpose-machines)); a Persistent Disk volume holds up to 64 TiB ([https://docs.cloud.google.com/compute/docs/disks/persistent-disks](https://docs.cloud.google.com/compute/docs/disks/persistent-disks)).
* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.
* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Compute Engine general-purpose machine pricing: [https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose)
* Disk and image pricing: [https://cloud.google.com/compute/disks-image-pricing](https://cloud.google.com/compute/disks-image-pricing)
* Network pricing: [https://cloud.google.com/vpc/network-pricing](https://cloud.google.com/vpc/network-pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-67ab648398db063f54620ef99fe9513d4263793e` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/added456832698012afd2e92c8a1bd0981ba6a1f2798ec6fa8fec78745a06582-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/7f8bdf40ebbea0ed1102c06aa92bef45abd075a62614a27852da01b7e8c46c46-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Target scenario | PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | PostgreSQL (one copy) | 80.90 | 80.90 |
| 0 | 0.00 | PostgreSQL (two copies) | 161.79 | 161.79 |
| 1 | 1.64 | PostgreSQL (one copy) | 80.90 | 79.25 |
| 1 | 1.64 | PostgreSQL (two copies) | 161.79 | 160.15 |
| 10 | 16.43 | PostgreSQL (one copy) | 80.90 | 64.47 |
| 10 | 16.43 | PostgreSQL (two copies) | 161.79 | 145.37 |
| 100 | 164.25 | PostgreSQL (one copy) | 80.90 | -83.35 |
| 100 | 164.25 | PostgreSQL (two copies) | 161.79 | -2.46 |
| 1,000 | 1,642.50 | PostgreSQL (one copy) | 80.90 | -1,561.60 |
| 1,000 | 1,642.50 | PostgreSQL (two copies) | 161.79 | -1,480.71 |
| 10,000 | 16,425.00 | PostgreSQL (one copy) | 1,144.34 | -15,280.66 |
| 10,000 | 16,425.00 | PostgreSQL (two copies) | 2,288.68 | -14,136.32 |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 32 vCPU, 128 GiB memory and 100 GiB SSD at 10,000 per second.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| PostgreSQL (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (one copy) | Representative item size | 1,024 | bytes |
| PostgreSQL (one copy) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (one copy) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (one copy) | Target reads per point read | 1 | operations |
| PostgreSQL (one copy) | Target writes per item write | 1 | operations |
| PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (one copy) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (one copy) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (one copy) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (one copy) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| PostgreSQL (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (two copies) | Representative item size | 1,024 | bytes |
| PostgreSQL (two copies) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (two copies) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (two copies) | Target reads per point read | 1 | operations |
| PostgreSQL (two copies) | Target writes per item write | 1 | operations |
| PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (two copies) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (two copies) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (two copies) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (two copies) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Self-hosted target: PostgreSQL (PostgreSQL License, [https://www.postgresql.org/about/licence/](https://www.postgresql.org/about/licence/)). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer's Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.
* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.
* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
* Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB ([https://docs.cloud.google.com/compute/docs/general-purpose-machines](https://docs.cloud.google.com/compute/docs/general-purpose-machines)); a Persistent Disk volume holds up to 64 TiB ([https://docs.cloud.google.com/compute/docs/disks/persistent-disks](https://docs.cloud.google.com/compute/docs/disks/persistent-disks)).
* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.
* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Compute Engine general-purpose machine pricing: [https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose)
* Disk and image pricing: [https://cloud.google.com/compute/disks-image-pricing](https://cloud.google.com/compute/disks-image-pricing)
* Network pricing: [https://cloud.google.com/vpc/network-pricing](https://cloud.google.com/vpc/network-pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-67ab648398db063f54620ef99fe9513d4263793e` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/84a517b1df5a949a2f9b0ba4a09df8ee4e51f363ef98bfd97c2edd5291eb795c-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/cda462fd8112cd349b433eb859ceefcb6afd87a33d351d049fa3a1698ba2bf59-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Target scenario | PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | PostgreSQL (one copy) | 80.90 | 80.90 |
| 0 | 0.00 | PostgreSQL (two copies) | 161.79 | 161.79 |
| 10 | 2.50 | PostgreSQL (one copy) | 80.90 | 78.40 |
| 10 | 2.50 | PostgreSQL (two copies) | 161.79 | 159.29 |
| 100 | 25.00 | PostgreSQL (one copy) | 92.08 | 67.08 |
| 100 | 25.00 | PostgreSQL (two copies) | 184.16 | 159.16 |
| 1,000 | 250.00 | PostgreSQL (one copy) | 806.02 | 556.02 |
| 1,000 | 250.00 | PostgreSQL (two copies) | 1,612.03 | 1,362.03 |
| 10,000 | 2,500.00 | PostgreSQL (one copy) | 6,878.59 | 4,378.59 |
| 10,000 | 2,500.00 | PostgreSQL (two copies) | 13,757.18 | 11,257.18 |
| 100,000 | 25,000.00 | PostgreSQL (one copy) | Unpriced | Unavailable |
| 100,000 | 25,000.00 | PostgreSQL (two copies) | Unpriced | Unavailable |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 GiB-month to 128 vCPU, 864 GiB memory and 12,525 GiB SSD at 10,000 GiB-month. From 100,000 GiB-month the workload exceeds the planning range and the target is unpriced.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| PostgreSQL (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (one copy) | Representative item size | 1,024 | bytes |
| PostgreSQL (one copy) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (one copy) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (one copy) | Target reads per point read | 1 | operations |
| PostgreSQL (one copy) | Target writes per item write | 1 | operations |
| PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (one copy) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (one copy) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (one copy) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (one copy) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| PostgreSQL (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| PostgreSQL (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| PostgreSQL (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| PostgreSQL (two copies) | Representative item size | 1,024 | bytes |
| PostgreSQL (two copies) | Strongly consistent read fraction | 1 | fraction |
| PostgreSQL (two copies) | Origin write-unit amplification | 1 | multiplier |
| PostgreSQL (two copies) | Target reads per point read | 1 | operations |
| PostgreSQL (two copies) | Target writes per item write | 1 | operations |
| PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL (two copies) | Target list price · GiB-month | 0.1 | USD/GiB-month |
| PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL (two copies) | Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| PostgreSQL (two copies) | Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| PostgreSQL (two copies) | Approximate target service minimum | 0 | USD/month |
| PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Self-hosted target: PostgreSQL (PostgreSQL License, [https://www.postgresql.org/about/licence/](https://www.postgresql.org/about/licence/)). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer's Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.
* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.
* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
* Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB ([https://docs.cloud.google.com/compute/docs/general-purpose-machines](https://docs.cloud.google.com/compute/docs/general-purpose-machines)); a Persistent Disk volume holds up to 64 TiB ([https://docs.cloud.google.com/compute/docs/disks/persistent-disks](https://docs.cloud.google.com/compute/docs/disks/persistent-disks)).
* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.
* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Compute Engine general-purpose machine pricing: [https://cloud.google.com/products/compute/pricing/general-purpose](https://cloud.google.com/products/compute/pricing/general-purpose)
* Disk and image pricing: [https://cloud.google.com/compute/disks-image-pricing](https://cloud.google.com/compute/disks-image-pricing)
* Network pricing: [https://cloud.google.com/vpc/network-pricing](https://cloud.google.com/vpc/network-pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-67ab648398db063f54620ef99fe9513d4263793e` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

**DynamoDB → PostgreSQL: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Provisioned primary CPU | 46.15 |
| Target: Provisioned primary RAM | 24.74 |
| Target: Provisioned primary disk | 10.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent provisioned resources | 0.00 |
| Target: Independent managed resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **80.90** |

Estimated allocation, not benchmark calibrated: sized at 2 vCPU, 8 GiB memory and 100 GiB SSD for this scenario.

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.1 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target list price · vCPU-hour | 0.031611 | USD/vCPU-hour |
| Target list price · GiB-hour | 0.004237 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Self-hosted target: PostgreSQL (PostgreSQL License, [https://www.postgresql.org/about/licence/](https://www.postgresql.org/about/licence/)). Selected CPU, RAM and physical disk allocation grow with workload; no per-operation price is assumed. No vendor charge: the target runs on the customer's Kubernetes nodes, so CPU, RAM and disk bill at the Kubernetes node reference rates, Compute Engine N2 in us-central1 (USD 0.031611/vCPU-hour, 0.004237/GiB-hour) with pd-balanced disk (0.10/GiB-month) and Premium Tier egress. The cost-optimized E2 series lists 0.02181159/vCPU-hour and 0.00292353/GiB-hour; AWS m6i/r6i and Azure D2s v5/E2s v5 both decompose to 0.033/vCPU-hour and 0.00375/GiB-hour. Requested CPU and RAM are billed; node bin-packing waste, system reservations and the cluster control-plane fee are not.

* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.

* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.

* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.

* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.

* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.

* Node bounds: Compute Engine n2-highmem-128 has 128 vCPUs and 864 GB ([https://docs.cloud.google.com/compute/docs/general-purpose-machines](https://docs.cloud.google.com/compute/docs/general-purpose-machines)); a Persistent Disk volume holds up to 64 TiB ([https://docs.cloud.google.com/compute/docs/disks/persistent-disks](https://docs.cloud.google.com/compute/docs/disks/persistent-disks)).

* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.

* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.

* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.

List prices read: 2026-10-22. Model: `plan-67ab648398db063f54620ef99fe9513d4263793e` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Compute Engine general-purpose machine pricing](https://cloud.google.com/products/compute/pricing/general-purpose), [Disk and image pricing](https://cloud.google.com/compute/disks-image-pricing), [Network pricing](https://cloud.google.com/vpc/network-pricing).

### On Azure

#### Azure Cosmos DB (provisioned)

##### Table administration on Azure Cosmos DB (provisioned throughput)

The application's DynamoDB client sends table-management requests to the Tensor9 adapter in the target environment. The control endpoint and the table endpoint use the same backend database. The deployed table uses a Cosmos DB container with an autoscale range of request units. Runtime CreateTable records logical table metadata in the configured container; it does not create another Cosmos account or a new independently sized container for every request.

##### Capacity settings

The provisioned backend uses an autoscale range of request units, or RUs, sized for the declared table. UpdateTable retains DynamoDB billing settings in the table registry. Change the Cosmos throughput configuration to change the actual capacity available to the container.

##### Deletion and durable state

The registry stores table names, key definitions and lifecycle state. DeleteTable marks the logical table deleted and advances its generation; a recreated name uses the new generation so older items are no longer reachable through it. Physical cleanup is separate from this logical deletion.

##### Configuration and retry constraints

Runtime CreateTable index definitions must match the deployed secondary-index configuration. The stream specification must also match the deployed configuration. Provisioned throughput can support Azure-managed global secondary indexes; plan those indexes with the deployment rather than treating runtime table creation as an unrestricted container-design API.

##### Operating the backend

Microsoft operates database durability, backups and availability. Tensor9 translates DynamoDB control requests and maintains the logical table registry. Native Cosmos account and container management remain separate from this endpoint; numeric precision, transactions and stream ownership are covered with the item APIs above.

##### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/193dccbec2796b6e5b1171fc4a7111fefeabb172227aef8c11ca6d5c32ad8196-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/8cc3648d8e340bbe4e76584c2e56cc26eb1ed0795f0657b10359947799ae7de5-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Azure Cosmos DB (provisioned) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 23.36 | 23.36 |
| 1 | 0.33 | 23.36 | 23.03 |
| 10 | 3.29 | 23.36 | 20.08 |
| 100 | 32.85 | 23.36 | -9.49 |
| 1,000 | 328.50 | 116.80 | -211.70 |
| 10,000 | 3,285.00 | 1,168.00 | -2,117.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.008 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 23.36 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Provisioned Cosmos DB bills reserved throughput in 100 RU/s blocks per hour, not consumed operations: planning-peak reads at 1 RU and writes at about 5.5 RU each are summed and rounded up to whole 100 RU/s blocks, with the documented 400 RU/s manual minimum ([https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput](https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput)). The blocks are a hard throughput limit, so they are planned at full utilization of the planning peak. Autoscale (USD 0.012 per 100 RU/s-hour, 100-1,000 RU/s entry) and the free tier (1,000 RU/s and 25 GB on one account) are not selected. Each additional region bills its own RU/s and storage.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-c920be7e617e9f0a40743bb26db180c9036769e6` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/246f19192dd7bc78a94f9f0df86544666da950f42b74e6a9ea2679108a556580-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/c6b19771b87a678f0ea1ea5181bcea37c8319c87c472ee7006b0c6526b66aacc-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Azure Cosmos DB (provisioned) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 23.36 | 23.36 |
| 1 | 1.64 | 23.36 | 21.72 |
| 10 | 16.43 | 23.36 | 6.94 |
| 100 | 164.25 | 70.08 | -94.17 |
| 1,000 | 1,642.50 | 648.24 | -994.26 |
| 10,000 | 16,425.00 | 6,429.84 | -9,995.16 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.008 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 23.36 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Provisioned Cosmos DB bills reserved throughput in 100 RU/s blocks per hour, not consumed operations: planning-peak reads at 1 RU and writes at about 5.5 RU each are summed and rounded up to whole 100 RU/s blocks, with the documented 400 RU/s manual minimum ([https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput](https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput)). The blocks are a hard throughput limit, so they are planned at full utilization of the planning peak. Autoscale (USD 0.012 per 100 RU/s-hour, 100-1,000 RU/s entry) and the free tier (1,000 RU/s and 25 GB on one account) are not selected. Each additional region bills its own RU/s and storage.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-c920be7e617e9f0a40743bb26db180c9036769e6` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/8fc506740d01cb1e3d31a20b358a55b374a8029899df42f92417a18e0b8830bf-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/ced7d83588c442c589c3870b5a69544f2a2009dbd22027b25d754e0abcf83f01-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Azure Cosmos DB (provisioned) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 23.36 | 23.36 |
| 10 | 2.50 | 25.86 | 23.36 |
| 100 | 25.00 | 48.36 | 23.36 |
| 1,000 | 250.00 | 273.36 | 23.36 |
| 10,000 | 2,500.00 | 2,523.36 | 23.36 |
| 100,000 | 25,000.00 | 25,023.36 | 23.36 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.008 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 23.36 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Provisioned Cosmos DB bills reserved throughput in 100 RU/s blocks per hour, not consumed operations: planning-peak reads at 1 RU and writes at about 5.5 RU each are summed and rounded up to whole 100 RU/s blocks, with the documented 400 RU/s manual minimum ([https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput](https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput)). The blocks are a hard throughput limit, so they are planned at full utilization of the planning peak. Autoscale (USD 0.012 per 100 RU/s-hour, 100-1,000 RU/s entry) and the free tier (1,000 RU/s and 25 GB on one account) are not selected. Each additional region bills its own RU/s and storage.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-c920be7e617e9f0a40743bb26db180c9036769e6` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

**DynamoDB → Azure Cosmos DB (provisioned): Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: eastus. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Target read operations | 0.00 |
| Target: Target write operations | 0.00 |
| Target: Target retained physical data | 0.00 |
| Target: Additional broker replica storage | 0.00 |
| Target: Execution or worker CPU | 0.00 |
| Target: Execution or worker RAM | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent native resources | 0.00 |
| Target: 100 RU/s blocks at planning peak | 23.36 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **23.36** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.008 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 23.36 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Provisioned Cosmos DB bills reserved throughput in 100 RU/s blocks per hour, not consumed operations: planning-peak reads at 1 RU and writes at about 5.5 RU each are summed and rounded up to whole 100 RU/s blocks, with the documented 400 RU/s manual minimum ([https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput](https://learn.microsoft.com/en-us/azure/cosmos-db/set-throughput)). The blocks are a hard throughput limit, so they are planned at full utilization of the planning peak. Autoscale (USD 0.012 per 100 RU/s-hour, 100-1,000 RU/s entry) and the free tier (1,000 RU/s and 25 GB on one account) are not selected. Each additional region bills its own RU/s and storage.

List prices read: 2026-10-22. Model: `plan-c920be7e617e9f0a40743bb26db180c9036769e6` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

#### Azure Cosmos DB (serverless)

##### Table administration on Azure Cosmos DB (serverless)

The application's DynamoDB client sends table-management requests to the Tensor9 adapter in the target environment. The control endpoint and the table endpoint use the same backend database. The adapter serves table administration over a configured serverless Cosmos DB container. CreateTable registers a logical table and its key schema in that container. ListTables and DescribeTable read the stored registry rather than discovering a separate Azure resource for each logical name.

##### Capacity settings

Cosmos DB charges for consumed request units and storage in this backend. DynamoDB billing settings are retained as metadata; UpdateTable cannot switch the Cosmos account from serverless to provisioned throughput. Choose that operating mode when selecting the backend.

##### Deletion and durable state

DeleteTable hides a table by changing its registry state and advancing its generation. Recreating the same name starts a new logical generation, with old items excluded from reads and listings. Cleanup of old documents can continue after the logical deletion.

##### Configuration and retry constraints

Azure-managed global secondary indexes require the provisioned backend and are not offered on this serverless backend. Runtime index definitions and stream settings must match the deployed configuration. A table that needs managed global secondary indexes should select provisioned Cosmos DB before deployment.

##### Operating the backend

Microsoft operates the Cosmos database while Tensor9 operates the adapter. Configure native backup and account access separately. Serverless consumption billing does not remove the documented Cosmos limits on numeric precision, multi-item transactions or stream ownership.

##### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/4771757d971e3824401e9b7583642844fc6318107e3589725df9928cca48993a-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/bd6716370e8b2e94e5c955d6b09b9e3a7954c2dd78eced8e3cc17e92b4b50173-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Azure Cosmos DB (serverless) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 0.33 | 0.66 | 0.33 |
| 10 | 3.29 | 6.57 | 3.29 |
| 100 | 32.85 | 65.70 | 32.85 |
| 1,000 | 328.50 | 657.00 | 328.50 |
| 10,000 | 3,285.00 | 6,570.00 | 3,285.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.00000025 | USD/read |
| Target list price · write | 0.000001375 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Cosmos DB serverless bills consumed Request Units (USD 0.25 per million) and stored GB. Per-operation rates assume Microsoft's published 1 KB costs: a point read is 1 RU and an unindexed insert about 5.5 RU ([https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes](https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes)). Larger items, default indexing of every property, replaces (2x an insert) and strong or bounded-staleness reads (2x) cost more RU than these rates assume.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-193a4d8c9f7cdd8a1e2cad0fae8d95ed44aad86e` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/c8207c089627fc4683370a73685e038ae3ae76a56b3f8b6000746fada5469ebd-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/368a2449ad33f0b70ee82375401b8f8daf5e214d4d54f30d5cf97aad688848d2-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Azure Cosmos DB (serverless) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 1.64 | 3.61 | 1.97 |
| 10 | 16.43 | 36.14 | 19.71 |
| 100 | 164.25 | 361.35 | 197.10 |
| 1,000 | 1,642.50 | 3,613.50 | 1,971.00 |
| 10,000 | 16,425.00 | 36,135.00 | 19,710.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.00000025 | USD/read |
| Target list price · write | 0.000001375 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Cosmos DB serverless bills consumed Request Units (USD 0.25 per million) and stored GB. Per-operation rates assume Microsoft's published 1 KB costs: a point read is 1 RU and an unindexed insert about 5.5 RU ([https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes](https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes)). Larger items, default indexing of every property, replaces (2x an insert) and strong or bounded-staleness reads (2x) cost more RU than these rates assume.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-193a4d8c9f7cdd8a1e2cad0fae8d95ed44aad86e` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: eastus; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/b5db18ebd2d54c999de35f1b739ab68377aca6dbf19f5946ea6653b0a18afc48-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/7d9f1b7ae0b26fe135d08c8d080e58ca7d472f4f7c5a6270b93261f96394c22e-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Azure Cosmos DB (serverless) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 10 | 2.50 | 2.50 | 0.00 |
| 100 | 25.00 | 25.00 | 0.00 |
| 1,000 | 250.00 | 250.00 | 0.00 |
| 10,000 | 2,500.00 | 2,500.00 | 0.00 |
| 100,000 | 25,000.00 | 25,000.00 | 0.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.00000025 | USD/read |
| Target list price · write | 0.000001375 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → eastus, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Cosmos DB serverless bills consumed Request Units (USD 0.25 per million) and stored GB. Per-operation rates assume Microsoft's published 1 KB costs: a point read is 1 RU and an unindexed insert about 5.5 RU ([https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes](https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes)). Larger items, default indexing of every property, replaces (2x an insert) and strong or bounded-staleness reads (2x) cost more RU than these rates assume.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Azure Retail Prices API: [https://prices.azure.com/api/retail/prices](https://prices.azure.com/api/retail/prices)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-193a4d8c9f7cdd8a1e2cad0fae8d95ed44aad86e` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

**DynamoDB → Azure Cosmos DB (serverless): Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: eastus. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Target read operations | 0.00 |
| Target: Target write operations | 0.00 |
| Target: Target retained physical data | 0.00 |
| Target: Additional broker replica storage | 0.00 |
| Target: Execution or worker CPU | 0.00 |
| Target: Execution or worker RAM | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent native resources | 0.00 |
| Target: Independent native resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **0.00** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.00000025 | USD/read |
| Target list price · write | 0.000001375 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.25 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.087 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Cosmos DB serverless bills consumed Request Units (USD 0.25 per million) and stored GB. Per-operation rates assume Microsoft's published 1 KB costs: a point read is 1 RU and an unindexed insert about 5.5 RU ([https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes](https://learn.microsoft.com/en-us/azure/cosmos-db/optimize-cost-reads-writes)). Larger items, default indexing of every property, replaces (2x an insert) and strong or bounded-staleness reads (2x) cost more RU than these rates assume.

List prices read: 2026-10-22. Model: `plan-193a4d8c9f7cdd8a1e2cad0fae8d95ed44aad86e` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Azure Retail Prices API](https://prices.azure.com/api/retail/prices).

### On Google Cloud

#### Firestore

##### Table administration on Google Cloud Firestore

The application's DynamoDB client sends table-management requests to the Tensor9 adapter in the target environment. The control endpoint and the table endpoint use the same backend database. CreateTable stores the key schema and table settings in a registry document. The table shares a Firestore collection with other logical tables. ListTables reads the registry, so it can return newly created tables before they contain any items.

##### Capacity settings

Firestore bills native document operations and storage. UpdateTable retains DynamoDB billing settings in the registry; those settings do not create DynamoDB-style reserved read or write capacity in Firestore.

##### Deletion and durable state

DeleteTable changes the registry to mark the table deleted and advances its generation number. Item reads, index entries and stream records use that generation, so recreating the same table name starts with an empty logical table even while old documents await cleanup.

##### Configuration and retry constraints

Physical cleanup is bounded and may leave unreachable documents behind. Those documents still consume storage until removed. Account for cleanup and Firestore document charges in environments that repeatedly create and delete large tables.

##### Operating the backend

The adapter stores table settings durably in Firestore and uses workload identity to access the database. Configure native backups and database access separately. Stream-enabled tables retain the single-writer requirement described for the item APIs above.

##### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/71457ed1407422790ed328d08bccd1118b2830e335f6c2375d73f9628126358e-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/78f6b999b6134342d0189b6da25a04a1fba8445d54b155754f06120746d2d31a-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Firestore | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 0.33 | 0.79 | 0.46 |
| 10 | 3.29 | 7.88 | 4.60 |
| 100 | 32.85 | 78.84 | 45.99 |
| 1,000 | 328.50 | 788.40 | 459.90 |
| 10,000 | 3,285.00 | 7,884.00 | 4,599.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000003 | USD/read |
| Target list price · write | 0.0000009 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.15 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Firestore Standard edition in us-central1 bills document reads, writes and deletes per operation and stored GiB-months. Index-entry reads (one read per batch of up to 1,000 entries) and query fan-out belong in workload translation. Deletes bill USD 0.01 per 100,000 (one ninth of a write), but this profile has no delete rate, so deletes the workload translates as writes are overstated. The daily free quota (50,000 reads, 20,000 writes, 20,000 deletes, 1 GiB) applies only to a project's default database and is not applied; the first 10 GiB/month of internet egress are free and are not applied.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Firestore pricing: [https://cloud.google.com/firestore/pricing](https://cloud.google.com/firestore/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-4ac0e0ca0267692d3ee4ec3549bf7a6dc8998ba8` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Firestore pricing](https://cloud.google.com/firestore/pricing).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/af360ecfa3402ff7d3b7e20eb4289d61f6961fb002cf80ebda5118e8951a9f48-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/03472c51f911ca8043f4fb5f927122a27521e4ed9a2c39e9d4e938bb31493d94-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Firestore | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 1.64 | 2.37 | 0.72 |
| 10 | 16.43 | 23.65 | 7.23 |
| 100 | 164.25 | 236.52 | 72.27 |
| 1,000 | 1,642.50 | 2,365.20 | 722.70 |
| 10,000 | 16,425.00 | 23,652.00 | 7,227.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000003 | USD/read |
| Target list price · write | 0.0000009 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.15 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Firestore Standard edition in us-central1 bills document reads, writes and deletes per operation and stored GiB-months. Index-entry reads (one read per batch of up to 1,000 entries) and query fan-out belong in workload translation. Deletes bill USD 0.01 per 100,000 (one ninth of a write), but this profile has no delete rate, so deletes the workload translates as writes are overstated. The daily free quota (50,000 reads, 20,000 writes, 20,000 deletes, 1 GiB) applies only to a project's default database and is not applied; the first 10 GiB/month of internet egress are free and are not applied.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Firestore pricing: [https://cloud.google.com/firestore/pricing](https://cloud.google.com/firestore/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-4ac0e0ca0267692d3ee4ec3549bf7a6dc8998ba8` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Firestore pricing](https://cloud.google.com/firestore/pricing).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/590e4079cf34eefc91d1a495a108780a445ce0ebf4b00e888584f01a51e93817-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/e93c1c61ba6360d774eba8373524ed002abbfecdc94828a50e240d63751d3dc6-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Firestore | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 10 | 2.50 | 1.50 | -1.00 |
| 100 | 25.00 | 15.00 | -10.00 |
| 1,000 | 250.00 | 150.00 | -100.00 |
| 10,000 | 2,500.00 | 1,500.00 | -1,000.00 |
| 100,000 | 25,000.00 | 15,000.00 | -10,000.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000003 | USD/read |
| Target list price · write | 0.0000009 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.15 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Firestore Standard edition in us-central1 bills document reads, writes and deletes per operation and stored GiB-months. Index-entry reads (one read per batch of up to 1,000 entries) and query fan-out belong in workload translation. Deletes bill USD 0.01 per 100,000 (one ninth of a write), but this profile has no delete rate, so deletes the workload translates as writes are overstated. The daily free quota (50,000 reads, 20,000 writes, 20,000 deletes, 1 GiB) applies only to a project's default database and is not applied; the first 10 GiB/month of internet egress are free and are not applied.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Firestore pricing: [https://cloud.google.com/firestore/pricing](https://cloud.google.com/firestore/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-4ac0e0ca0267692d3ee4ec3549bf7a6dc8998ba8` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Firestore pricing](https://cloud.google.com/firestore/pricing).

**DynamoDB → Firestore: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Target read operations | 0.00 |
| Target: Target write operations | 0.00 |
| Target: Target retained physical data | 0.00 |
| Target: Additional broker replica storage | 0.00 |
| Target: Execution or worker CPU | 0.00 |
| Target: Execution or worker RAM | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent native resources | 0.00 |
| Target: Independent native resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **0.00** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000003 | USD/read |
| Target list price · write | 0.0000009 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.15 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Firestore Standard edition in us-central1 bills document reads, writes and deletes per operation and stored GiB-months. Index-entry reads (one read per batch of up to 1,000 entries) and query fan-out belong in workload translation. Deletes bill USD 0.01 per 100,000 (one ninth of a write), but this profile has no delete rate, so deletes the workload translates as writes are overstated. The daily free quota (50,000 reads, 20,000 writes, 20,000 deletes, 1 GiB) applies only to a project's default database and is not applied; the first 10 GiB/month of internet egress are free and are not applied.

List prices read: 2026-10-22. Model: `plan-4ac0e0ca0267692d3ee4ec3549bf7a6dc8998ba8` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Firestore pricing](https://cloud.google.com/firestore/pricing).

#### Cloud Spanner

##### Table administration on Google Cloud Spanner

The application's DynamoDB client sends table-management requests to the Tensor9 adapter in the target environment. The control endpoint and the table endpoint use the same backend database. CreateTable records the requested key and index definitions, then creates the corresponding Spanner tables and indexes. DeleteTable removes those objects. ListTables and DescribeTable use the durable table catalog.

##### Capacity settings

Spanner capacity belongs to the instance. DynamoDB billing-mode and throughput settings are retained as table metadata; changing them does not allocate a separate pool of Spanner processing units for that table.

##### Deletion and durable state

The catalog records creation and deletion before the associated schema work finishes. A retried create can resume matching unfinished work; a request with a different schema cannot reuse that unfinished creation. This makes retry behavior relevant when a client times out during a schema change.

##### Configuration and retry constraints

Spanner schema changes can take longer than item requests. Allow time for table creation and retain normal SDK retry handling. A deleted table must finish its recorded teardown before its name can be created again.

##### Operating the backend

Configure the Spanner instance, database access and backup policy for the target environment. This control endpoint manages DynamoDB tables within that database; it does not turn per-table capacity settings into Spanner instance administration. DynamoDB Streams remain outside this mapping.

##### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/5be9179bb760cc12cf951e6f0a5732208b0f004d12893f3843c6690bfaa96e33-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/15448b6151da1c858ec2092fff4a0f4709cf0c6fa345454e659ddb33d1e9672a-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Target scenario | Cloud Spanner | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Spanner (one copy) | 65.70 | 65.70 |
| 0 | 0.00 | Cloud Spanner (two copies) | 65.70 | 65.70 |
| 1 | 0.33 | Cloud Spanner (one copy) | 65.70 | 65.37 |
| 1 | 0.33 | Cloud Spanner (two copies) | 65.70 | 65.37 |
| 10 | 3.29 | Cloud Spanner (one copy) | 65.70 | 62.42 |
| 10 | 3.29 | Cloud Spanner (two copies) | 65.70 | 62.42 |
| 100 | 32.85 | Cloud Spanner (one copy) | 65.70 | 32.85 |
| 100 | 32.85 | Cloud Spanner (two copies) | 65.70 | 32.85 |
| 1,000 | 328.50 | Cloud Spanner (one copy) | 131.40 | -197.10 |
| 1,000 | 328.50 | Cloud Spanner (two copies) | 131.40 | -197.10 |
| 10,000 | 3,285.00 | Cloud Spanner (one copy) | 919.80 | -2,365.20 |
| 10,000 | 3,285.00 | Cloud Spanner (two copies) | 919.80 | -2,365.20 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Spanner (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (one copy) | Representative item size | 1,024 | bytes |
| Cloud Spanner (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (one copy) | Target reads per point read | 1 | operations |
| Cloud Spanner (one copy) | Target writes per item write | 1 | operations |
| Cloud Spanner (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (one copy) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (one copy) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (one copy) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Spanner (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Spanner (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (two copies) | Representative item size | 1,024 | bytes |
| Cloud Spanner (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (two copies) | Target reads per point read | 1 | operations |
| Cloud Spanner (two copies) | Target writes per item write | 1 | operations |
| Cloud Spanner (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (two copies) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (two copies) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (two copies) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Spanner (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Spanner bills compute capacity in processing units (100 PU minimum and steps, 1,000 PU per node) whose price includes the three replicas of a regional configuration, plus SSD storage including all replicas. Capacity is sized from planning-peak reads and writes against Google's per-node throughput; replication is built in, so the standby selection adds no copy. Enterprise (USD 1.23) and Enterprise Plus (1.71 per node-hour) editions, dual- and multi-region configurations and per-node storage limits are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Spanner pricing: [https://cloud.google.com/spanner/pricing](https://cloud.google.com/spanner/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-1f7602bf670b04f3676190fd832f3a586a145caa` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Spanner pricing](https://cloud.google.com/spanner/pricing).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/c1ab7e70dcf274a35ae2207c296c4f0234c96c95dc36d6049e1f493c12b615ea-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/fde1cf40f9d532fbf958592fe737c419a2c39393206996a0bec2e34822855b2b-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Target scenario | Cloud Spanner | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Spanner (one copy) | 65.70 | 65.70 |
| 0 | 0.00 | Cloud Spanner (two copies) | 65.70 | 65.70 |
| 1 | 1.64 | Cloud Spanner (one copy) | 65.70 | 64.06 |
| 1 | 1.64 | Cloud Spanner (two copies) | 65.70 | 64.06 |
| 10 | 16.43 | Cloud Spanner (one copy) | 65.70 | 49.28 |
| 10 | 16.43 | Cloud Spanner (two copies) | 65.70 | 49.28 |
| 100 | 164.25 | Cloud Spanner (one copy) | 65.70 | -98.55 |
| 100 | 164.25 | Cloud Spanner (two copies) | 65.70 | -98.55 |
| 1,000 | 1,642.50 | Cloud Spanner (one copy) | 591.30 | -1,051.20 |
| 1,000 | 1,642.50 | Cloud Spanner (two copies) | 591.30 | -1,051.20 |
| 10,000 | 16,425.00 | Cloud Spanner (one copy) | 5,781.60 | -10,643.40 |
| 10,000 | 16,425.00 | Cloud Spanner (two copies) | 5,781.60 | -10,643.40 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Spanner (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (one copy) | Representative item size | 1,024 | bytes |
| Cloud Spanner (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (one copy) | Target reads per point read | 1 | operations |
| Cloud Spanner (one copy) | Target writes per item write | 1 | operations |
| Cloud Spanner (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (one copy) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (one copy) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (one copy) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Spanner (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Spanner (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (two copies) | Representative item size | 1,024 | bytes |
| Cloud Spanner (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (two copies) | Target reads per point read | 1 | operations |
| Cloud Spanner (two copies) | Target writes per item write | 1 | operations |
| Cloud Spanner (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (two copies) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (two copies) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (two copies) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Spanner (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Spanner bills compute capacity in processing units (100 PU minimum and steps, 1,000 PU per node) whose price includes the three replicas of a regional configuration, plus SSD storage including all replicas. Capacity is sized from planning-peak reads and writes against Google's per-node throughput; replication is built in, so the standby selection adds no copy. Enterprise (USD 1.23) and Enterprise Plus (1.71 per node-hour) editions, dual- and multi-region configurations and per-node storage limits are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Spanner pricing: [https://cloud.google.com/spanner/pricing](https://cloud.google.com/spanner/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-1f7602bf670b04f3676190fd832f3a586a145caa` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Spanner pricing](https://cloud.google.com/spanner/pricing).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/9444703ebc91281d5fa979aeadae58b545d0c94303b24f40953e873b9036f02e-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/853cb7b0541452ddb0c1360fae2fc55e387bf4dc82752446e97ca76b8d59d4c8-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Target scenario | Cloud Spanner | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Spanner (one copy) | 65.70 | 65.70 |
| 0 | 0.00 | Cloud Spanner (two copies) | 65.70 | 65.70 |
| 10 | 2.50 | Cloud Spanner (one copy) | 68.70 | 66.20 |
| 10 | 2.50 | Cloud Spanner (two copies) | 68.70 | 66.20 |
| 100 | 25.00 | Cloud Spanner (one copy) | 95.70 | 70.70 |
| 100 | 25.00 | Cloud Spanner (two copies) | 95.70 | 70.70 |
| 1,000 | 250.00 | Cloud Spanner (one copy) | 365.70 | 115.70 |
| 1,000 | 250.00 | Cloud Spanner (two copies) | 365.70 | 115.70 |
| 10,000 | 2,500.00 | Cloud Spanner (one copy) | 3,065.70 | 565.70 |
| 10,000 | 2,500.00 | Cloud Spanner (two copies) | 3,065.70 | 565.70 |
| 100,000 | 25,000.00 | Cloud Spanner (one copy) | 30,065.70 | 5,065.70 |
| 100,000 | 25,000.00 | Cloud Spanner (two copies) | 30,065.70 | 5,065.70 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Spanner (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (one copy) | Representative item size | 1,024 | bytes |
| Cloud Spanner (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (one copy) | Target reads per point read | 1 | operations |
| Cloud Spanner (one copy) | Target writes per item write | 1 | operations |
| Cloud Spanner (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (one copy) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (one copy) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (one copy) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Spanner (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Spanner (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Spanner (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Spanner (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Spanner (two copies) | Representative item size | 1,024 | bytes |
| Cloud Spanner (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Spanner (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Spanner (two copies) | Target reads per point read | 1 | operations |
| Cloud Spanner (two copies) | Target writes per item write | 1 | operations |
| Cloud Spanner (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Spanner (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Spanner (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Spanner (two copies) | Target list price · GiB-month | 0.3 | USD/GiB-month |
| Cloud Spanner (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Spanner (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Spanner (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Spanner (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Spanner (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Spanner (two copies) | Target list price · resource-hour | 0.9 | USD/resource-hour |
| Cloud Spanner (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Spanner (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Spanner (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Spanner (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Spanner (two copies) | Target service minimum | 65.7 | USD/month |
| Cloud Spanner (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Spanner (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Spanner (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Spanner (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Spanner (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Spanner (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Spanner (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Spanner (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Spanner (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Spanner (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Spanner (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Spanner (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Spanner (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Spanner (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Spanner (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Spanner bills compute capacity in processing units (100 PU minimum and steps, 1,000 PU per node) whose price includes the three replicas of a regional configuration, plus SSD storage including all replicas. Capacity is sized from planning-peak reads and writes against Google's per-node throughput; replication is built in, so the standby selection adds no copy. Enterprise (USD 1.23) and Enterprise Plus (1.71 per node-hour) editions, dual- and multi-region configurations and per-node storage limits are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Spanner pricing: [https://cloud.google.com/spanner/pricing](https://cloud.google.com/spanner/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-1f7602bf670b04f3676190fd832f3a586a145caa` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Spanner pricing](https://cloud.google.com/spanner/pricing).

**DynamoDB → Cloud Spanner: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: nodes at planning peak | 65.70 |
| Target: Target retained physical data | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent managed resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **65.70** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.3 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.9 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 65.7 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Spanner bills compute capacity in processing units (100 PU minimum and steps, 1,000 PU per node) whose price includes the three replicas of a regional configuration, plus SSD storage including all replicas. Capacity is sized from planning-peak reads and writes against Google's per-node throughput; replication is built in, so the standby selection adds no copy. Enterprise (USD 1.23) and Enterprise Plus (1.71 per node-hour) editions, dual- and multi-region configurations and per-node storage limits are not selected.

List prices read: 2026-10-22. Model: `plan-1f7602bf670b04f3676190fd832f3a586a145caa` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Spanner pricing](https://cloud.google.com/spanner/pricing).

#### Cloud Bigtable

##### Table lifecycle

The DynamoDB adapter manages logical tables inside an existing Bigtable table. CreateTable records the table name and key schema; it does not create a Bigtable instance or allocate a separate cluster. DescribeTable and ListTables return the adapter's table catalog. Provision the Bigtable instance, physical table, column families and single-cluster app profile before using these APIs.

##### Capacity and supported configuration

Bigtable cluster capacity is shared by the logical tables. Changing DynamoDB billing-mode metadata does not add Bigtable nodes or enforce provisioned read and write units. The adapter rejects secondary indexes, DynamoDB Streams and per-item TTL; selecting those options cannot make the underlying row store provide those DynamoDB behaviors.

##### Deletion and storage cleanup

DeleteTable removes a logical table's visibility through the DynamoDB API. A table generation separates a recreated name from its predecessor's rows. Logical deletion does not delete the Bigtable cluster or its shared physical table; the provisioned store remains. Plan storage cleanup and account for retained storage costs after deleting a logical table.

##### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/4c58455f30b9a901a569e8583aaf80e093d70ddac4e9511ef869d306691f6a86-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/ba0814bc80862860cf20562ef8afc2473ca46eb284231864beadf71d44476b8b-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Target scenario | Cloud Bigtable | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Bigtable (one copy) | 474.50 | 474.50 |
| 0 | 0.00 | Cloud Bigtable (two copies) | 474.50 | 474.50 |
| 1 | 0.33 | Cloud Bigtable (one copy) | 474.50 | 474.17 |
| 1 | 0.33 | Cloud Bigtable (two copies) | 474.50 | 474.17 |
| 10 | 3.29 | Cloud Bigtable (one copy) | 474.50 | 471.22 |
| 10 | 3.29 | Cloud Bigtable (two copies) | 474.50 | 471.22 |
| 100 | 32.85 | Cloud Bigtable (one copy) | 474.50 | 441.65 |
| 100 | 32.85 | Cloud Bigtable (two copies) | 474.50 | 441.65 |
| 1,000 | 328.50 | Cloud Bigtable (one copy) | 474.50 | 146.00 |
| 1,000 | 328.50 | Cloud Bigtable (two copies) | 474.50 | 146.00 |
| 10,000 | 3,285.00 | Cloud Bigtable (one copy) | 949.00 | -2,336.00 |
| 10,000 | 3,285.00 | Cloud Bigtable (two copies) | 949.00 | -2,336.00 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (one copy) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (one copy) | Target reads per point read | 1 | operations |
| Cloud Bigtable (one copy) | Target writes per item write | 1 | operations |
| Cloud Bigtable (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (one copy) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (one copy) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Bigtable (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (two copies) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (two copies) | Target reads per point read | 1 | operations |
| Cloud Bigtable (two copies) | Target writes per item write | 1 | operations |
| Cloud Bigtable (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (two copies) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (two copies) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Bigtable (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Bigtable bills whole provisioned nodes per hour, not vCPU or RAM, plus SSD storage of the compressed physical data. Nodes are sized from planning-peak reads and writes against Google's per-node SSD throughput, with a one-node minimum. A replicated instance bills every cluster's nodes and its own copy of the data; this profile prices one cluster, so the standby selection does not add a cluster.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Bigtable pricing: [https://cloud.google.com/bigtable/pricing](https://cloud.google.com/bigtable/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-54c656ab4ad36cede3d0182c3bf9faef6669d51d` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Bigtable pricing](https://cloud.google.com/bigtable/pricing).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/55366a4f63a3f198c5a74a53ea73789e91ab57269876a29e7e75ce4da1806d80-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/ee86a62cd95344baee3f9b95369236c73ac2f070339b544b01ddb04415a89769-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Target scenario | Cloud Bigtable | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Bigtable (one copy) | 474.50 | 474.50 |
| 0 | 0.00 | Cloud Bigtable (two copies) | 474.50 | 474.50 |
| 1 | 1.64 | Cloud Bigtable (one copy) | 474.50 | 472.86 |
| 1 | 1.64 | Cloud Bigtable (two copies) | 474.50 | 472.86 |
| 10 | 16.43 | Cloud Bigtable (one copy) | 474.50 | 458.08 |
| 10 | 16.43 | Cloud Bigtable (two copies) | 474.50 | 458.08 |
| 100 | 164.25 | Cloud Bigtable (one copy) | 474.50 | 310.25 |
| 100 | 164.25 | Cloud Bigtable (two copies) | 474.50 | 310.25 |
| 1,000 | 1,642.50 | Cloud Bigtable (one copy) | 474.50 | -1,168.00 |
| 1,000 | 1,642.50 | Cloud Bigtable (two copies) | 474.50 | -1,168.00 |
| 10,000 | 16,425.00 | Cloud Bigtable (one copy) | 1,423.50 | -15,001.50 |
| 10,000 | 16,425.00 | Cloud Bigtable (two copies) | 1,423.50 | -15,001.50 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (one copy) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (one copy) | Target reads per point read | 1 | operations |
| Cloud Bigtable (one copy) | Target writes per item write | 1 | operations |
| Cloud Bigtable (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (one copy) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (one copy) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Bigtable (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (two copies) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (two copies) | Target reads per point read | 1 | operations |
| Cloud Bigtable (two copies) | Target writes per item write | 1 | operations |
| Cloud Bigtable (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (two copies) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (two copies) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Bigtable (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Bigtable bills whole provisioned nodes per hour, not vCPU or RAM, plus SSD storage of the compressed physical data. Nodes are sized from planning-peak reads and writes against Google's per-node SSD throughput, with a one-node minimum. A replicated instance bills every cluster's nodes and its own copy of the data; this profile prices one cluster, so the standby selection does not add a cluster.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Bigtable pricing: [https://cloud.google.com/bigtable/pricing](https://cloud.google.com/bigtable/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-54c656ab4ad36cede3d0182c3bf9faef6669d51d` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Bigtable pricing](https://cloud.google.com/bigtable/pricing).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/e1895dd943b66431cc0a2f399c8a95a8e184ef51fa872c86c435844cef24b8ae-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/4e1cf0e2070befb9b73bfe9b6f37f09fdab9985391ea19e411eba58e6101c365-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Target scenario | Cloud Bigtable | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud Bigtable (one copy) | 474.50 | 474.50 |
| 0 | 0.00 | Cloud Bigtable (two copies) | 474.50 | 474.50 |
| 10 | 2.50 | Cloud Bigtable (one copy) | 476.20 | 473.70 |
| 10 | 2.50 | Cloud Bigtable (two copies) | 476.20 | 473.70 |
| 100 | 25.00 | Cloud Bigtable (one copy) | 491.50 | 466.50 |
| 100 | 25.00 | Cloud Bigtable (two copies) | 491.50 | 466.50 |
| 1,000 | 250.00 | Cloud Bigtable (one copy) | 644.50 | 394.50 |
| 1,000 | 250.00 | Cloud Bigtable (two copies) | 644.50 | 394.50 |
| 10,000 | 2,500.00 | Cloud Bigtable (one copy) | 2,174.50 | -325.50 |
| 10,000 | 2,500.00 | Cloud Bigtable (two copies) | 2,174.50 | -325.50 |
| 100,000 | 25,000.00 | Cloud Bigtable (one copy) | 17,474.50 | -7,525.50 |
| 100,000 | 25,000.00 | Cloud Bigtable (two copies) | 17,474.50 | -7,525.50 |

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (one copy) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (one copy) | Target reads per point read | 1 | operations |
| Cloud Bigtable (one copy) | Target writes per item write | 1 | operations |
| Cloud Bigtable (one copy) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (one copy) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (one copy) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (one copy) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (one copy) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (one copy) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (one copy) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud Bigtable (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud Bigtable (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud Bigtable (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud Bigtable (two copies) | Representative item size | 1,024 | bytes |
| Cloud Bigtable (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud Bigtable (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud Bigtable (two copies) | Target reads per point read | 1 | operations |
| Cloud Bigtable (two copies) | Target writes per item write | 1 | operations |
| Cloud Bigtable (two copies) | Target price guess · read | 0 | USD/read |
| Cloud Bigtable (two copies) | Target price guess · write | 0 | USD/write |
| Cloud Bigtable (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud Bigtable (two copies) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud Bigtable (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud Bigtable (two copies) | Target list price · network GiB | 0.12 | USD/network GiB |
| Cloud Bigtable (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud Bigtable (two copies) | Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Target list price · resource-hour | 0.65 | USD/resource-hour |
| Cloud Bigtable (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud Bigtable (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud Bigtable (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud Bigtable (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud Bigtable (two copies) | Target service minimum | 474.5 | USD/month |
| Cloud Bigtable (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud Bigtable (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud Bigtable (two copies) | Minimum primary disk | 100 | GiB |
| Cloud Bigtable (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud Bigtable (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud Bigtable (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud Bigtable (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud Bigtable (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud Bigtable (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud Bigtable (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud Bigtable (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud Bigtable (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud Bigtable (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud Bigtable (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud Bigtable (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Bigtable bills whole provisioned nodes per hour, not vCPU or RAM, plus SSD storage of the compressed physical data. Nodes are sized from planning-peak reads and writes against Google's per-node SSD throughput, with a one-node minimum. A replicated instance bills every cluster's nodes and its own copy of the data; this profile prices one cluster, so the standby selection does not add a cluster.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Bigtable pricing: [https://cloud.google.com/bigtable/pricing](https://cloud.google.com/bigtable/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-54c656ab4ad36cede3d0182c3bf9faef6669d51d` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Bigtable pricing](https://cloud.google.com/bigtable/pricing).

**DynamoDB → Cloud Bigtable: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: nodes at planning peak | 474.50 |
| Target: Target retained physical data | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent managed resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **474.50** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.17 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.12 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target list price · resource-hour | 0.65 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 474.5 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Bigtable bills whole provisioned nodes per hour, not vCPU or RAM, plus SSD storage of the compressed physical data. Nodes are sized from planning-peak reads and writes against Google's per-node SSD throughput, with a one-node minimum. A replicated instance bills every cluster's nodes and its own copy of the data; this profile prices one cluster, so the standby selection does not add a cluster.

List prices read: 2026-10-22. Model: `plan-54c656ab4ad36cede3d0182c3bf9faef6669d51d` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Bigtable pricing](https://cloud.google.com/bigtable/pricing).

#### Cloud SQL for PostgreSQL

##### Table administration on Google Cloud SQL for PostgreSQL

The application's DynamoDB client sends table-management requests to the Tensor9 adapter in the target environment. The control endpoint and the table endpoint use the same backend database. CreateTable creates a PostgreSQL table, its declared secondary indexes and a registry entry. A stream-enabled table also receives a change-log table. The DynamoDB endpoint serves both table administration and item requests against this same database.

##### Capacity settings

Cloud SQL instance size, storage and availability settings determine capacity. UpdateTable records DynamoDB billing settings without resizing the Cloud SQL instance. The adapter applies a 500-table guardrail per namespace; this is an adapter limit rather than a PostgreSQL service quota.

##### Deletion and durable state

Table creation writes the schema and registry in a database transaction. DeleteTable drops the item table and its change log and removes the registry and stream-owner records in the same transaction. Recreating the name therefore does not expose the deleted table's records.

##### Configuration and retry constraints

Enabling time to live builds the needed PostgreSQL index before advertising the setting as enabled. The API waits for that index work while normal item reads and writes remain available. Plan schema changes with enough database capacity and request timeout allowance.

##### Operating the backend

Google operates the Cloud SQL database; Tensor9 operates the DynamoDB adapter and uses Cloud SQL IAM database authentication. Configure database backups and availability through Cloud SQL. The table page describes transaction behavior and stream-related restrictions.

##### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/ad196ac4da6918302c1737f03f7d3d5afcf1958b0bfa1749ca171efd50db5298-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/16e76eeb9846492d8b80d85a26be8ea0a6ab91e22d8e6b5d5a118f49c8e1bcf7-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | Target scenario | Cloud SQL for PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 118.18 |
| 0 | 0.00 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 236.36 |
| 1 | 0.33 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 117.85 |
| 1 | 0.33 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 236.03 |
| 10 | 3.29 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 114.89 |
| 10 | 3.29 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 233.07 |
| 100 | 32.85 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 85.33 |
| 100 | 32.85 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 203.51 |
| 1,000 | 328.50 | Cloud SQL for PostgreSQL (one copy) | 118.18 | -210.32 |
| 1,000 | 328.50 | Cloud SQL for PostgreSQL (two copies) | 236.36 | -92.14 |
| 10,000 | 3,285.00 | Cloud SQL for PostgreSQL (one copy) | 1,635.85 | -1,649.15 |
| 10,000 | 3,285.00 | Cloud SQL for PostgreSQL (two copies) | 3,271.70 | -13.30 |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 32 vCPU, 128 GiB memory and 100 GiB SSD at 10,000 per second.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud SQL for PostgreSQL (one copy) | Representative item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (one copy) | Target reads per point read | 1 | operations |
| Cloud SQL for PostgreSQL (one copy) | Target writes per item write | 1 | operations |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud SQL for PostgreSQL (one copy) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud SQL for PostgreSQL (one copy) | Target list price · network GiB | 0.19 | USD/network GiB |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Target list price · vCPU-hour | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (one copy) | Target list price · GiB-hour | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud SQL for PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud SQL for PostgreSQL (one copy) | Target service minimum | 9.365 | USD/month |
| Cloud SQL for PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud SQL for PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud SQL for PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| Cloud SQL for PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud SQL for PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud SQL for PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud SQL for PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud SQL for PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud SQL for PostgreSQL (two copies) | Representative item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (two copies) | Target reads per point read | 1 | operations |
| Cloud SQL for PostgreSQL (two copies) | Target writes per item write | 1 | operations |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud SQL for PostgreSQL (two copies) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud SQL for PostgreSQL (two copies) | Target list price · network GiB | 0.19 | USD/network GiB |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Target list price · vCPU-hour | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (two copies) | Target list price · GiB-hour | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud SQL for PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud SQL for PostgreSQL (two copies) | Target service minimum | 9.365 | USD/month |
| Cloud SQL for PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud SQL for PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud SQL for PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| Cloud SQL for PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud SQL for PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud SQL for PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud SQL for PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud SQL for PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Cloud SQL Enterprise edition (PostgreSQL) publishes separate vCPU, memory and SSD prices for zonal instances; a high-availability (regional) instance bills exactly twice each, which the standby copy reproduces. Enterprise Plus, committed-use discounts, backups (USD 0.08 per GiB-month) and idle IPv4 addresses (0.01 per hour) are not selected.
* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.
* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
* Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)).
* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.
* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Cloud SQL pricing: [https://cloud.google.com/sql/pricing](https://cloud.google.com/sql/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-f1008577e0cf5d5cb82de2bf437390d5c3a08962` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Cloud SQL pricing](https://cloud.google.com/sql/pricing).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/3e6ba11596efbbf546995cbbecec36f5fd3aa1c1acf48476596d1a80ec7ffd27-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/7ec8dc728be23a1fdf08960fac1909d47683163f8491be38923c12fc8ca6c829-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | Target scenario | Cloud SQL for PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 118.18 |
| 0 | 0.00 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 236.36 |
| 1 | 1.64 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 116.54 |
| 1 | 1.64 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 234.71 |
| 10 | 16.43 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 101.75 |
| 10 | 16.43 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 219.93 |
| 100 | 164.25 | Cloud SQL for PostgreSQL (one copy) | 118.18 | -46.07 |
| 100 | 164.25 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 72.11 |
| 1,000 | 1,642.50 | Cloud SQL for PostgreSQL (one copy) | 118.18 | -1,524.32 |
| 1,000 | 1,642.50 | Cloud SQL for PostgreSQL (two copies) | 236.36 | -1,406.14 |
| 10,000 | 16,425.00 | Cloud SQL for PostgreSQL (one copy) | 1,635.85 | -14,789.15 |
| 10,000 | 16,425.00 | Cloud SQL for PostgreSQL (two copies) | 3,271.70 | -13,153.30 |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 32 vCPU, 128 GiB memory and 100 GiB SSD at 10,000 per second.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud SQL for PostgreSQL (one copy) | Representative item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (one copy) | Target reads per point read | 1 | operations |
| Cloud SQL for PostgreSQL (one copy) | Target writes per item write | 1 | operations |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud SQL for PostgreSQL (one copy) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud SQL for PostgreSQL (one copy) | Target list price · network GiB | 0.19 | USD/network GiB |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Target list price · vCPU-hour | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (one copy) | Target list price · GiB-hour | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud SQL for PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud SQL for PostgreSQL (one copy) | Target service minimum | 9.365 | USD/month |
| Cloud SQL for PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud SQL for PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud SQL for PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| Cloud SQL for PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud SQL for PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud SQL for PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud SQL for PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud SQL for PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud SQL for PostgreSQL (two copies) | Representative item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (two copies) | Target reads per point read | 1 | operations |
| Cloud SQL for PostgreSQL (two copies) | Target writes per item write | 1 | operations |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud SQL for PostgreSQL (two copies) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud SQL for PostgreSQL (two copies) | Target list price · network GiB | 0.19 | USD/network GiB |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Target list price · vCPU-hour | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (two copies) | Target list price · GiB-hour | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud SQL for PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud SQL for PostgreSQL (two copies) | Target service minimum | 9.365 | USD/month |
| Cloud SQL for PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud SQL for PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud SQL for PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| Cloud SQL for PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud SQL for PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud SQL for PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud SQL for PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud SQL for PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Cloud SQL Enterprise edition (PostgreSQL) publishes separate vCPU, memory and SSD prices for zonal instances; a high-availability (regional) instance bills exactly twice each, which the standby copy reproduces. Enterprise Plus, committed-use discounts, backups (USD 0.08 per GiB-month) and idle IPv4 addresses (0.01 per hour) are not selected.
* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.
* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
* Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)).
* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.
* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Cloud SQL pricing: [https://cloud.google.com/sql/pricing](https://cloud.google.com/sql/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-f1008577e0cf5d5cb82de2bf437390d5c3a08962` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Cloud SQL pricing](https://cloud.google.com/sql/pricing).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-central1; currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/98cbac070e5a60cf8606d5a6de3bc59b87c097e975059c882fdf9874dc295683-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/764f929674c5e1d67dded41b3b745d9910a750a3c9d5741777237b546c7b7ec3-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | Target scenario | Cloud SQL for PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 118.18 |
| 0 | 0.00 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 236.36 |
| 10 | 2.50 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 115.68 |
| 10 | 2.50 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 233.86 |
| 100 | 25.00 | Cloud SQL for PostgreSQL (one copy) | 136.90 | 111.90 |
| 100 | 25.00 | Cloud SQL for PostgreSQL (two copies) | 273.80 | 248.80 |
| 1,000 | 250.00 | Cloud SQL for PostgreSQL (one copy) | 1,210.13 | 960.13 |
| 1,000 | 250.00 | Cloud SQL for PostgreSQL (two copies) | 2,420.27 | 2,170.27 |
| 10,000 | 2,500.00 | Cloud SQL for PostgreSQL (one copy) | 8,212.19 | 5,712.19 |
| 10,000 | 2,500.00 | Cloud SQL for PostgreSQL (two copies) | 16,424.39 | 13,924.39 |
| 100,000 | 25,000.00 | Cloud SQL for PostgreSQL (one copy) | Unpriced | Unavailable |
| 100,000 | 25,000.00 | Cloud SQL for PostgreSQL (two copies) | Unpriced | Unavailable |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 GiB-month to 96 vCPU, 624 GiB memory and 12,525 GiB SSD at 10,000 GiB-month. From 100,000 GiB-month the workload exceeds the planning range and the target is unpriced.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud SQL for PostgreSQL (one copy) | Representative item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (one copy) | Strongly consistent read fraction | 1 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (one copy) | Target reads per point read | 1 | operations |
| Cloud SQL for PostgreSQL (one copy) | Target writes per item write | 1 | operations |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud SQL for PostgreSQL (one copy) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud SQL for PostgreSQL (one copy) | Target list price · network GiB | 0.19 | USD/network GiB |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Target list price · vCPU-hour | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (one copy) | Target list price · GiB-hour | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| Cloud SQL for PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| Cloud SQL for PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| Cloud SQL for PostgreSQL (one copy) | Target service minimum | 9.365 | USD/month |
| Cloud SQL for PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| Cloud SQL for PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| Cloud SQL for PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| Cloud SQL for PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Cloud SQL for PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud SQL for PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| Cloud SQL for PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| Cloud SQL for PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Cloud SQL for PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud SQL for PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Origin list price · Control-plane calls | 0 | USD/requests |
| Cloud SQL for PostgreSQL (two copies) | Representative item size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (two copies) | Strongly consistent read fraction | 1 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Origin write-unit amplification | 1 | multiplier |
| Cloud SQL for PostgreSQL (two copies) | Target reads per point read | 1 | operations |
| Cloud SQL for PostgreSQL (two copies) | Target writes per item write | 1 | operations |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Cloud SQL for PostgreSQL (two copies) | Target list price · GiB-month | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Cloud SQL for PostgreSQL (two copies) | Target list price · network GiB | 0.19 | USD/network GiB |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Target list price · vCPU-hour | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (two copies) | Target list price · GiB-hour | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| Cloud SQL for PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| Cloud SQL for PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| Cloud SQL for PostgreSQL (two copies) | Target service minimum | 9.365 | USD/month |
| Cloud SQL for PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| Cloud SQL for PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| Cloud SQL for PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| Cloud SQL for PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Cloud SQL for PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Cloud SQL for PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| Cloud SQL for PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| Cloud SQL for PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Cloud SQL for PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Cloud SQL for PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Cloud SQL for PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Cloud SQL for PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-central1, USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Cloud SQL Enterprise edition (PostgreSQL) publishes separate vCPU, memory and SSD prices for zonal instances; a high-availability (regional) instance bills exactly twice each, which the standby copy reproduces. Enterprise Plus, committed-use discounts, backups (USD 0.08 per GiB-month) and idle IPv4 addresses (0.01 per hour) are not selected.
* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.
* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.
* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.
* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.
* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.
* Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)).
* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.
* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.
* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* Cloud SQL pricing: [https://cloud.google.com/sql/pricing](https://cloud.google.com/sql/pricing)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-f1008577e0cf5d5cb82de2bf437390d5c3a08962` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Cloud SQL pricing](https://cloud.google.com/sql/pricing).

**DynamoDB → Cloud SQL for PostgreSQL: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-central1. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Provisioned primary CPU | 60.30 |
| Target: Provisioned primary RAM | 40.88 |
| Target: Provisioned primary disk | 17.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent provisioned resources | 0.00 |
| Target: Independent managed resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **118.18** |

Estimated allocation, not benchmark calibrated: sized at 2 vCPU, 8 GiB memory and 100 GiB SSD for this scenario.

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.17 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0.19 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target list price · vCPU-hour | 0.0413 | USD/vCPU-hour |
| Target list price · GiB-hour | 0.007 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Target service minimum | 9.365 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Cloud SQL Enterprise edition (PostgreSQL) publishes separate vCPU, memory and SSD prices for zonal instances; a high-availability (regional) instance bills exactly twice each, which the standby copy reproduces. Enterprise Plus, committed-use discounts, backups (USD 0.08 per GiB-month) and idle IPv4 addresses (0.01 per hour) are not selected.

* Row-store throughput (capacityOpsPerVcpuSecond, default 1500) is measured-by-tensor9 as a lower bound: the DynamoDB adapter on Cloud SQL db-custom-2-7680 (2 vCPU, PostgreSQL 16, us-west1) served 2,974 ops/s of YCSB-A at 16 threads without recorded saturation (src/main/kotlin/t9/prime/equiv/generated/eval/CloudsqlPostgresqlYcsbAT16GoYcsbV1\_0\_0.kt). Published CPU-bound pgbench reaches 3,101 read-write transactions and 20,289 point reads per vCPU-second (AWS z1d.2xlarge, PostgreSQL 14.5), so actual capacity is likely higher. Reads and writes share one coefficient: at the same adapter version, read-only YCSB-C was not faster than 50%-update YCSB-A.

* Log-broker throughput (capacityStreamMiBPerVcpuSecond 20 at 0.5 utilization, 4 GiB RAM per vCPU) is provider-documented by Google Managed Service for Apache Kafka sizing ([https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size](https://docs.cloud.google.com/managed-service-for-apache-kafka/docs/plan-cluster-size)): write-equivalent bytes are replicated writes plus a quarter of reads. Producer batches below 10 KB lower per-CPU throughput; that penalty is not modeled.

* Disk utilization 0.8 is provider-documented headroom below Cloud SQL automatic storage increase, which triggers near 91-95% full ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)). The 20 GiB reserve exceeds PostgreSQL's 1 GB default max\_wal\_size; the remainder of that reserve is unmeasured.

* CPU tiers double from 2 vCPUs to the target's largest node at 4 GiB per vCPU; each target's documented largest node bounds CPU, RAM, RAM per vCPU and disk, and the durable staging database uses Cloud SQL Enterprise (96 vCPU, 6.5 GiB per vCPU, 624 GiB, 64 TiB). Targets billed per capacity unit or throughput unit are sized by their backend instead.

* No public evidence: peak/mean work (2) and the RAM working-set fraction (0.1). Proposed measurements: the p99 one-minute rate over the monthly mean from customer CloudWatch metrics; the buffer hit ratio while stepping RAM under a fixed YCSB-B load.

* Node bounds: Cloud SQL Enterprise allows 1-96 vCPUs at 0.9-6.5 GB per vCPU and up to 64 TB with a dedicated vCPU ([https://docs.cloud.google.com/sql/docs/postgres/instance-settings](https://docs.cloud.google.com/sql/docs/postgres/instance-settings)).

* Stored GiB already includes the origin family's physical footprint assumptions; no second storage amplification is applied.

* The operations/vCPU coefficient supplies the compute requirement alongside explicit resource-hour minima.

* Copies and allocation fractions change cost only; they do not increase modeled primary capacity.

List prices read: 2026-10-22. Model: `plan-f1008577e0cf5d5cb82de2bf437390d5c3a08962` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [Cloud SQL pricing](https://cloud.google.com/sql/pricing).

### On OCI

#### OCI NoSQL Database

| Capability | Area | Support | Operations | Notes |
| - | - | - | - | - |
| aws\_dynamodb\_table provisioning | Infrastructure | Partial | - | creates oci\_nosql\_table with the mapped key schema and capacity settings; review storage, index, TTL and integration differences |
| DynamoDB item and table-management requests | Runtime API | Out of scope | - | this OCI NoSQL mapping has no DynamoDB API translator; use OCI NoSQL APIs and SDKs |

##### Infrastructure mapping

Tensor9 converts the declared aws\_dynamodb\_table to an oci\_nosql\_table in the customer's OCI compartment. This is the infrastructure-only adaptation: it provisions storage but does not provide an AWS DynamoDB endpoint. Application reads, writes, queries and runtime table administration use OCI NoSQL APIs. The table and control pages describe this same backend choice.

##### Keys and item data

The DynamoDB partition key becomes the OCI SHARD key. An optional sort key becomes the second primary-key column. String, number and binary key types become corresponding OCI column types; other item attributes occupy a value JSON column. Adapt queries and serialization to that layout rather than sending DynamoDB attribute documents directly.

##### Capacity and storage

PAY\_PER\_REQUEST selects OCI ON\_DEMAND; provisioned DynamoDB capacity selects OCI PROVISIONED settings. OCI read and write units differ from DynamoDB units, so validate them against the workload. OCI also requires an explicit storage cap. Increase that cap before data reaches it; the source DynamoDB table had no equivalent fixed cap.

##### Indexes, expiry and integrations

The current infrastructure mapping does not create declared GSIs or LSIs. Configure native OCI indexes and update the application's access patterns. A source TTL declaration produces a no-expiry default; its per-item epoch attribute is not translated into automatic expiry. DynamoDB Streams, AWS PITR configuration, source KMS key references and replica settings are not reproduced by this table resource. Configure the corresponding backend data-protection and event requirements separately.

##### Migration and operation

The new table starts empty. Convert application access, load the data, and test key lookups, queries, expiry and recovery before switching traffic. Oracle operates the NoSQL service; the customer manages compartment access, capacity, storage limits and the chosen recovery procedures. Use a different listed adaptation when the application must keep runtime DynamoDB API calls.

##### Example monthly charges

This Tensor9 Cloud Adapter scenario estimates service charges for the named origin and target services. Adapter hosting and commercial Tensor9 fees need separate allocations. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method and what the estimates include.

**Native or deployment mapping.** The mapping provisions OCI NoSQL tables without exposing a DynamoDB management endpoint. There is no DynamoDB request-serving fabric on this path. Cost estimates describe the selected service resources; operation coverage remains separate.

##### DynamoDB · DynamoDB read units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB read units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-ashburn-1 (global list); currency: USD.

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/e9d4806414954cdb8a28cb7522acca37b5c68defb92c2f8a67d3719216681f41-light.svg)

![DynamoDB · DynamoDB read units: monthly service charges by DynamoDB read units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/17ea672e2636885eb1d9b047ef059e2705bb624788a1033478ae353d0d90cafe-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB read units (per second) | DynamoDB | OCI NoSQL Database | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 0.33 | 0.16 | -0.17 |
| 10 | 3.29 | 1.57 | -1.72 |
| 100 | 32.85 | 15.70 | -17.15 |
| 1,000 | 328.50 | 156.99 | -171.51 |
| 10,000 | 3,285.00 | 1,569.89 | -1,715.11 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000000597 | USD/read |
| Target list price · write | 0.0000011705 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.066 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Writes and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-ashburn-1 (global list), USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Native/deployment comparison scope: The mapping provisions OCI NoSQL tables without exposing a DynamoDB management endpoint. There is no DynamoDB request-serving fabric on this path.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Oracle NoSQL Database Cloud on-demand capacity bills consumed 1 KB read and write units and stored GB. Absolute-consistency reads cost two read units; larger records cost one unit per KB. Provisioned capacity (USD 0.0064 per read unit-month and 0.1254 per write unit-month, parts B89738 and B89737) and the Always Free tables are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* OCI price list API: [https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-a45d0e6d8b183b039aefa956c723cea5c9269d3d` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [OCI price list API](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/).

##### DynamoDB · DynamoDB write units

Feature: DynamoDB.

Estimated monthly service charges by DynamoDB write units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-ashburn-1 (global list); currency: USD.

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/326071fedd417ddf54e87be9f953dec36c14e43713aaa431690dbdc2bae8069e-light.svg)

![DynamoDB · DynamoDB write units: monthly service charges by DynamoDB write units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/ba040c83d26b707872951942a219f9e1b4bf07849b5bb8e9d10ba31ea6378657-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| DynamoDB write units (per second) | DynamoDB | OCI NoSQL Database | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 1 | 1.64 | 3.08 | 1.43 |
| 10 | 16.43 | 30.76 | 14.34 |
| 100 | 164.25 | 307.60 | 143.35 |
| 1,000 | 1,642.50 | 3,076.01 | 1,433.51 |
| 10,000 | 16,425.00 | 30,760.08 | 14,335.08 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000000597 | USD/read |
| Target list price · write | 0.0000011705 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.066 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Reads and storage remain independent. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-ashburn-1 (global list), USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Native/deployment comparison scope: The mapping provisions OCI NoSQL tables without exposing a DynamoDB management endpoint. There is no DynamoDB request-serving fabric on this path.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Oracle NoSQL Database Cloud on-demand capacity bills consumed 1 KB read and write units and stored GB. Absolute-consistency reads cost two read units; larger records cost one unit per KB. Provisioned capacity (USD 0.0064 per read unit-month and 0.1254 per write unit-month, parts B89738 and B89737) and the Always Free tables are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* OCI price list API: [https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-a45d0e6d8b183b039aefa956c723cea5c9269d3d` / `2026-10-22.planning.2`. Curve: `workload-2`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [OCI price list API](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/).

##### DynamoDB · Stored data

Feature: DynamoDB.

Estimated monthly service charges by Stored data. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: us-ashburn-1 (global list); currency: USD.

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/75c9397485a9166de32d73b4ecad392b7dee9224c3061c5cbde880ac1ad5b55c-light.svg)

![DynamoDB · Stored data: monthly service charges by Stored data. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/8adc345c56e772d47603c2eb55ee6ea7be8335491d7b9e3f07e2590a801dee93-dark.svg)

Comparison pills describe all sampled scale points; amounts beside each service are for the named workload. Costs The Same means within 20% at every point. Costs Depend includes mixed results and unpriced samples.

Sampled monthly charges in USD, rounded to cents. Difference means target minus origin; a positive difference means the target costs more.

| Stored data (GiB-month) | DynamoDB | OCI NoSQL Database | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 0.00 | 0.00 |
| 10 | 2.50 | 0.66 | -1.84 |
| 100 | 25.00 | 6.60 | -18.40 |
| 1,000 | 250.00 | 66.00 | -184.00 |
| 10,000 | 2,500.00 | 660.00 | -1,840.00 |
| 100,000 | 25,000.00 | 6,600.00 | -18,400.00 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000000597 | USD/read |
| Target list price · write | 0.0000011705 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.066 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |

* Request meters remain at their independently authored defaults. Other native meters and workload assumptions retain their explicitly displayed default quantities. Workload translation and capacity assumptions are not benchmark measurements.
* Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts. Rates as of 2026-10-22: us-east-1 → us-ashburn-1 (global list), USD/month.
* Source prices are reference charges, not an invoice. Target lines cover selected service usage/configuration only; adapter hosting and Tensor9 fees are excluded.
* Samples of explicit prices are not performance measurements or capacity qualification. No interpolation or break-even guarantee is implied.
* Variant assumptions show the first axis sample; any axis-dependent configuration is described by this curve's workload note.
* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.
* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.
* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.
* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.
* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.
* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.
* Native/deployment comparison scope: The mapping provisions OCI NoSQL tables without exposing a DynamoDB management endpoint. There is no DynamoDB request-serving fabric on this path.
* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.
* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.
* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.
* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.
* Oracle NoSQL Database Cloud on-demand capacity bills consumed 1 KB read and write units and stored GB. Absolute-consistency reads cost two read units; larger records cost one unit per KB. Provisioned capacity (USD 0.0064 per read unit-month and 0.1254 per write unit-month, parts B89738 and B89737) and the Always Free tables are not selected.
* AWS Price List API, AmazonDynamoDB offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json)
* Amazon DynamoDB pricing: [https://aws.amazon.com/dynamodb/pricing/](https://aws.amazon.com/dynamodb/pricing/)
* OCI price list API: [https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/)

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

List prices read: 2026-10-22. Model: `plan-a45d0e6d8b183b039aefa956c723cea5c9269d3d` / `2026-10-22.planning.2`. Curve: `workload-3`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [OCI price list API](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/).

**DynamoDB → OCI NoSQL Database: Authored native-usage planning example.** Native monthly usage priced at the cited provider list prices; listed target allowances apply where present, excluding invoice credits, taxes and negotiated discounts.

Scenario source region: us-east-1. Scenario target region: us-ashburn-1 (global list). Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: DynamoDB read units | 0.00 |
| Origin: DynamoDB write units | 0.00 |
| Origin: DynamoDB stored data | 0.00 |
| Origin: Control-plane calls | 0.00 |
| Target: Target read operations | 0.00 |
| Target: Target write operations | 0.00 |
| Target: Target retained physical data | 0.00 |
| Target: Additional broker replica storage | 0.00 |
| Target: Execution or worker CPU | 0.00 |
| Target: Execution or worker RAM | 0.00 |
| Target: Selected billable network | 0.00 |
| Target: Independent native resources | 0.00 |
| Target: Independent native resources | 0.00 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **0.00** |

Unestimated components: Adapter hosting, Tensor9 fees. A modeled adapted total and savings require these costs.

Cost scope: Modeled target native service and explicitly modeled state allocation; hosting and Tensor9 fees only when supplied.

Excluded costs and workload features:

* Additional network transfer, backups, KMS, one-time migration and operational labor unless an explicit meter includes them.
* Destination application execution and separately billed downstream services; supply those allocations separately.
* Taxes, discounts, credits and free-tier allowances not explicitly listed by this model.
* Unmodeled dependent services, task execution and operations outside the selected workload family.

**Scenario assumptions**

| Input | Value | Unit |
| - | -: | - |
| Origin list price · DynamoDB read units | 0.000000125 | USD/read request units |
| Origin list price · DynamoDB write units | 0.000000625 | USD/write request units |
| Origin list price · DynamoDB stored data | 0.25 | USD/GiB-month |
| Origin list price · Control-plane calls | 0 | USD/requests |
| Representative item size | 1,024 | bytes |
| Strongly consistent read fraction | 1 | fraction |
| Origin write-unit amplification | 1 | multiplier |
| Target reads per point read | 1 | operations |
| Target writes per item write | 1 | operations |
| Target list price · read | 0.0000000597 | USD/read |
| Target list price · write | 0.0000011705 | USD/write |
| Target price guess · provider operation | 0 | USD/provider operation |
| Target list price · GiB-month | 0.066 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target list price · network GiB | 0 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target price guess · vCPU-hour | 0 | USD/vCPU-hour |
| Target price guess · GiB-hour | 0 | USD/GiB-hour |
| Target price guess · resource-hour | 0 | USD/resource-hour |
| Target price guess · resource-month | 0 | USD/resource-month |
| Target price guess · input token | 0 | USD/input token |
| Target price guess · output token | 0 | USD/output token |
| Target monthly base charge | 0 | USD/month |
| Approximate target service minimum | 0 | USD/month |
| Minimum primary CPU | 2 | vCPU |
| Minimum primary RAM | 8 | GiB |
| Minimum primary disk | 100 | GiB |
| Additional full-price standby copy | 0 | 0 or 1 |
| Allocated share of provisioned cost | 1 | fraction |
| Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Planning peak / mean work | 2 | multiplier |
| Planning primary CPU utilization | 0.7 | fraction |
| Resident state reserved in RAM | 0.1 | fraction |
| Planning disk utilization | 0.8 | fraction |
| Maintenance and log disk reserve | 20 | GiB |
| Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Dependent object sink write price guess | 0.000005 | USD/write |
| DynamoDB read units | 0 | read request units |
| DynamoDB write units | 0 | write request units |
| DynamoDB stored data | 0 | GiB-month |
| Control-plane calls | 0 | requests |

* Translated reads: 0 operations.

* Translated writes: 0 operations.

* Translated resident physical data: 0 GiB-month.

* Native provider operations: 0 operations.

* Published payload: 0 GiB.

* Delivered payload: 0 GiB.

* Allocated execution CPU: 0 vCPU-hour.

* Allocated execution RAM: 0 GiB-hour.

* Independent resource allocation: 0 resource-hour.

* Independent inventory: 0 resource-month.

* Input tokens: 0 tokens.

* Output tokens: 0 tokens.

* Billable network: 0 GiB.

* Dependent object sink retained data: 0 GiB-month.

* Dependent object sink writes: 0 writes.

* Rates are cited provider list prices, editable for discounts, commitments or another region. Workload translation and capacity coefficients remain editable planning assumptions, not benchmark measurements or a commercial quote.

* Default-zero rates are explicit assumptions, not evidence that the deployed service or resource is free.

* Provisioned-unit minimums use an editable approximate allocation floor. Modeled target service cost is max(usage/allocation, minimum), with billable network, durable staging and dependent sinks added separately; actual RU/TU sizing, scaling increments and throughput remain unqualified.

* Durable staging is priced once: provisioned targets include adapter state in their selected allocation; native targets add a separate staging allocation when required. Adapter hosting is a separate allocation and must exclude resources already priced as staging, workers or target capacity.

* A declared adapter mapping and cost model do not establish implementation availability or service equivalence.

* This is a declared directed mapping; a planning estimate does not establish deployment or request-serving support.

* Native/deployment comparison scope: The mapping provisions OCI NoSQL tables without exposing a DynamoDB management endpoint. There is no DynamoDB request-serving fabric on this path.

* Authored planning assumptions, not measured adapter capacity. Origin rates are cited first-tier list prices, before free allowances and discounts.

* A cost scenario does not establish backend availability, protocol fidelity or production readiness. Registry serving status remains independent.

* The control plane and table facet describe the same family workload; allocate shared capacity once, not once per catalog facet.

* No transactional, global-table, Streams or scan pricing is inferred from ordinary on-demand point units.

* Oracle NoSQL Database Cloud on-demand capacity bills consumed 1 KB read and write units and stored GB. Absolute-consistency reads cost two read units; larger records cost one unit per KB. Provisioned capacity (USD 0.0064 per read unit-month and 0.1254 per write unit-month, parts B89738 and B89737) and the Always Free tables are not selected.

List prices read: 2026-10-22. Model: `plan-a45d0e6d8b183b039aefa956c723cea5c9269d3d` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AmazonDynamoDB offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonDynamoDB/current/us-east-1/index.json), [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/), [OCI price list API](https://apexapps.oracle.com/pls/apex/cetools/api/v1/products/).

## Costs

Estimated monthly service charges for each backend with a published cost model, at one sampled workload from that model's cost curve. Adapter hosting and Tensor9 fees are excluded. [How Tensor9 estimates costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/overview.md) explains the method, what the estimates include and how to read their qualifications.

| Origin API | Backend | Sampled workload | Price basis | Origin USD/month | Backend USD/month | Difference | Mapping |
| - | - | - | - | -: | -: | -: | - |
| `aws::1.0.0::dynamodb::control` | Azure Cosmos DB (provisioned) | DynamoDB read units: 100 per second | Cited list prices, 2026-10-22 | 32.85 | 23.36 | -9.49 | Service adapter |
| `aws::1.0.0::dynamodb::control` | Azure Cosmos DB (serverless) | DynamoDB read units: 100 per second | Cited list prices, 2026-10-22 | 32.85 | 65.70 | +32.85 | Service adapter |
| `aws::1.0.0::dynamodb::control` | Cloud Bigtable | DynamoDB read units: 100 per second; one copy | Cited list prices, 2026-10-22 | 32.85 | 474.50 | +441.65 | Service adapter |
| `aws::1.0.0::dynamodb::control` | Cloud SQL for PostgreSQL | DynamoDB read units: 100 per second; one copy | Cited list prices, 2026-10-22 | 32.85 | 118.18 | +85.33 | Service adapter |
| `aws::1.0.0::dynamodb::control` | Cloud Spanner | DynamoDB read units: 100 per second; one copy | Cited list prices, 2026-10-22 | 32.85 | 65.70 | +32.85 | Service adapter |
| `aws::1.0.0::dynamodb::control` | Firestore | DynamoDB read units: 100 per second | Cited list prices, 2026-10-22 | 32.85 | 78.84 | +45.99 | Service adapter |
| `aws::1.0.0::dynamodb::control` | OCI NoSQL Database | DynamoDB read units: 100 per second | Cited list prices, 2026-10-22 | 32.85 | 15.70 | -17.15 | Native or deployment |
| `aws::1.0.0::dynamodb::control` | PostgreSQL | DynamoDB read units: 100 per second; one copy | Cited list prices, 2026-10-22 | 32.85 | 80.90 | +48.05 | Service adapter |
| `aws::1.0.0::dynamodb::table` | Azure Cosmos DB (provisioned) | DynamoDB read units: 100 per second | Cited list prices, 2026-10-22 | 32.85 | 23.36 | -9.49 | Service adapter |
| `aws::1.0.0::dynamodb::table` | Azure Cosmos DB (serverless) | DynamoDB read units: 100 per second | Cited list prices, 2026-10-22 | 32.85 | 65.70 | +32.85 | Service adapter |
| `aws::1.0.0::dynamodb::table` | Cloud Bigtable | DynamoDB read units: 100 per second; one copy | Cited list prices, 2026-10-22 | 32.85 | 474.50 | +441.65 | Service adapter |
| `aws::1.0.0::dynamodb::table` | Cloud SQL for PostgreSQL | Read operations/s: 100 reads/s; HA | Reference rates, 2026-10-18 | 74.28 | 270.36 | +196.08 | Service adapter |
| `aws::1.0.0::dynamodb::table` | Cloud Spanner | DynamoDB read units: 100 per second; one copy | Cited list prices, 2026-10-22 | 32.85 | 65.70 | +32.85 | Service adapter |
| `aws::1.0.0::dynamodb::table` | Firestore | Read operations/s: 100 reads/s | Reference rates, 2026-10-18 | 74.28 | 117.49 | +43.22 | Service adapter |
| `aws::1.0.0::dynamodb::table` | OCI NoSQL Database | DynamoDB read units: 100 per second | Cited list prices, 2026-10-22 | 32.85 | 15.70 | -17.15 | Native or deployment |
| `aws::1.0.0::dynamodb::table` | PostgreSQL | DynamoDB read units: 100 per second; one copy | Cited list prices, 2026-10-22 | 32.85 | 80.90 | +48.05 | Service adapter |

Difference means backend minus origin; a positive difference means the backend costs more. Workloads and target configurations differ by model, so compare each row's difference at its stated workload rather than charges across rows.
Cost curves across workload sizes, with every assumption and exclusion: [Amazon DynamoDB costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/dynamodb.md).

## Service level agreements

> [!WARNING]
>
> These tables show Tensor9's standard service levels and adapters whose standard terms are still being defined. Your signed agreement determines the SLAs, covered adapters and operations, limits, remedies and support terms that apply to your deployment.

Listed terms cover requests sent through this service adapter. They do not cover direct connections to the target service or replace the cloud provider's own SLA. Each origin-to-target pair has its own terms or an explicit pending status.

See the [SLA tables](https://docs.tensor9.com/cloud-adapter-early-access/support/service-adapter-slas.md), [measurement rules](https://docs.tensor9.com/cloud-adapter-early-access/support/service-levels.md), and [scaling conditions](https://docs.tensor9.com/cloud-adapter-early-access/support/scaling-and-limits.md).

### DynamoDB to Azure Cosmos DB (provisioned)

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `azure::1.0.0::cosmosdb::provisioned`, Cosmos stores typed items in documents. Updates may use conditional PATCH, a partition-scoped stored procedure, or an ETag-guarded read/modify/write. Query windows and partition boundaries matter. Provisioned and serverless accounts retain their distinct throughput and index restrictions. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to Azure Cosmos DB (serverless)

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `azure::1.0.0::cosmosdb::serverless`, Cosmos stores typed items in documents. Updates may use conditional PATCH, a partition-scoped stored procedure, or an ETag-guarded read/modify/write. Query windows and partition boundaries matter. Provisioned and serverless accounts retain their distinct throughput and index restrictions. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to Cloud Bigtable

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `google::1.0.0::bigtable`, Items use row-atomic Bigtable storage. Multi-item transactions and unsupported secondary-index/stream semantics do not become covered merely because point reads are covered. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to Cloud SQL for PostgreSQL

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `google::1.0.0::cloudsql::postgresql`, The SQL-backed adapter maps items, expressions and indexes onto relational rows and transactions. Row locks, index maintenance, stream outboxes and transaction conflict handling can add work beyond a single statement. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to Firestore

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `google::1.0.0::firestore`, The adapter translates typed items to Firestore documents and uses the documented transactional behavior. Residual filtering, pagination and index choices determine how many documents the adapter must inspect for one DynamoDB response. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to Cloud Spanner

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `google::1.0.0::spanner`, The adapter lowers DynamoDB reads and writes into GoogleSQL and Spanner physical plans. Simple point calls differ from expression evaluation, secondary-index maintenance and transaction planning. Table DDL is asynchronous and has a separate control-plane path. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to OCI NoSQL Database

**SLA status:** Not applicable

The mapping provisions OCI NoSQL tables without exposing a DynamoDB management endpoint. There is no DynamoDB request-serving fabric on this path.

### DynamoDB to PostgreSQL

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `postgres::1.0.0::database`, The SQL-backed adapter maps items, expressions and indexes onto relational rows and transactions. Row locks, index maintenance, stream outboxes and transaction conflict handling can add work beyond a single statement. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to Provisioned Cosmos DB

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | Tests whether the endpoint can be reached, separately from whether requests complete correctly. |
| GetItem, plain PutItem / DeleteItem adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `GetItem`, `PutItem`, `DeleteItem` | Full item ≤4 KiB, at most 64 attributes and nesting depth 8. Covered read-consistency settings. Writes have no condition, ReturnValues absent/NONE, no secondary-index maintenance, and streams disabled. |
| UpdateItem, conditional or old-item-return PutItem / DeleteItem adapter-added latency | +5 ms monthly p99 | `aws::1.0.0::dynamodb`: `UpdateItem`, `PutItem`, `DeleteItem` | Full item ≤4 KiB; expression ≤2 KiB and at most 20 clauses; at most two maintained indexes; streams disabled. Use supported conditions and return-value options. Local retries and adapter metadata waits count. |
| Query, Scan adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `Query`, `Scan` | One page. The adapter may examine or load ≤100 items and ≤400 KiB of data, including items filtered out of the response. |
| BatchGetItem, BatchWriteItem adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `BatchGetItem`, `BatchWriteItem` | ≤100 items and ≤400 KiB of total data. Any smaller API limit still applies. Report items that were not processed. |
| Saving each write completely | Save all required data before returning success | `aws::1.0.0::dynamodb`: `PutItem`, `DeleteItem`, `UpdateItem`, `BatchWriteItem` | Save each write within its partition together with required metadata and records for pending follow-up work. Apply supported condition checks and writes together. No multi-item transaction SLA. |
| Base-table and index consistency | Read consistency as documented for this adapter | `aws::1.0.0::dynamodb`: `GetItem`, `PutItem`, `DeleteItem`, `UpdateItem`, `Query`, `Scan`, `BatchGetItem`, `BatchWriteItem` | Use a Strong-consistency Cosmos DB account for strongly consistent table and local secondary index reads. Global secondary indexes update asynchronously, with no fixed freshness deadline. Strongly consistent GSI requests are rejected. |
| Adapter autoscaling and limits | Automatic scaling within agreed traffic and deployment limits | Adapter behavior across requests | Agree limits for the mix of operations, full item and expression sizes, indexes and streams, Cosmos DB throughput mode (RU/s), partition and container layout, traffic growth and bursts, and spare capacity for failures. The standard service level promises no fixed request rate, reserved throughput or unlimited scaling. Backend capacity is separate. Adapter scaling delays still count toward the SLA while traffic stays within the agreed limits. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** Latency targets measure the time Tensor9's adapter adds to backend processing, not the application's total elapsed time. They do not replace the backend provider's SLA. Adapter time covers permission checks, deciding whether to accept a request, time waiting inside the adapter, request handling, coordination, retries, internal storage and response handling. Waiting for the backend service is excluded only when that wait is measured separately and the agreement allows the exclusion. Your agreement must name the covered deployment, operations, request limits and traffic limits. Unlisted operations are not automatically covered. Correct data and authorization behavior is required for every supported request; endpoint reachability does not excuse incorrect results.

**DynamoDB write limits.** A plain write has no `ConditionExpression` or legacy `Expected`, no returned old item (`ReturnValues` absent or `NONE`), and streams disabled. The index configuration must be covered by your agreement. Size limits include the full current item and any previous item the adapter must read. For a delete that does not read the old item, count the key and request size. Writes with streams enabled need a separate latency agreement. Table management, PartiQL and Streams operations are not covered here. Any smaller API limit still applies.

**Scaling limits.** Tensor9 automatically adds adapter capacity within the traffic growth, burst size and infrastructure limits in your agreement. The standard service level does not promise a fixed request rate or unlimited scaling. Capacity depends on request sizes and types, how traffic is distributed across keys or message groups, backend configuration and spare capacity for failures. More adapter processes cannot speed up every shared or sequential step. You remain responsible for backend-service capacity; failures caused independently by the provider are outside this SLA.

**Read the details.** Each linked service page lists the covered operations, request limits, measurement rules, data guarantees, scaling limits and examples. This summary does not add coverage beyond those terms. Your signed agreement determines the service levels that apply to your deployment.

#### Why these latency targets differ

Plain GetItem, PutItem and DeleteItem have a 1 ms target for the small-item shape. Plain writes exclude conditions, old-value returns, secondary-index maintenance and streams. Update/conditional requests have 5 ms because the implementation may select PATCH, a partition-scoped stored procedure or an ETag-guarded read/modify/write path. Expressions are bounded to 2 KiB and 20 clauses, with at most two maintained indexes. Query/Scan has 10 ms for a page of at most 100 examined items and 400 KiB; item batches have 20 ms for at most 100 items, subject to each API's smaller limit.

Native Cosmos document execution is measured separately. Residual filtering, retries, response conversion and adapter-owned metadata remain fabric work. The adapter target does not imply Cosmos returns in 1 ms or that provisioned-account terms apply to a serverless account. Conditional conflicts and throttling still require correct handling, even when they move a request outside a tightly bounded latency class.

#### Adapter and scope

These standard terms cover the DynamoDB table API adapted to **provisioned Azure Cosmos DB**. They do not apply interchangeably to a serverless Cosmos DB backend or the Cosmos DB queue adapter.

Your signed agreement determines the Cosmos DB consistency setting, capacity and partition configuration, deployment requirements, and covered request sizes and traffic levels.

#### Operations and latency

The operation terms below concern `GetItem`, `PutItem`, `DeleteItem`, `UpdateItem`, `Query`, `Scan`, `BatchGetItem` and `BatchWriteItem`, with the request options supported by the adapter. Larger supported requests retain their documented behavior without inheriting the latency rows' size limits or targets.

`TransactWriteItems`, `TransactGetItems` and `ExecuteTransaction` are outside this adapter's supported transaction scope and have no SLA here. Table lifecycle, PartiQL and DynamoDB Streams operations are not covered by these terms. A supported `ExecuteStatement` or `BatchExecuteStatement` does not inherit another operation's SLA because it performs related item work.

##### Which writes are covered

A plain write has no `ConditionExpression` or legacy `Expected` condition, `ReturnValues` absent or `NONE`, streams disabled, and the indexes specified in the agreement. Conditional writes and writes requesting supported previous-item values use the conditional-update class. `UpdateItem` uses that class regardless of how short its update expression looks.

Count the full items the adapter reads or changes, including previous items loaded to check conditions or return old values. Returning only a few fields through a DynamoDB projection does not make a larger item meet the size limit. For a plain delete that does not read the old item, the 4 KiB limit applies to the key and request.

Writes with streams enabled, and other supported request options outside these limits, need separately agreed latency targets. Sharing an operation name does not give them the same guarantee.

##### Which queries and batches are covered

To check whether a query meets the latency limits, record whether it reads the base table, an LSI or a GSI, its consistency mode, the items examined, and the data the adapter loaded. Filtering can discard many items before returning a small page. A small result does not prove that the request met those limits.

Each batch API retains its own smaller item and payload limits. Preserve per-item outcomes and unprocessed entries. A batch response is one API result, not proof that every submitted read or write succeeded.

#### Timing and responsibility

Adapter processing time includes authorization, encoding, expression processing, local queues, retries, coordination and response transformation. Native stored-procedure execution and attributable provider waits are measured separately.

That timing separation does not remove responsibility for Tensor9-authored behavior executing at the backend. An incorrect stored procedure, bad mapping or unnecessary expensive request remains an adapter issue even when Azure reports the resulting error or execution time.

A correctly reported failed condition is healthy request handling. Returning success too early, losing a response, or making the wrong change is an adapter failure. After a timeout, the write may have succeeded. Do not claim it failed unless that has been established.

#### Durability and consistency

The adapter may return success only after Cosmos DB has committed the change within its partition and the adapter has saved the required metadata or pending follow-up work. A supported condition check and its change must succeed or fail together within the scope the adapter supports.

Keeping changes within one partition atomic does not imply support for DynamoDB multi-item transactions. The adapter must never silently weaken a condition, lose adapter state already reported as saved or corrupt an item.

| Read or state behavior | Qualification |
| - | - |
| Strong base-table and LSI behavior | Requires the profile's Strong-consistency Cosmos DB account; another account setting is not equivalent |
| GSI reads | Asynchronous propagation with no fixed freshness deadline under these standard terms |
| Strong GSI request | Remains rejected; account consistency does not make it a valid origin request |
| Numeric values and item size | Preserve the profile's supported precision and 400 KiB functional item checks |
| Streams and table lifecycle | Separate profile behavior, without an additional numerical SLA under these standard terms |

GSI replication and adapter-owned stream state are different mechanisms. Ordinary eventual GSI lag does not excuse an incorrect index mapping or lost committed stream state. Table deletion and recreation do not acquire an instantaneous cleanup guarantee from the item-operation terms.

#### Scaling and backend sizing

The standard production model automatically adds adapter capacity within the agreement's workload limits. Delays in adding capacity within those limits still count toward adapter latency.

Provisioned Cosmos DB still needs an appropriate RU allocation, consistency mode and partition distribution. Record whether capacity uses manual or provider autoscale RU/s and which logical tables share a container. The same RU allocation does not guarantee the same origin-operation rate for every workload.

Independent partitions can support parallel work. Hot partitions, shared container consumers, local expression processing, retry amplification and stream-writer ownership can constrain completed operations. More adapter instances cannot create more backend RUs or remove per-key serialization.

No numerical maximum request rate is assigned here. A supported limit needs the exact mix, item and expression sizes, index and stream settings, key distribution, backend capacity and partition configuration, allowed traffic bursts and spare capacity for failures. It must measure useful completed origin operations, not a growing number of native retry attempts.

#### Worked example: update an order

The `orders` table receives an `UpdateItem` with a condition on its current version. The full item and expression fit the conditional-update class.

1. The adapter interprets the condition and prepares the supported partition-local mutation. This preparation is adapter work.
2. Cosmos DB executes the native mutation. Native execution time and request charge help explain backend cost and delay.
3. The adapter returns the origin-shaped result. Local retry and response handling remain part of the conditional-update adapter latency target.

A subsequent GSI query may observe the change later under the eventual index contract. That delay does not by itself establish corruption or failure of the item update.

#### Worked example: throttling during a traffic increase

Suppose 429 responses increase. Inspect RU consumption, partition pressure and competing workloads in the shared container. Then compare native calls per completed update, local retry delays and the selected mutation path.

Backend undersizing can require a capacity or workload change. If the adapter issues unnecessary requests or ignores supported tuning, the resulting pressure remains a Tensor9 issue. An Azure 429 response alone does not tell you whether Azure capacity or adapter behavior caused the problem.

If a base read sees the committed item but a GSI does not, inspect index lag and mapping separately from throttling. Do not blindly repeat the write to make the index catch up.

#### Evidence for support

Keep the operation, table and index path, account consistency, configured RU mode, full item and expression sizes, request charge where available, status, identifiers and incident timestamps. Include relevant shared-container and hot-partition observations, with recent tuning changes.

Use `tensor9 explain` for profile behavior and a safely captured request report for observed mapping. `x-t9-explain: true` executes the operation; do not replay a conditional mutation just to gather a report. An explanation is not proof that a write committed, or a continuous measurement of SLA compliance.

Remove tokens, keys, credentials and sensitive item values before sharing evidence. Tensor9 helps separate backend pressure, mapping behavior and adapter processing without requiring you to prove fault first.

### DynamoDB to Azure Cosmos DB (serverless)

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Small point reads adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `GetItem` | One complete item at most 4 KiB, at most 64 attributes and nesting depth 8; covered read-consistency and DynamoDB ProjectionExpression settings. Selecting fewer attributes does not reduce the full-item size used for this limit. No implicit follow-up page. |
| Plain small-item writes adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `DeleteItem`, `PutItem` | One complete item at most 4 KiB; no condition, ReturnValues absent or NONE, no streams and no secondary-index maintenance. A composite profile row is restricted to these plain-write shapes. |
| Conditional writes and updates adapter-added latency | +5 ms monthly p99 | `aws::1.0.0::dynamodb`: `DeleteItem`, `PutItem`, `UpdateItem` | One item at most 4 KiB, expression at most 2 KiB with at most 20 clauses; at most two maintained indexes. The agreement must name any stream-enabled variant. Local retries and adapter metadata waits count. |
| Bounded query and scan pages adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `Query`, `Scan` | One page; at most 100 items examined, each at most 4 KiB, at most 400 KiB decoded in total. The cap is on examined items, not only returned matches; residual filtering counts. |
| Bounded item batches adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `BatchGetItem`, `BatchWriteItem` | At most 25 item actions and 100 KiB aggregate full-item data. Per-item results and unprocessed-item behavior follow this backend's profile. |
| Bounded PartiQL statements adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `BatchExecuteStatement`, `ExecuteStatement` | At most 10 statements of 2 KiB each; at most 100 examined items or 400 KiB returned/decoded data. Only grammar and transaction forms supported by this target are covered. |
| DynamoDB Streams reads adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb-streams`: `DescribeStream`, `GetRecords`, `GetShardIterator`, `ListStreams` | One stream page, at most 100 records and 400 KiB total record data; a single shard iterator and the documented retention window. |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeContinuousBackups`, `DescribeEndpoints`, `DescribeLimits`, `DescribeTable`, `DescribeTimeToLive`, `ListTables`, `ListTagsOfResource`, `TagResource`, `UntagResource`, `UpdateContinuousBackups`, `UpdateTable`, `UpdateTimeToLive` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `GetItem`, `DeleteItem`, `PutItem`, `UpdateItem`, `Query`, `Scan`, `BatchGetItem`, `BatchWriteItem`, `BatchExecuteStatement`, `ExecuteStatement`, `CreateTable`, `DeleteTable`, `DescribeContinuousBackups`, `DescribeEndpoints`, `DescribeLimits`, `DescribeTable`, `DescribeTimeToLive`, `ListTables`, `ListTagsOfResource`, `TagResource`, `UntagResource`, `UpdateContinuousBackups`, `UpdateTable`, `UpdateTimeToLive` `aws::1.0.0::dynamodb-streams`: `DescribeStream`, `GetRecords`, `GetShardIterator`, `ListStreams` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `azure::1.0.0::cosmosdb::serverless`, Cosmos stores typed items in documents. Updates may use conditional PATCH, a partition-scoped stored procedure, or an ETag-guarded read/modify/write. Query windows and partition boundaries matter. Provisioned and serverless accounts retain their distinct throughput and index restrictions. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Small point reads: +1 ms monthly p99 (adapter-added).** `GetItem`. Key decoding, one physical-plan construction and bounded item conversion. The target database's own response time is separate.

**Plain small-item writes: +1 ms monthly p99 (adapter-added).** `DeleteItem`, `PutItem`. The simple write avoids expression evaluation, read/modify/write and index/outbox amplification.

**Conditional writes and updates: +5 ms monthly p99 (adapter-added).** `DeleteItem`, `PutItem`, `UpdateItem`. Expression parsing, update evaluation and result construction add CPU work; guarded updates can repeat local work after target conflicts.

**Bounded query and scan pages: +10 ms monthly p99 (adapter-added).** `Query`, `Scan`. Physical query planning, item decoding, filters, ordering and cursor generation scale with the examined page, including rows the response omits.

**Bounded item batches: +10 ms monthly p99 (adapter-added).** `BatchGetItem`, `BatchWriteItem`. The adapter builds and schedules item plans and assembles partial results; target-call fan-out is not free even when target waits are excluded.

**Bounded PartiQL statements: +10 ms monthly p99 (adapter-added).** `BatchExecuteStatement`, `ExecuteStatement`. PartiQL adds parse, validate and lowering stages before ordinary item execution; a statement is not automatically a point lookup.

**DynamoDB Streams reads: +10 ms monthly p99 (adapter-added).** `DescribeStream`, `GetRecords`, `GetShardIterator`, `ListStreams`. The adapter reads its stream/outbox representation and converts records, versions and cursors. Adapter-owned stream metadata waits remain on the clock.

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeContinuousBackups`, `DescribeEndpoints`, `DescribeLimits`, `DescribeTable`, `DescribeTimeToLive`, `ListTables`, `ListTagsOfResource`, `TagResource`, `UntagResource`, `UpdateContinuousBackups`, `UpdateTable`, `UpdateTimeToLive`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to Cloud Bigtable

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Small point reads adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `GetItem` | One complete item at most 4 KiB, at most 64 attributes and nesting depth 8; covered read-consistency and DynamoDB ProjectionExpression settings. Selecting fewer attributes does not reduce the full-item size used for this limit. No implicit follow-up page. |
| Plain small-item writes adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `DeleteItem`, `PutItem` | One complete item at most 4 KiB; no condition, ReturnValues absent or NONE, no streams and no secondary-index maintenance. A composite profile row is restricted to these plain-write shapes. |
| Conditional writes and updates adapter-added latency | +3 ms monthly p99 | `aws::1.0.0::dynamodb`: `DeleteItem`, `PutItem`, `UpdateItem` | One item at most 4 KiB, expression at most 2 KiB with at most 20 clauses; at most two maintained indexes. The agreement must name any stream-enabled variant. Local retries and adapter metadata waits count. |
| Bounded query and scan pages adapter-added latency | +5 ms monthly p99 | `aws::1.0.0::dynamodb`: `Query`, `Scan` | One page; at most 100 items examined, each at most 4 KiB, at most 400 KiB decoded in total. The cap is on examined items, not only returned matches; residual filtering counts. |
| Bounded item batches adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `BatchGetItem`, `BatchWriteItem` | At most 25 item actions and 100 KiB aggregate full-item data. Per-item results and unprocessed-item behavior follow this backend's profile. |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `GetItem`, `DeleteItem`, `PutItem`, `UpdateItem`, `Query`, `Scan`, `BatchGetItem`, `BatchWriteItem`, `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `google::1.0.0::bigtable`, Items use row-atomic Bigtable storage. Multi-item transactions and unsupported secondary-index/stream semantics do not become covered merely because point reads are covered. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Small point reads: +1 ms monthly p99 (adapter-added).** `GetItem`. Key decoding, one physical-plan construction and bounded item conversion. The target database's own response time is separate.

**Plain small-item writes: +1 ms monthly p99 (adapter-added).** `DeleteItem`, `PutItem`. The simple write avoids expression evaluation, read/modify/write and index/outbox amplification.

**Conditional writes and updates: +3 ms monthly p99 (adapter-added).** `DeleteItem`, `PutItem`, `UpdateItem`. Expression parsing, update evaluation and result construction add CPU work; guarded updates can repeat local work after target conflicts.

**Bounded query and scan pages: +5 ms monthly p99 (adapter-added).** `Query`, `Scan`. Physical query planning, item decoding, filters, ordering and cursor generation scale with the examined page, including rows the response omits.

**Bounded item batches: +10 ms monthly p99 (adapter-added).** `BatchGetItem`, `BatchWriteItem`. The adapter builds and schedules item plans and assembles partial results; target-call fan-out is not free even when target waits are excluded.

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `ListTables`, `UpdateTable`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to Cloud SQL for PostgreSQL

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Small point reads adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `GetItem` | One complete item at most 4 KiB, at most 64 attributes and nesting depth 8; covered read-consistency and DynamoDB ProjectionExpression settings. Selecting fewer attributes does not reduce the full-item size used for this limit. No implicit follow-up page. |
| Plain small-item writes adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `DeleteItem`, `PutItem` | One complete item at most 4 KiB; no condition, ReturnValues absent or NONE, no streams and no secondary-index maintenance. A composite profile row is restricted to these plain-write shapes. |
| Conditional writes and updates adapter-added latency | +3 ms monthly p99 | `aws::1.0.0::dynamodb`: `DeleteItem`, `PutItem`, `UpdateItem` | One item at most 4 KiB, expression at most 2 KiB with at most 20 clauses; at most two maintained indexes. The agreement must name any stream-enabled variant. Local retries and adapter metadata waits count. |
| Bounded query and scan pages adapter-added latency | +5 ms monthly p99 | `aws::1.0.0::dynamodb`: `Query`, `Scan` | One page; at most 100 items examined, each at most 4 KiB, at most 400 KiB decoded in total. The cap is on examined items, not only returned matches; residual filtering counts. |
| Bounded item batches adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `BatchGetItem`, `BatchWriteItem` | At most 25 item actions and 100 KiB aggregate full-item data. Per-item results and unprocessed-item behavior follow this backend's profile. |
| Bounded transactions adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `ExecuteTransaction`, `TransactGetItems`, `TransactWriteItems` | At most 10 actions and 40 KiB total item data, at most two tables, within the target's documented transaction scope. This row does not add transaction support to a profile that rejects it. |
| Bounded PartiQL statements adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `BatchExecuteStatement`, `ExecuteStatement` | At most 10 statements of 2 KiB each; at most 100 examined items or 400 KiB returned/decoded data. Only grammar and transaction forms supported by this target are covered. |
| DynamoDB Streams reads adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb-streams`: `DescribeStream`, `GetRecords`, `GetShardIterator`, `ListStreams` | One stream page, at most 100 records and 400 KiB total record data; a single shard iterator and the documented retention window. |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `DescribeTimeToLive`, `ListTables`, `ListTagsOfResource`, `TagResource`, `UntagResource`, `UpdateTable`, `UpdateTimeToLive` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `GetItem`, `DeleteItem`, `PutItem`, `UpdateItem`, `Query`, `Scan`, `BatchGetItem`, `BatchWriteItem`, `ExecuteTransaction`, `TransactGetItems`, `TransactWriteItems`, `BatchExecuteStatement`, `ExecuteStatement`, `CreateTable`, `DeleteTable`, `DescribeTable`, `DescribeTimeToLive`, `ListTables`, `ListTagsOfResource`, `TagResource`, `UntagResource`, `UpdateTable`, `UpdateTimeToLive` `aws::1.0.0::dynamodb-streams`: `DescribeStream`, `GetRecords`, `GetShardIterator`, `ListStreams` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `google::1.0.0::cloudsql::postgresql`, The SQL-backed adapter maps items, expressions and indexes onto relational rows and transactions. Row locks, index maintenance, stream outboxes and transaction conflict handling can add work beyond a single statement. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Small point reads: +1 ms monthly p99 (adapter-added).** `GetItem`. Key decoding, one physical-plan construction and bounded item conversion. The target database's own response time is separate.

**Plain small-item writes: +1 ms monthly p99 (adapter-added).** `DeleteItem`, `PutItem`. The simple write avoids expression evaluation, read/modify/write and index/outbox amplification.

**Conditional writes and updates: +3 ms monthly p99 (adapter-added).** `DeleteItem`, `PutItem`, `UpdateItem`. Expression parsing, update evaluation and result construction add CPU work; guarded updates can repeat local work after target conflicts.

**Bounded query and scan pages: +5 ms monthly p99 (adapter-added).** `Query`, `Scan`. Physical query planning, item decoding, filters, ordering and cursor generation scale with the examined page, including rows the response omits.

**Bounded item batches: +10 ms monthly p99 (adapter-added).** `BatchGetItem`, `BatchWriteItem`. The adapter builds and schedules item plans and assembles partial results; target-call fan-out is not free even when target waits are excluded.

**Bounded transactions: +10 ms monthly p99 (adapter-added).** `ExecuteTransaction`, `TransactGetItems`, `TransactWriteItems`. Transaction validation, conditional plans, idempotency checks and commit-result assembly cost more than independent point operations.

**Bounded PartiQL statements: +10 ms monthly p99 (adapter-added).** `BatchExecuteStatement`, `ExecuteStatement`. PartiQL adds parse, validate and lowering stages before ordinary item execution; a statement is not automatically a point lookup.

**DynamoDB Streams reads: +10 ms monthly p99 (adapter-added).** `DescribeStream`, `GetRecords`, `GetShardIterator`, `ListStreams`. The adapter reads its stream/outbox representation and converts records, versions and cursors. Adapter-owned stream metadata waits remain on the clock.

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `DescribeTimeToLive`, `ListTables`, `ListTagsOfResource`, `TagResource`, `UntagResource`, `UpdateTable`, `UpdateTimeToLive`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

### DynamoDB to Firestore

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | Tests whether the endpoint can be reached, separately from whether requests complete correctly. |
| GetItem, plain PutItem / DeleteItem adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `GetItem`, `PutItem`, `DeleteItem` | Full item ≤4 KiB, at most 64 attributes and nesting depth 8. Covered read-consistency settings. Writes have no condition, ReturnValues absent/NONE, no secondary-index maintenance, and streams disabled. |
| UpdateItem, conditional or old-item-return PutItem / DeleteItem adapter-added latency | +3 ms monthly p99 | `aws::1.0.0::dynamodb`: `UpdateItem`, `PutItem`, `DeleteItem` | Full item ≤4 KiB; expression ≤2 KiB and at most 20 clauses; at most two maintained indexes; streams disabled. Use supported conditions and return-value options. Local retries and adapter metadata waits count. |
| Query, Scan adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `Query`, `Scan` | One page. The adapter may examine or load ≤100 items and ≤400 KiB of data, including items filtered out of the response. |
| TransactWriteItems adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `TransactWriteItems` | Supported combinations of operations, with ≤100 actions and ≤400 KiB of total data. Any smaller API or adapter limit still applies. |
| Saving writes without losing data | Save all required data before returning success | `aws::1.0.0::dynamodb`: `PutItem`, `DeleteItem`, `UpdateItem`, `TransactWriteItems` | Save both the backend data and required adapter records before returning success. The adapter must not lose data it has confirmed as saved. |
| Conditions, transactions and stored values | Preserve the behavior documented for this adapter | `aws::1.0.0::dynamodb`: `GetItem`, `PutItem`, `DeleteItem`, `UpdateItem`, `Query`, `Scan`, `TransactWriteItems` | Apply each condition check and write together. Preserve supported all-or-nothing transactions, number values, and read/index behavior. The supported item-size limit remains 400 KiB. |
| Adapter autoscaling and limits | Automatic scaling within agreed traffic and deployment limits | Adapter behavior across requests | Agree limits for the mix of operations, full item and expression sizes, indexes, heavily used documents, which process writes stream records, traffic growth and bursts, and spare capacity for failures. The standard service level promises no fixed request rate, reserved throughput or unlimited scaling. Backend capacity is separate. Adapter scaling delays still count toward the SLA while traffic stays within the agreed limits. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** Latency targets measure the time Tensor9's adapter adds to backend processing, not the application's total elapsed time. They do not replace the backend provider's SLA. Adapter time covers permission checks, deciding whether to accept a request, time waiting inside the adapter, request handling, coordination, retries, internal storage and response handling. Waiting for the backend service is excluded only when that wait is measured separately and the agreement allows the exclusion. Your agreement must name the covered deployment, operations, request limits and traffic limits. Unlisted operations are not automatically covered. Correct data and authorization behavior is required for every supported request; endpoint reachability does not excuse incorrect results.

**DynamoDB write limits.** A plain write has no `ConditionExpression` or legacy `Expected`, no returned old item (`ReturnValues` absent or `NONE`), and streams disabled. The index configuration must be covered by your agreement. Size limits include the full current item and any previous item the adapter must read. For a delete that does not read the old item, count the key and request size. Writes with streams enabled need a separate latency agreement. Table management, PartiQL and Streams operations are not covered here. Any smaller API limit still applies.

**Scaling limits.** Tensor9 automatically adds adapter capacity within the traffic growth, burst size and infrastructure limits in your agreement. The standard service level does not promise a fixed request rate or unlimited scaling. Capacity depends on request sizes and types, how traffic is distributed across keys or message groups, backend configuration and spare capacity for failures. More adapter processes cannot speed up every shared or sequential step. You remain responsible for backend-service capacity; failures caused independently by the provider are outside this SLA.

**Read the details.** Each linked service page lists the covered operations, request limits, measurement rules, data guarantees, scaling limits and examples. This summary does not add coverage beyond those terms. Your signed agreement determines the service levels that apply to your deployment.

#### Why these latency targets differ

Plain point requests have a 1 ms target for items up to 4 KiB, with at most 64 attributes and nesting depth 8. Plain writes have no condition, old-value return, secondary-index maintenance or stream work. The 3 ms conditional/update class adds expression parsing and bounded item manipulation; it permits at most 20 expression clauses and two maintained indexes. The 10 ms page class accounts for decoding and filtering up to 100 examined items, including discarded items. A transaction with up to 100 actions has a separate 20 ms budget for validation, planning and result handling.

Backend document execution is measured separately; adapter-owned catalog, coordination, retry and response work remains included. Changing the request shape changes its class rather than quietly raising the point-request limit.

#### Adapter and scope

These standard terms cover the DynamoDB table API adapted to Google Cloud Firestore. They distinguish the adapter's processing from Firestore execution, while keeping the adapter responsible for correct translation, acknowledgment and response handling.

Your signed agreement determines which deployment is covered, where timing starts and stops, and which request sizes and traffic levels are covered.

#### Operations and latency

The operation terms below concern `GetItem`, `PutItem`, `DeleteItem`, `UpdateItem`, `Query`, `Scan` and `TransactWriteItems`, with the request options supported by the adapter. Larger supported requests retain their documented behavior without inheriting the small-request latency targets.

`BatchGetItem`, `BatchWriteItem` and `TransactGetItems` are not covered by these standard terms. Table lifecycle, PartiQL and DynamoDB Streams operations are also outside these terms. Absence from this SLA is not a statement that an operation is unsupported; consult the directed service profile for support.

##### Plain writes and conditional updates

A plain `PutItem` or `DeleteItem` has no `ConditionExpression` or legacy `Expected` condition, has `ReturnValues` absent or `NONE`, uses the index configuration specified in the agreement, and has streams disabled.

A request that checks a supported condition or asks for supported values from the previous item needs more work. It belongs in the conditional-update class, not the plain-write class. `UpdateItem` always belongs in the update class, even when it only changes one small attribute.

The item-size limit includes the complete item the adapter reads or changes, including any previous item needed to evaluate a condition. A DynamoDB projection returning 100 bytes does not bring a larger item the adapter loaded within that limit. For a plain delete that does not read the old item, the 4 KiB bound applies to the key and request instead.

Writes with streams enabled, and other supported request options outside these limits, need separately agreed latency targets. They do not inherit these latency values merely because the operation name is the same.

##### Queries and transactions

Record whether a query reads the base table, an LSI or a GSI, along with its consistency mode and declared indexes. A filter returning five results after examining thousands of candidates does not meet the query row's limits.

The transaction class covers only the combinations described by this adapter's profile. The performance-class limit does not extend API limits or add support for stream-enabled transactions. A supported request that exceeds these limits has no latency target from this row. The adapter must not truncate its result to meet that target.

#### What the latency includes

Included work covers permission checks, reading the request, processing expressions, accepting or queueing the request, local retries, coordination, and preparing the response. Firestore transaction and commit waits are separately measured when measurements reliably show how long Firestore took.

Local retry delays remain adapter time even when contention triggered them. A timing span named after Firestore is not sufficient evidence that all time inside it was spent waiting on Firestore.

A correct `ConditionalCheckFailedException` is a valid result. Evaluating the condition incorrectly, losing the response, or returning success for a failed write is an adapter failure.

#### Durability and consistency

The adapter must handle every supported request correctly:

* Return success for a write only after the required Firestore commit and adapter-state updates.
* Keep a supported condition check and its write together, and ensure supported transactions either complete all their changes or make none.
* Preserve the profile's supported numeric domain and reject unsupported numeric values rather than silently rounding them.
* Enforce the 400 KiB item limit. This API limit is separate from the smaller 4 KiB limit for the latency target.
* Honor the declared base-table and index behavior rather than substituting an unrestricted scan or an unchecked write.

Exact supported signed 64-bit integers do not imply support for every DynamoDB decimal. Check the profile when workloads depend on wider numeric precision.

Item durability is not a promise of immediate physical erasure after table deletion. Table lifecycle and cleanup behavior have separate semantics and are not assigned a deletion deadline here.

#### Scaling and limits

In the standard production model, Tensor9 automatically adds adapter capacity within the agreement's workload limits. Your team is not responsible for routinely adjusting the number of adapter instances. Delays in adding capacity within those limits still count toward adapter latency.

Independent keys can supply parallel work. A heavily contended document, shared coordination stage or table-scoped stream-writer ownership can limit scale even when more workers are available. Firestore quotas and backend contention are distinct from time spent processing expressions, queueing requests, and retrying.

The standard terms do not set a numerical maximum request rate. A useful agreed limit must identify the operation mix, item and expression sizes, indexes, consistency, streams, key distribution, allowed traffic bursts and spare capacity for failures. It measures completed origin operations while preserving latency and correctness, not just requests sent toward Firestore.

Do not add separately measured read and update maxima together. Both operations can share workers and state, while conditional updates do substantially more work per request.

#### Worked example: conditional order update

The `orders` table stores a small order with a `version` attribute. An application uses `UpdateItem` to change its status only if the stored version matches the version it read.

1. The adapter decodes the expression and prepares the supported Firestore operation. This is adapter work.
2. Firestore evaluates the native transaction and commits the change, or reports a conflict. The separately measured time spent waiting for the backend is recorded separately.
3. The adapter returns the DynamoDB-shaped success or conditional failure. Local retry and response work remain covered.

A competing update can make the condition false. Returning the expected conditional-check failure satisfies the request's semantics; the SLA does not promise that every requested mutation succeeds.

#### Worked example: one hot order

Suppose many workers update the same order and p99 response time rises. Compare Firestore contention, key distribution, local queueing and retries for the same interval.

If native contention increases while local processing stays stable, changing the workload's contention pattern can be more effective than adding adapter instances. If retries multiply native calls or a local queue grows while Firestore has headroom, Tensor9 investigates the adapter behavior. Both conditions can occur together; a backend conflict is not a blanket exclusion.

#### Evidence for support

Keep the operation, table and index selection, consistency mode, full item and expression sizes, examined candidate count, status, timestamps and request identifiers. Record index or stream configuration changes that preceded the incident.

Use `tensor9 explain` to inspect the directed profile. A request-level Explain report can help relate selected behavior to observed calls; it is not a continuous measurement of SLA compliance. `x-t9-explain: true` executes the request while recording an explanation, so do not replay an order mutation merely to obtain a report.

Share sanitized evidence through the agreed support channel. Remove credentials, tokens and sensitive item values while preserving the shape, sizes and identifiers needed to correlate the incident. Tensor9 helps investigate both adapter and backend behavior; you do not need to prove fault before contacting support.

### DynamoDB to Spanner

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | Tests whether the endpoint can be reached, separately from whether requests complete correctly. |
| GetItem adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `GetItem` | Full item ≤4 KiB. Use the read-consistency and index settings covered by your agreement. |
| Plain PutItem / DeleteItem adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `PutItem`, `DeleteItem` | Full item ≤4 KiB, at most 64 attributes and nesting depth 8. Covered read-consistency settings. Writes have no condition, ReturnValues absent/NONE, no secondary-index maintenance, and streams disabled. |
| UpdateItem, conditional or old-item-return PutItem / DeleteItem adapter-added latency | +3 ms monthly p99 | `aws::1.0.0::dynamodb`: `UpdateItem`, `PutItem`, `DeleteItem` | Full item ≤4 KiB; expression ≤2 KiB and at most 20 clauses; at most two maintained indexes; streams disabled. Use supported conditions and return-value options. Local retries and adapter metadata waits count. |
| Query, Scan adapter-added latency | +5 ms monthly p99 | `aws::1.0.0::dynamodb`: `Query`, `Scan` | One page. The adapter may examine or load ≤100 items and ≤400 KiB of data, including items filtered out of the response. |
| BatchGetItem, BatchWriteItem adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `BatchGetItem`, `BatchWriteItem` | ≤100 items and ≤400 KiB of total data. Any smaller API limit still applies. Report items that were not processed. |
| TransactGetItems, TransactWriteItems adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `TransactGetItems`, `TransactWriteItems` | Supported combinations of operations, with ≤100 actions and ≤400 KiB of total data. Any smaller API or adapter limit still applies. |
| Saving writes without losing data | Save all required data before returning success | `aws::1.0.0::dynamodb`: `PutItem`, `DeleteItem`, `UpdateItem`, `BatchWriteItem`, `TransactWriteItems` | Save both the backend data and required adapter records before returning success. Recovering adapter records must not lose data already confirmed as saved. |
| Transactions, reads and stored values | Preserve the behavior documented for this adapter | `aws::1.0.0::dynamodb`: `GetItem`, `PutItem`, `DeleteItem`, `UpdateItem`, `Query`, `Scan`, `BatchGetItem`, `BatchWriteItem`, `TransactGetItems`, `TransactWriteItems` | Transactions must be all-or-nothing and safe to retry as documented. Preserve exact decimals and strongly consistent table reads; update indexes with the transaction. Strongly consistent GSI reads are unsupported. |
| Adapter autoscaling and limits | Automatic scaling within agreed traffic and deployment limits | Adapter behavior across requests | Agree limits for the mix of operations, full item and transaction sizes, indexes, total connections and sessions, heavily used rows, traffic growth and bursts, and spare capacity for failures. The standard service level promises no fixed request rate, reserved throughput or unlimited scaling. Backend capacity is separate. Adapter scaling delays still count toward the SLA while traffic stays within the agreed limits. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** Latency targets measure the time Tensor9's adapter adds to backend processing, not the application's total elapsed time. They do not replace the backend provider's SLA. Adapter time covers permission checks, deciding whether to accept a request, time waiting inside the adapter, request handling, coordination, retries, internal storage and response handling. Waiting for the backend service is excluded only when that wait is measured separately and the agreement allows the exclusion. Your agreement must name the covered deployment, operations, request limits and traffic limits. Unlisted operations are not automatically covered. Correct data and authorization behavior is required for every supported request; endpoint reachability does not excuse incorrect results.

**DynamoDB write limits.** A plain write has no `ConditionExpression` or legacy `Expected`, no returned old item (`ReturnValues` absent or `NONE`), and streams disabled. The index configuration must be covered by your agreement. Size limits include the full current item and any previous item the adapter must read. For a delete that does not read the old item, count the key and request size. Writes with streams enabled need a separate latency agreement. Table management, PartiQL and Streams operations are not covered here. Any smaller API limit still applies.

**Scaling limits.** Tensor9 automatically adds adapter capacity within the traffic growth, burst size and infrastructure limits in your agreement. The standard service level does not promise a fixed request rate or unlimited scaling. Capacity depends on request sizes and types, how traffic is distributed across keys or message groups, backend configuration and spare capacity for failures. More adapter processes cannot speed up every shared or sequential step. You remain responsible for backend-service capacity; failures caused independently by the provider are outside this SLA.

**Read the details.** Each linked service page lists the covered operations, request limits, measurement rules, data guarantees, scaling limits and examples. This summary does not add coverage beyond those terms. Your signed agreement determines the service levels that apply to your deployment.

#### Why these latency targets differ

GetItem and plain small writes each have a 1 ms target. A plain write avoids conditions, old-value returns, secondary-index maintenance and streams. The conditional/update class has 3 ms for bounded expression work and physical-plan construction; a bounded query/scan page has 5 ms for up to 100 examined items and 400 KiB decoded data. Batches and transactions retain a separate 20 ms budget for up to 100 actions/items, subject to the smaller limit of each API.

Only separately measured Spanner application-operation waits are candidates for exclusion. Adapter metadata and coordination stored in Spanner remain adapter work.

#### Adapter and scope

These standard terms cover the DynamoDB table API adapted to Google Cloud Spanner. The adapter commitment concerns correct handling and the processing it adds; it is not a guarantee that a complete Spanner transaction finishes within the adapter's latency budget.

Your signed agreement determines the deployment requirements and the request sizes, traffic levels, and traffic bursts it covers.

#### Operations and latency

The operation terms concern the operations in the table with the request options supported by the adapter. Supported requests outside a latency row's size and count limits retain their documented behavior without inheriting that row's latency target. Table lifecycle, PartiQL and DynamoDB Streams operations are not covered by these terms. This profile does not provide DynamoDB Streams support.

An equal threshold does not combine measurements: report `TransactGetItems` and `TransactWriteItems` separately, just as successful high-volume reads must not hide failing writes.

##### Which write class applies?

The plain-write class requires no `ConditionExpression` or legacy `Expected` condition, `ReturnValues` absent or `NONE`, streams disabled, and the index configuration specified in the agreement.

A supported condition or supported previous-item return puts `PutItem` and `DeleteItem` in the conditional-update class. `UpdateItem` always uses that class. The request determines which row applies. A faster execution path does not let the adapter choose a different row afterward.

The 4 KiB limit applies to the full items the adapter reads, loads, or changes, including any previous item needed for a condition or response. Returning only a few fields through a DynamoDB projection does not make a larger item qualify. For a plain delete that does not load the old item, measure the key and request size instead.

##### Pages, batches and transactions

For a query, record the base-table or index path, consistency choice and examined data. A page returning ten items does not meet the query limit if the adapter had to scan many more items before filtering them.

A batch's API-specific item limit still applies even though the shared performance class says “at most 100.” Preserve individual item outcomes and unprocessed items rather than treating an HTTP success as proof that every item completed.

The transaction performance class is narrower than some supported API maxima. Supported combinations and idempotency-token behavior remain part of correctness; a request is not allowed to lose atomicity to fit the latency class.

#### What counts toward adapter latency

Include authorization, decoding, expression evaluation, mutation preparation, local queueing, connection or session acquisition, coordination, retry scheduling and response handling. These costs remain adapter work even when they occur inside a function that calls Spanner.

Time spent waiting for Spanner to execute and commit a request is reported separately when it can be measured. Measure the adapter and backend portions of the same request. Subtracting the p99 of one benchmark from the p99 of another does not tell you how much time the adapter added.

Correctly reporting a failed condition is a valid result. If the write commits but the adapter loses the response, the caller did not receive a successful response. Check whether repeating the operation is safe before retrying.

#### Durability and consistency

The standard obligations include:

* Return success for writes only after the required Spanner and adapter commits.
* Preserve data reported as successfully saved when the adapter recovers its state.
* Preserve supported decimal values exactly and enforce the 400 KiB item limit.
* Keep supported multi-item transactions atomic and preserve documented idempotency behavior.
* Provide the documented strong reads from the base table and update native indexes as part of the same commit.

Spanner's native capabilities do not broaden the origin API. In particular, a DynamoDB GSI request cannot acquire support for `ConsistentRead=true` simply because Spanner can perform strong reads. The adapter must preserve the supported origin request rules.

These correctness obligations apply to every supported request. Native storage durability remains a separate provider responsibility.

#### Scaling and limits

The standard production model automatically adds adapter capacity. The agreed limits must describe how many application operations can complete for the actual workload, including adapter work before and between backend calls.

Independent transactions and keys can supply parallel work. Shared connection and session budgets, hot rows, local expression processing and repeated conflicts can limit useful completions. Adding replicas without a fleet-wide connection budget can move the bottleneck or make contention worse.

The standard terms do not assign a numerical maximum request rate. A point-read limit cannot be multiplied by the number of actions in a transaction to establish transaction capacity. Qualify the transaction mix, action count, item sizes, indexes, conflict distribution, traffic growth and spare capacity for failures separately.

The customer's Spanner sizing affects native execution capacity. Tensor9 remains responsible for unnecessary repeated work and local queueing within the agreed adapter workload limits; “increase Spanner capacity” is not an adequate answer when the delay is in a local pool.

#### Worked example: order and inventory transaction

The application uses `TransactWriteItems` to create an order and decrement its inventory item. The action count and all data loaded by the adapter meet the transaction row's limits.

1. The adapter validates the supported actions and prepares their native transaction. Authorization, expression and encoding work count as adapter processing time.
2. Spanner executes and commits the transaction. Separately measured backend wait is measured separately.
3. The adapter constructs the origin response. The response must reflect the transaction's atomic outcome.

The adapter latency target does not cap total transaction duration. Atomicity applies regardless of whether a particular request meets that performance class.

#### Worked example: slow requests with spare backend capacity

Suppose requests slow down while Spanner metrics show available capacity. Local session acquisition grows, and retries occupy workers for longer.

Tensor9 investigates waits for a connection or session, total connections, retry scheduling and traffic mix. Increasing backend capacity may not reduce those delays. Conversely, if native contention dominates after local queues are ruled out, support helps examine hot rows, transaction scope and backend sizing.

If a transaction times out, it may already have committed. Check what happened before retrying. Do not repeat it with a new identity on the assumption that the first attempt did nothing.

#### Evidence for support

Capture operation names, transaction action counts, full item and expression sizes, indexes, consistency, result classes, request identifiers and the incident interval. Keep local queue, pool, retry and native execution observations together.

An Explain report can help identify the selected path and captured calls, but it does not prove a commit that the report did not observe, and it does not continuously measure SLA compliance. `x-t9-explain: true` executes the requested operation; use it only when repeating that operation is safe, or capture it on an already intended request.

Remove tokens, credentials and sensitive item values from support material. Preserve sizes, conditions' structure and correlation identifiers so Tensor9 can investigate without needing sensitive customer data or requiring you to prove who caused the problem.

### DynamoDB to OCI NoSQL Database

**SLA status:** Not applicable

The application uses the OCI NoSQL API on this mapping. It does not provide a DynamoDB request translator, so DynamoDB fabric latency does not apply.

### DynamoDB to PostgreSQL

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Small point reads adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `GetItem` | One complete item at most 4 KiB, at most 64 attributes and nesting depth 8; covered read-consistency and DynamoDB ProjectionExpression settings. Selecting fewer attributes does not reduce the full-item size used for this limit. No implicit follow-up page. |
| Plain small-item writes adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::dynamodb`: `DeleteItem`, `PutItem` | One complete item at most 4 KiB; no condition, ReturnValues absent or NONE, no streams and no secondary-index maintenance. A composite profile row is restricted to these plain-write shapes. |
| Conditional writes and updates adapter-added latency | +3 ms monthly p99 | `aws::1.0.0::dynamodb`: `DeleteItem`, `PutItem`, `UpdateItem` | One item at most 4 KiB, expression at most 2 KiB with at most 20 clauses; at most two maintained indexes. The agreement must name any stream-enabled variant. Local retries and adapter metadata waits count. |
| Bounded query and scan pages adapter-added latency | +5 ms monthly p99 | `aws::1.0.0::dynamodb`: `Query`, `Scan` | One page; at most 100 items examined, each at most 4 KiB, at most 400 KiB decoded in total. The cap is on examined items, not only returned matches; residual filtering counts. |
| Bounded item batches adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `BatchGetItem`, `BatchWriteItem` | At most 25 item actions and 100 KiB aggregate full-item data. Per-item results and unprocessed-item behavior follow this backend's profile. |
| Bounded transactions adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `ExecuteTransaction`, `TransactGetItems`, `TransactWriteItems` | At most 10 actions and 40 KiB total item data, at most two tables, within the target's documented transaction scope. This row does not add transaction support to a profile that rejects it. |
| Bounded PartiQL statements adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb`: `BatchExecuteStatement`, `ExecuteStatement` | At most 10 statements of 2 KiB each; at most 100 examined items or 400 KiB returned/decoded data. Only grammar and transaction forms supported by this target are covered. |
| DynamoDB Streams reads adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::dynamodb-streams`: `DescribeStream`, `GetRecords`, `GetShardIterator`, `ListStreams` | One stream page, at most 100 records and 400 KiB total record data; a single shard iterator and the documented retention window. |
| Table and configuration API responses adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::dynamodb`: `CreateTable`, `DeleteTable`, `DescribeTable`, `DescribeTimeToLive`, `ListTables`, `ListTagsOfResource`, `TagResource`, `UntagResource`, `UpdateTable`, `UpdateTimeToLive` | One logical table, at most 20 attributes and two declared indexes, or a list page of at most 100 tables. Measures request handling and status response, not the time until target DDL, backup, restore or index build finishes. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::dynamodb`: `GetItem`, `DeleteItem`, `PutItem`, `UpdateItem`, `Query`, `Scan`, `BatchGetItem`, `BatchWriteItem`, `ExecuteTransaction`, `TransactGetItems`, `TransactWriteItems`, `BatchExecuteStatement`, `ExecuteStatement`, `CreateTable`, `DeleteTable`, `DescribeTable`, `DescribeTimeToLive`, `ListTables`, `ListTagsOfResource`, `TagResource`, `UntagResource`, `UpdateTable`, `UpdateTimeToLive` `aws::1.0.0::dynamodb-streams`: `DescribeStream`, `GetRecords`, `GetShardIterator`, `ListStreams` | Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA. |
| Endpoint reachability | 99.9% per calendar month | Adapter endpoint reachability | The agreed production deployment has healthy target connectivity and receives a valid adapter health probe. This measures the adapter endpoint, not the target provider's service. |
| Adapter autoscaling and limits | Automatic scaling within the workload and deployment limits in your agreement | Adapter behavior across requests | Your agreement states the maximum request rate, burst size, request and response sizes, concurrency, and target calls per request. Tensor9 maintains adapter capacity inside that envelope. Target-service quotas and capacity are separate. |

**Adapter-added latency.** A + prefix marks time added by the adapter, not the total time your application waits. Total request time includes adapter processing, backend service time and network time. The backend provider's SLA applies independently. Only separately measured target-service wait may be subtracted, and only when your agreement permits it; internal metadata, coordination and retry processing still count. For one request, 12 ms of adapter processing plus 90 ms waiting for the backend means at least 102 ms total. This example does not add monthly p99 values.

**What Tensor9 covers.** These service levels cover the adapter between the origin API and target API. They do not replace the target provider's SLA.

**How latency is counted.** Adapter work, including metadata and coordination, counts. Only separately measured permitted target waits are excluded.

**Which terms apply.** Your signed agreement names the covered operations, workload limits, remedies, and final service levels for your deployment.

#### What this adapter does

For `postgres::1.0.0::database`, The SQL-backed adapter maps items, expressions and indexes onto relational rows and transactions. Row locks, index maintenance, stream outboxes and transaction conflict handling can add work beyond a single statement. The 1 ms point-operation objective is deliberately narrow. A conditional write, scanned page, transaction or control-plane request uses its own row. Stored procedures or SQL that implement the application operation are target execution; adapter catalog, coordination and retry work must not be mislabeled as application-database wait.

#### How the latency targets were chosen

**Small point reads: +1 ms monthly p99 (adapter-added).** `GetItem`. Key decoding, one physical-plan construction and bounded item conversion. The target database's own response time is separate.

**Plain small-item writes: +1 ms monthly p99 (adapter-added).** `DeleteItem`, `PutItem`. The simple write avoids expression evaluation, read/modify/write and index/outbox amplification.

**Conditional writes and updates: +3 ms monthly p99 (adapter-added).** `DeleteItem`, `PutItem`, `UpdateItem`. Expression parsing, update evaluation and result construction add CPU work; guarded updates can repeat local work after target conflicts.

**Bounded query and scan pages: +5 ms monthly p99 (adapter-added).** `Query`, `Scan`. Physical query planning, item decoding, filters, ordering and cursor generation scale with the examined page, including rows the response omits.

**Bounded item batches: +10 ms monthly p99 (adapter-added).** `BatchGetItem`, `BatchWriteItem`. The adapter builds and schedules item plans and assembles partial results; target-call fan-out is not free even when target waits are excluded.

**Bounded transactions: +10 ms monthly p99 (adapter-added).** `ExecuteTransaction`, `TransactGetItems`, `TransactWriteItems`. Transaction validation, conditional plans, idempotency checks and commit-result assembly cost more than independent point operations.

**Bounded PartiQL statements: +10 ms monthly p99 (adapter-added).** `BatchExecuteStatement`, `ExecuteStatement`. PartiQL adds parse, validate and lowering stages before ordinary item execution; a statement is not automatically a point lookup.

**DynamoDB Streams reads: +10 ms monthly p99 (adapter-added).** `DescribeStream`, `GetRecords`, `GetShardIterator`, `ListStreams`. The adapter reads its stream/outbox representation and converts records, versions and cursors. Adapter-owned stream metadata waits remain on the clock.

**Table and configuration API responses: +20 ms monthly p99 (adapter-added).** `CreateTable`, `DeleteTable`, `DescribeTable`, `DescribeTimeToLive`, `ListTables`, `ListTagsOfResource`, `TagResource`, `UntagResource`, `UpdateTable`, `UpdateTimeToLive`. Logical-table catalogs and lifecycle state must be persisted and validated. Their storage latency is adapter work even when the catalog uses the same database as application items.

Your signed agreement sets the terms for your deployment. A target does not add an operation or option that the compatibility tables mark unavailable.

#### What counts toward latency

For a request-response row, measure from the agreed ingress boundary to dispatch of the complete response. A row that explicitly names a first response chunk ends at that chunk; its number does not cover the rest of the stream. A long-poll row names the intentional wait and when adapter delay starts. Include parsing, authorization, admission, translation, serialization, adapter-owned storage and coordination, retries and response handling. Subtract only separately measured target-workload waits and external network segments allowed by the measurement rules. The adapter's own response handling and dispatch remain covered. A database used for adapter metadata is still adapter work, even if a cloud provider hosts it.

For concurrent calls, exclude the union of permitted wait intervals, not the sum of overlapping spans. Calculate each request's adapter duration first, then the monthly p99. Do not subtract one service's p99 from another's. Known adapter timeouts are over-budget samples; failed or incomplete requests cannot disappear to improve the percentile. Missing measurements do not become zero latency. An SDK call span alone does not prove how much of its duration can be excluded.

#### Endpoint reachability and request failures

The endpoint-reachability target measures adapter health checks. Correctly forwarding a target quota or permission error is different from producing that error because the adapter sent the wrong request. Adapter-caused failures remain Tensor9's responsibility even when the target is healthy.

Correctness and data-integrity requirements apply to every supported request. Endpoint reachability does not measure request correctness or grant an allowance for incorrect results.

#### Scaling and target-service capacity

Watch adapter CPU and allocation rate alongside target read/write capacity, partition hot spots and connection/session limits. Scale adapter replicas on outstanding work, not QPS alone: a 100-item scan and a GetItem differ substantially. Tensor9 is responsible for autoscaling within the agreed per-operation concurrency, item-size, page and burst limits. The customer selects and sizes the target, including Cosmos RU/s, Spanner capacity or SQL connections; scaling the adapter cannot remove a hot partition or a database quota.

Tell Tensor9 the expected steady rate, bursts, concurrency, payload sizes and operation mix. Tensor9 sizes and scales the adapter for the agreed load; you choose and monitor the target service's capacity with Tensor9's help. A latency budget is not a requests-per-second rating. Larger requests and higher rates need explicit terms, not silent inheritance of a small-request SLA.

#### Data and behavior guarantees

Conditional writes must not silently lose their condition, and a transaction must not report atomic success after a partial commit. Exact number representation, consistency, secondary-index behavior and stream ordering remain those documented for this target. A request outside that support is rejected or handled as explicitly documented, not made correct by meeting a latency percentile. The underlying database's durability commitment is not a Tensor9 storage SLA.

#### Example and diagnosis

In `orders`, GetItem for a 3 KiB item uses the point-read row. Query that examines 90 items but returns only two still uses the page row. An UpdateItem with a version condition uses the conditional-write row. In Explain, compare adapter expression/planning/serialization work with the measured target operation; a rise in Cosmos throttling or Spanner execution time is different from a rise in adapter queueing or catalog lookups.

Use `tensor9 explain` and the documented explain headers to understand the selected adapter and its behavior. Correlate available request diagnostics with the target provider's latency, throttling and capacity metrics. An explain report helps diagnose a request; it is not by itself a qualified SLA timing measurement. Share the operation, request shape, timestamps and request identifiers with support, with credentials and customer payloads removed.

## Install and run

The documentation and SLAs are public. Downloading and running the Cloud Adapter binary requires an entitled customer account. Set `T9_API_KEY` as described in [Install and Authenticate](https://docs.tensor9.com/cloud-adapter-early-access/getting-started/install-and-authenticate.md), then list the adapters your account may use with this origin:

```sh theme={null}
tensor9 adapt svc list \
  -origin aws::1.0.0::dynamodb::table
```

The result is limited to directed mappings for this origin that your account is entitled to use. Use a returned backend identifier when configuring the adapter or investigating a request.

Request binary access from [hello@tensor9.com](mailto:hello@tensor9.com) if your account does not yet include this direction.

## Existing data and credentials

Selecting a backend does not copy existing data, credentials or access policies. Plan and verify migration separately before changing an application's endpoint. Do not assume an identifier, credential or encrypted value from the origin service works unchanged on the target.

## Configure, tune and debug

Start with [setup](https://docs.tensor9.com/cloud-adapter-early-access/getting-started/overview.md) and [configuration](https://docs.tensor9.com/cloud-adapter-early-access/configuration/overview.md). Use [tuning](https://docs.tensor9.com/cloud-adapter-early-access/tuning/overview.md) to understand supported request tags, [debugging](https://docs.tensor9.com/cloud-adapter-early-access/debugging/overview.md) to investigate a request, and [High Fidelity Cloud Emulators](https://docs.tensor9.com/cloud-adapter-early-access/local-testing/overview.md) to validate a bounded reproduction.

For requests that go through an entitled service adapter, use [tensor9 explain](https://docs.tensor9.com/cloud-adapter-early-access/debugging/explain.md) and [x-t9-explain](https://docs.tensor9.com/cloud-adapter-early-access/debugging/response-headers.md) to inspect the selected mapping.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.