> ## 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.

# SQS (FIFO)

> SQS (FIFO) APIs with Cloud Adapter.

This page describes how SQS (FIFO) 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 SQS (FIFO) with its adaptation on each backend.
A dash means this profile does not state the capability for that backend.

### Cloud Adapter

| Capability | SQS (FIFO) | Akamai, Azure, DigitalOcean, OCI, Private Kubernetes, and Scaleway · PostgreSQL | Azure · Azure Service Bus | Azure · Azure Cosmos DB (queue) | Azure · PostgreSQL Flexible Server | Google Cloud | Scaleway · Scaleway Managed Database for PostgreSQL |
| - | - | - | - | - | - | - | - |
| Ordering · delivery order | Yes - per-group FIFO | Yes - oldest message of each group first; same contract (per-MessageGroupId, one in flight per group) | Yes - broker-exclusive sessions (session = MessageGroupId), Service Bus coordinates session ownership across adapter instances | Yes - transactional per-group order; conservative ordered-batch redelivery; independent groups concurrent | Yes - oldest message of each group first; same contract on the managed server (per-MessageGroupId, one in flight per group) | Yes - oldest message of each group first; same contract (per-MessageGroupId, one in flight per group) | Yes - oldest message of each group first; same contract (per-MessageGroupId, one in flight per group) |
| Deduplication · dedup window | Yes - explicit MessageDeduplicationId + content-based, 5-min window | Yes - both modes, over a marker table in the same Postgres; 5-minute window | Partial - broker-native duplicate detection; fresh-id echo (not the original id) + no send-side SequenceNumber | Yes - both modes (explicit tag or content hash), 5-min window; echoes the original MessageId and SequenceNumber; reproduces the neither-tag-nor-dedup rejection | Yes - both modes, over a marker table in the same Postgres; 5-minute window | Yes - both modes, over a marker table in the same Postgres; 5-minute window | Yes - both modes, over a marker table in the same Postgres; 5-minute window |
| Message group · group ordering | ordered per group-id | per MessageGroupId (oldest message of each group first) | session = MessageGroupId (broker-exclusive) | per group-id (the ordering unit) | per MessageGroupId (oldest message of each group first) | per MessageGroupId (oldest message of each group first) | per MessageGroupId (oldest message of each group first) |
| Delivery guarantee | ordered per group; duplicate sends suppressed for 5 minutes; consumer redelivery remains possible | at-least-once, in order per group | at-least-once in order per group; duplicate sends suppressed by the broker within the window | at-least-once with in-window dedup (duplicate sends suppressed) | at-least-once, in order per group | at-least-once, in order per group | at-least-once, in order per group |
| Dead-letter | Yes - native redrive (maxReceiveCount) | Yes - atomic maxReceiveCount move only in the same supported SQS message database transaction | Yes - native delivery-count limit + auto-forward to the declared (session-enabled) DLQ entity | No - cross-partition / cross-store transfer and redrive unsupported | Yes - atomic maxReceiveCount move only in the same supported SQS message database transaction | Yes - atomic maxReceiveCount move only in the same supported SQS message database transaction | Yes - atomic maxReceiveCount move only in the same supported SQS message database transaction |
| Visibility timeout · max hold | up to 12 h | honored (30 s default) | ≤ 5 min (session-lock cap; longer is rejected with an error, extends via renewal) | stored deadline; SQS validation, no broker lock ceiling, conservative batch restriction | honored (30 s default) | honored (30 s default) | honored (30 s default) |
| Receipt handle · restart durability | stateless, durable | a durable handle that survives an adapter restart | - | - | a durable handle that survives an adapter restart | a durable handle that survives an adapter restart | a durable handle that survives an adapter restart |
| Max message size · per message | 1 MiB | 256 KB | 256 KB | 256 KB (well under the 2 MB Cosmos document cap) | 256 KB | 256 KB | 256 KB |
| Long-polling · receive wait | up to 20 s | bounded by WaitTimeSeconds (poll loop) | native (session accept may overrun \~60 s worst case) | poll (the adapter checks Cosmos DB until a message arrives or the wait ends) | bounded by WaitTimeSeconds (poll loop) | bounded by WaitTimeSeconds (poll loop) | bounded by WaitTimeSeconds (poll loop) |
| Message retention · message lifetime | up to 14 d | retention enforced on message age (60 s..14 d) | - | durable logical expiry; TTL / bounded cleanup reclaim eligible state | retention enforced on message age (60 s..14 d) | retention enforced on message age (60 s..14 d) | retention enforced on message age (60 s..14 d) |
| API coverage | full | high (FIFO SQS semantics, subject to the selected PostgreSQL image/version, SQS SIP revision, FIFO schema and group/deduplication configuration. Registry version 1.0.0 is not the database version. Classic SQS installation/recovery evidence does not qualify FIFO; exact selected FIFO behavior and Kubernetes deployment require their own evidence.) | high | high | high | high | high |
| Duplicate-send echo | Yes - echoes the original MessageId/SequenceNumber | - | Partial - returns a fresh MessageId corresponding to no delivered message | Yes - echoes the original MessageId and SequenceNumber (crash-safe) | - | - | - |
| SequenceNumber on send | Yes - returned on every FIFO send | - | No - omitted (the broker sequence is asynchronous); receive-side sequence is real | Yes - the per-group sequence position, monotonic per group (the Service Bus backend omits it) | - | - | - |
| Receipt handle · restart durability | Yes - stateless, durable | - | Partial - session-lock-bound; an adapter restart invalidates in-flight handles | Yes - stateless data; survives an adapter restart, with no broker lock behind it (unlike the Service Bus backend) | - | - | - |
| Message retention · TTL scope | strictly per-message | - | expiry of the first message can expire its whole session | - | - | - | - |
| Single-group throughput | up to 10 msg per receive batch | - | 1 msg per round-trip per group (the one-in-flight strictness); scales with concurrent groups | - | - | - | - |
| Multi-pod clock skew · one-in-flight vs skew | service-owned time | - | - | database-side acceptance and stored expiry; host clocks do not decide deduplication or receipt eligibility | - | - | - |
| FIFO / ordering | Yes - ordered per MessageGroupId; up to 10 messages in an ordered receive batch | - | - | - | Yes - oldest message of each group first; same contract on the managed server | - | - |
| Explicit deduplication | Yes - explicit MessageDeduplicationId | - | - | - | Yes - served (marker table, 5-minute window) | - | - |
| Content-based deduplication | Yes - SHA-256(body) dedup key | - | - | - | Yes - served (SHA-256 of the body, same marker table) | - | - |
| Durability · cluster-rebuild survival | SQS: managed, cross-AZ | - | - | - | queue data is stored on the managed Flexible Server outside the Cloud Adapter deployment cluster and survives a cluster rebuild | - | - |
| Shared-server tenancy · shared database | dedicated SQS | - | - | - | one shared Flexible Server + one shared database per Cloud Adapter deployment; every SQS queue on the Cloud Adapter deployment co-locates as a table-per-queue in that database, with no cross-Cloud Adapter deployment co-location | - | - |
| Server size · SKU / storage default | AWS-managed capacity | - | - | - | uses a fixed default server size and storage allocation because an SQS queue declares no source instance size | - | - |
| Maintenance and shared capacity · shared server | per-queue isolation | - | - | - | the shared server has one maintenance window and shared compute, so a heavy queue can affect neighbors on the same Cloud Adapter deployment server (the shared-server tradeoff) | - | - |

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

### PostgreSQL

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Dead-letter redrive | Dead-letter | Supported | Most usage | fires automatically once a message passes maxReceiveCount |
| Content/ID deduplication | FIFO | Supported | Most usage | both modes are served: an explicit MessageDeduplicationId takes precedence over the content hash (AWS's own rule), and a content-based queue derives a stable digest of the body. The message insert and deduplication marker share one transaction. A duplicate rolls back its new row and returns the original message identifiers |
| FIFO ordering | FIFO | Supported | Common | per-MessageGroupId strict order with one message in flight per group; each receive takes the oldest message of each group |
| Message attributes | Messages | Supported | Common | - |
| GetQueueAttributes | Queues | Supported | Most usage | reads queue attributes, including approximate message counts |
| GetQueueUrl | Queues | Supported | Most usage | resolves the queue by name |
| DeleteMessage | Send / receive | Supported | Common | resolves by receipt handle; a stale handle returns ReceiptHandleIsInvalid |
| DeleteMessageBatch | Send / receive | Supported | Common | returns the result for each entry |
| ReceiveMessage | Send / receive | Supported | Common | long-poll (WaitTimeSeconds) honored; one message in flight per MessageGroupId |
| SendMessage | Send / receive | Supported | Common | MessageGroupId required on send (the AWS FIFO rule); MD5 checksums match what your SDK verifies |
| SendMessageBatch | Send / receive | Supported | Common | up to 10 messages per call, each with its MessageGroupId; returns the result for each entry |
| ChangeMessageVisibility | Visibility | Supported | Common | resolves by receipt handle; a stale handle is rejected rather than silently succeeding |

#### PostgreSQL hosting

Tensor9 operates CloudNativePG inside the customer's Kubernetes cluster. Queue data is stored on that cluster's volumes and does not survive a full cluster rebuild. Plan recovery and message cutover before replacing the cluster. Tensor9 operates the queue schema and adapter. Queues start empty; existing SQS messages are not migrated. Drain each message group before cutover to preserve order.

#### Persistent queue management and total cost

Cloud Adapter retains a persistent PostgreSQL store for the queue catalog, tenancy and lifecycle/control state, normally shared with the Cloud Adapter deployment. Native broker or Cosmos message storage does not remove this resource. Include its allocated compute, storage, backups and selected HA costs alongside adapter and message-backend charges; an idle or serverless message backend does not imply a zero total installation floor. Backend-only curves omit these shared allocations unless their assumptions explicitly include them.

This control store is distinct from the SQS-owned message database. PostgreSQL-authority FIFO composites add recoverable message bodies, receipts, deduplication and outbox state to an explicitly configured SQS message database; they do not store messages in the shared control catalog. A separate logical database and login provide data/permission separation, but still share server CPU, storage, IOPS, WAL and connection limits when hosted on the same instance. Dedicated physical server/instance capacity is a separate allocation and cost decision.

#### Database placement and recovery

CloudNativePG keeps message tables on your Kubernetes cluster's persistent volumes. Tensor9 operates the database and adapter. Replacing the cluster requires an explicit data recovery or drained cutover procedure; a new empty cluster is not a recovery of the old queues. This placement shares cluster resources with the application.

#### Capacity and queue workload

The default shared message database holds multiple queues, each with its own table. Dedicated physical server/instance capacity isolates compute and I/O from other server workloads; a separate logical database alone does not. HA changes recovery, commit latency and price rather than FIFO semantics. Neither choice creates an unlimited queue service. Size connection pools, storage, IOPS and WAL for accepted sends, receives, deletes, visibility changes, retries and cleanup together. Long polls wait outside database transactions.

The single-message receive mechanism below permits one message in flight per group. If a group takes T seconds from receive to settlement, its useful completion rate is bounded by roughly 1/T, even when other groups are idle. A larger MaxNumberOfMessages can collect heads from multiple groups; it does not create a ten-message pipeline within one group. Adding consumers or database CPU does not remove that serialization. Compare the separate ordered-batch design before selecting a workload that depends on within-group batching.

Requested live counts scan the message population even for a single requested counter. Frequent depth polling over a large backlog competes for database I/O and pool capacity; receipt classification can change index/heap work. Price those queries separately from sends and completed message cycles. A fall in depth can reflect purge, expiry or dead-letter transfer rather than application completion.

The portable Standard-queue benchmark does not establish the capacity of this host, its HA configuration or a FIFO workload. Payload sizes, active-group skew, settlement time, backlog growth and matched native measurements determine whether a proposed size fits. Missing measurements leave capacity unknown.

#### Retries, batches and application changes

The application keeps its SQS SDK and uses the adapter's configured endpoint and authentication. Backend IAM, database schema permissions and TLS identity belong to the deployment; an AWS ARN or policy is not automatically a target-cloud authorization grant. Scope identities to the customer resources and keep rotated credentials out of message bodies and receipt handles.

A batch response reports each entry separately. Retry only failed entries whose outcome is known; a request timeout can follow a committed send or delete. Keep the same effective deduplication ID on uncertain retries. Duplicate enqueue suppression does not make consumer side effects exactly once. SDK retries and adapter retries share one bounded deadline, with backoff for provider throttling. An expired observer deadline does not prove a still-running native operation was cancelled.

Visibility expiration permits another delivery while an earlier worker can still be executing. Consumers use idempotent writes, choose a visibility duration that covers normal processing and handle stale receipt errors. Retention can expire a message in flight. Queues start empty: drain the source before cutover, group by group. Queue recreation and purge must invalidate old claims independently of public names; data cleanup can continue after logical retirement. Database or broker backup is a resource recovery mechanism, not an automatic replay of application side effects.

#### PostgreSQL queue behavior

Your application keeps its SQS SDK and uses the authenticated Cloud Adapter endpoint configured for the install. The adapter performs `SendMessage` and `ReceiveMessage` in the SQS-owned PostgreSQL message database and returns SQS responses, error codes and MD5 checksums. Its message-data login is separate from other services and the shared control catalog.

Each queue is a PostgreSQL table with one row per message. Sending, receiving, deleting, delays, visibility, dead-letter delivery and message counts all work on those rows. FIFO queues add ordering by message group, per-group sequence numbers and duplicate detection. Consumers can still receive a message more than once.

![Before: on AWS the application's SQS SDK calls Amazon SQS. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS API with one PostgreSQL table per queue.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMuIEFmdGVyOiBpbiB0aGUgdGFyZ2V0IGNsb3VkIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggaW1wbGVtZW50cyB0aGUgU1FTIEFQSSB3aXRoIG9uZSBQb3N0Z3JlU1FMIHRhYmxlIHBlciBxdWV1ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyODgiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gU1FTPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiNjYmQ1ZTEiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI3NzQiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMXB4Ij5Qb3N0Z3JlczwvdGV4dD4KPHRleHQgeD0iNzc0IiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj50YWJsZSBwZXIgcXVldWU8L3RleHQ+Cjwvc3ZnPg==)

![Before: on AWS the application's SQS SDK calls Amazon SQS. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS API with one PostgreSQL table per queue.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMuIEFmdGVyOiBpbiB0aGUgdGFyZ2V0IGNsb3VkIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggaW1wbGVtZW50cyB0aGUgU1FTIEFQSSB3aXRoIG9uZSBQb3N0Z3JlU1FMIHRhYmxlIHBlciBxdWV1ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyODgiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gU1FTPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiM0NzU1NjkiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI3NzQiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMXB4Ij5Qb3N0Z3JlczwvdGV4dD4KPHRleHQgeD0iNzc0IiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij50YWJsZSBwZXIgcXVldWU8L3RleHQ+Cjwvc3ZnPg==)

The application keeps its SQS SDK. The adapter stores each queue in a PostgreSQL table.

#### Architecture

The adapter keeps all queue state in PostgreSQL, including messages and receipt handles, so adapter instances can restart or scale out without losing track of in-flight messages. On Cloud SQL and Azure Flexible Server it signs in with short-lived Cloud SQL IAM or Microsoft Entra tokens used as database passwords, so no static secret is stored.

When the stack is deployed, Tensor9 creates one database per Cloud Adapter deployment and one table per declared queue. Each row holds the message body and attributes, its message group, its visibility time, its receipt handle, its receive count and the time it was sent. A FIFO queue orders messages within each message group; each row's arrival position gives its sequence number. A dead-letter queue is another queue table, and a background task deletes messages older than the queue's retention period.

CloudNativePG, Cloud SQL for PostgreSQL, Azure Flexible Server and Scaleway use the same adapter code and tables. They differ in where the data lives: the managed servers run outside your Kubernetes cluster, while CloudNativePG runs inside it. See the rebuild limitation below.

![The adapter stores messages, receipt handles, receive counts and visibility times in PostgreSQL: one table per queue, and another table for each dead-letter queue. A background task removes messages past their retention. FIFO messages also store their message group and sequence number, and each group has at most one message in flight.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQ0IiB2aWV3Qm94PSIwIDAgODM2IDI0NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciBzdG9yZXMgbWVzc2FnZXMsIHJlY2VpcHQgaGFuZGxlcywgcmVjZWl2ZSBjb3VudHMgYW5kIHZpc2liaWxpdHkgdGltZXMgaW4gUG9zdGdyZVNRTDogb25lIHRhYmxlIHBlciBxdWV1ZSwgYW5kIGFub3RoZXIgdGFibGUgZm9yIGVhY2ggZGVhZC1sZXR0ZXIgcXVldWUuIEEgYmFja2dyb3VuZCB0YXNrIHJlbW92ZXMgbWVzc2FnZXMgcGFzdCB0aGVpciByZXRlbnRpb24uIEZJRk8gbWVzc2FnZXMgYWxzbyBzdG9yZSB0aGVpciBtZXNzYWdlIGdyb3VwIGFuZCBzZXF1ZW5jZSBudW1iZXIsIGFuZCBlYWNoIGdyb3VwIGhhcyBhdCBtb3N0IG9uZSBtZXNzYWdlIGluIGZsaWdodC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InFhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIyNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDYiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyNiIgeT0iNDQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNCIgeT0iMTA0IiB3aWR0aD0iOTYiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzIiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNzIiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjcyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTIwIiB5MT0iMTQyIiB4Mj0iMTUyIiB5Mj0iMTQyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjcWEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iMTU0IiB5PSIxMTIiIHdpZHRoPSIxNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjI0IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTNweCI+VGVuc29yOSBhZGFwdGVyPC90ZXh0Pgo8dGV4dCB4PSIyMjQiIHk9IjE1NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c3RhdGUgaW4gUG9zdGdyZVNRTDwvdGV4dD4KPGxpbmUgeDE9IjI5NiIgeTE9IjE0MiIgeDI9IjM2MCIgeTI9IjE0MiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3FhKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+Cjx0ZXh0IHg9IjMyOCIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+U1FMPC90ZXh0Pgo8dGV4dCB4PSIzMjgiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPnRva2VuIHNpZ24taW48L3RleHQ+CjxyZWN0IHg9IjM2NCIgeT0iNTgiIHdpZHRoPSI0NTYiIGhlaWdodD0iMTY0IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjU5MSIgeT0iODIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5Qb3N0Z3JlU1FMPC90ZXh0Pgo8dGV4dCB4PSI1OTEiIHk9Ijk4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNjQ3NDhiIj5vbmUgZGF0YWJhc2UgcGVyIGFwcGxpYW5jZSDCtyBvbmUgdGFibGUgcGVyIHF1ZXVlPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjExMCIgd2lkdGg9IjIwNiIgaGVpZ2h0PSI3NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0ODMiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+bWVzc2FnZSByb3dzPC90ZXh0Pgo8dGV4dCB4PSI0ODMiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm9uZSByb3cgcGVyIG1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQ4MyIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+Ym9keSDCtyBhdHRyaWJ1dGVzIMK3IHNlbmQgdGltZTwvdGV4dD4KPHJlY3QgeD0iNTk4IiB5PSIxMTAiIHdpZHRoPSIyMDYiIGhlaWdodD0iNzQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNzAxIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+RklGTyBncm91cHM8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5ncm91cCBpZCDCtyBzZXF1ZW5jZSBudW1iZXI8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjE5MiIgd2lkdGg9IjQzNiIgaGVpZ2h0PSIyMiIgcng9IjYiIHN0cm9rZS13aWR0aD0iMSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1OTgiIHk9IjIwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6OS41cHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPnNhbWUgYWRhcHRlciBvbiBldmVyeSBQb3N0Z3JlU1FMIGhvc3Q8L3RleHQ+Cjwvc3ZnPg==)

![The adapter stores messages, receipt handles, receive counts and visibility times in PostgreSQL: one table per queue, and another table for each dead-letter queue. A background task removes messages past their retention. FIFO messages also store their message group and sequence number, and each group has at most one message in flight.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQ0IiB2aWV3Qm94PSIwIDAgODM2IDI0NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciBzdG9yZXMgbWVzc2FnZXMsIHJlY2VpcHQgaGFuZGxlcywgcmVjZWl2ZSBjb3VudHMgYW5kIHZpc2liaWxpdHkgdGltZXMgaW4gUG9zdGdyZVNRTDogb25lIHRhYmxlIHBlciBxdWV1ZSwgYW5kIGFub3RoZXIgdGFibGUgZm9yIGVhY2ggZGVhZC1sZXR0ZXIgcXVldWUuIEEgYmFja2dyb3VuZCB0YXNrIHJlbW92ZXMgbWVzc2FnZXMgcGFzdCB0aGVpciByZXRlbnRpb24uIEZJRk8gbWVzc2FnZXMgYWxzbyBzdG9yZSB0aGVpciBtZXNzYWdlIGdyb3VwIGFuZCBzZXF1ZW5jZSBudW1iZXIsIGFuZCBlYWNoIGdyb3VwIGhhcyBhdCBtb3N0IG9uZSBtZXNzYWdlIGluIGZsaWdodC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InFhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIyNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDYiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyNiIgeT0iNDQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNCIgeT0iMTA0IiB3aWR0aD0iOTYiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzIiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNzIiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjcyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTIwIiB5MT0iMTQyIiB4Mj0iMTUyIiB5Mj0iMTQyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjcWEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iMTU0IiB5PSIxMTIiIHdpZHRoPSIxNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjI0IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTNweCI+VGVuc29yOSBhZGFwdGVyPC90ZXh0Pgo8dGV4dCB4PSIyMjQiIHk9IjE1NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c3RhdGUgaW4gUG9zdGdyZVNRTDwvdGV4dD4KPGxpbmUgeDE9IjI5NiIgeTE9IjE0MiIgeDI9IjM2MCIgeTI9IjE0MiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3FhKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+Cjx0ZXh0IHg9IjMyOCIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+U1FMPC90ZXh0Pgo8dGV4dCB4PSIzMjgiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPnRva2VuIHNpZ24taW48L3RleHQ+CjxyZWN0IHg9IjM2NCIgeT0iNTgiIHdpZHRoPSI0NTYiIGhlaWdodD0iMTY0IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjU5MSIgeT0iODIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5Qb3N0Z3JlU1FMPC90ZXh0Pgo8dGV4dCB4PSI1OTEiIHk9Ijk4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojOTRhM2I4Ij5vbmUgZGF0YWJhc2UgcGVyIGFwcGxpYW5jZSDCtyBvbmUgdGFibGUgcGVyIHF1ZXVlPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjExMCIgd2lkdGg9IjIwNiIgaGVpZ2h0PSI3NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0ODMiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+bWVzc2FnZSByb3dzPC90ZXh0Pgo8dGV4dCB4PSI0ODMiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm9uZSByb3cgcGVyIG1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQ4MyIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+Ym9keSDCtyBhdHRyaWJ1dGVzIMK3IHNlbmQgdGltZTwvdGV4dD4KPHJlY3QgeD0iNTk4IiB5PSIxMTAiIHdpZHRoPSIyMDYiIGhlaWdodD0iNzQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNzAxIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+RklGTyBncm91cHM8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5ncm91cCBpZCDCtyBzZXF1ZW5jZSBudW1iZXI8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjE5MiIgd2lkdGg9IjQzNiIgaGVpZ2h0PSIyMiIgcng9IjYiIHN0cm9rZS13aWR0aD0iMSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1OTgiIHk9IjIwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6OS41cHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPnNhbWUgYWRhcHRlciBvbiBldmVyeSBQb3N0Z3JlU1FMIGhvc3Q8L3RleHQ+Cjwvc3ZnPg==)

Each queue, including each dead-letter queue, is a PostgreSQL table. The same adapter runs on every supported PostgreSQL host.

#### Receiving messages

One database step selects messages whose visibility timeout has passed, oldest first, up to the requested batch size. In the same step it gives each a new receipt handle, hides it for the visibility timeout, adds one to its receive count and returns it. Messages another receiver is taking at that moment are skipped. FIFO queues return the next eligible message in each group, keeping one in flight per group. When the visibility timeout passes, the message can be delivered again; that does not stop a worker still processing the earlier copy.

`ApproximateReceiveCount` is the actual number of receives, not an estimate. The MD5 checksums of the body and attributes are recomputed, so your SDK's checks pass. `DelaySeconds` sets when a message first becomes visible. Long polling waits up to `WaitTimeSeconds` (at most 20 seconds) and returns as soon as a message is available. `SendMessageBatch` inserts all entries at once and reports a result for each entry. Message bodies are stored in the queue table.

![A receive takes the oldest visible messages and, in the same step, gives each a new receipt handle, hides it for the visibility timeout and adds one to its receive count. Two receivers at the same time get different messages. A message can be delivered again once its visibility timeout passes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIHJlY2VpdmUgdGFrZXMgdGhlIG9sZGVzdCB2aXNpYmxlIG1lc3NhZ2VzIGFuZCwgaW4gdGhlIHNhbWUgc3RlcCwgZ2l2ZXMgZWFjaCBhIG5ldyByZWNlaXB0IGhhbmRsZSwgaGlkZXMgaXQgZm9yIHRoZSB2aXNpYmlsaXR5IHRpbWVvdXQgYW5kIGFkZHMgb25lIHRvIGl0cyByZWNlaXZlIGNvdW50LiBUd28gcmVjZWl2ZXJzIGF0IHRoZSBzYW1lIHRpbWUgZ2V0IGRpZmZlcmVudCBtZXNzYWdlcy4gQSBtZXNzYWdlIGNhbiBiZSBkZWxpdmVyZWQgYWdhaW4gb25jZSBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0IHBhc3Nlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0icmEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJyZyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojMDQ3ODU3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPkZpbmQgdmlzaWJsZSBtZXNzYWdlczwvdGV4dD4KPHRleHQgeD0iNzYiIHk9Ijc5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+PHRzcGFuIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnZpc2libGUgbm93PC90c3Bhbj4gwrcgb2xkZXN0IGZpcnN0PC90ZXh0Pgo8bGluZSB4MT0iMjAwIiB5MT0iOTAiIHgyPSIyMDAiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI3JhKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIzMDAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlNraXAgbWVzc2FnZXMgaW4gdXNlPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMTUzIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dGFrZW4gYnkgYW5vdGhlciByZWNlaXZlcjwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9IjE2NCIgeDI9IjIwMCIgeTI9IjE4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjcmEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEycHgiPkhhbmQgb3V0IGluIHRoZSBzYW1lIHN0ZXA8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIyMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPm5ldyByZWNlaXB0IGhhbmRsZSDCtyBoaWRkZW48dHNwYW4geD0iNzYiIGR5PSIxMiI+cmVjZWl2ZSBjb3VudCArIDE8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iMzg4IiB5PSI0MiIgd2lkdGg9IjQyNCIgaGVpZ2h0PSIxOTYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjAwIiB5PSI2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+VFdPIENPTkNVUlJFTlQgUkVDRUlWRVJTPC90ZXh0Pgo8cmVjdCB4PSI0MDQiIHk9Ijc4IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjI0IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0NzkiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEEgZ2V0cyBtMTwvdGV4dD4KPHJlY3QgeD0iNDA0IiB5PSIxMDgiIHdpZHRoPSIxNTAiIGhlaWdodD0iMjQiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjQ3OSIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEIgZ2V0cyBtMjwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSI3OCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz48dGV4dCB4PSI2MTIiIHk9IjkzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5tMSAgaW4gZmxpZ2h0IChBKTwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxMDQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+PHRleHQgeD0iNjEyIiB5PSIxMTkiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPm0yICBpbiBmbGlnaHQgKEIpPC90ZXh0Pgo8cmVjdCB4PSI2MDAiIHk9IjEzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz48dGV4dCB4PSI2MTIiIHk9IjE0NSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzY0NzQ4YiI+bTMgIHZpc2libGUgwrcgbmV4dDwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxNTYiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+PHRleHQgeD0iNjEyIiB5PSIxNzEiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiM2NDc0OGIiPm00ICB2aXNpYmxlIMK3IG5leHQ8L3RleHQ+CjxsaW5lIHgxPSI1NTYiIHkxPSI5MCIgeDI9IjU5NiIgeTI9Ijg4IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8bGluZSB4MT0iNTU2IiB5MT0iMTIwIiB4Mj0iNTk2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSI0MDQiIHk9IjE5NiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzMCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjYwMCIgeT0iMjE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmVhY2ggcmVjZWl2ZXIgZ2V0cyBkaWZmZXJlbnQgbWVzc2FnZXM8L3RleHQ+Cjwvc3ZnPg==)

![A receive takes the oldest visible messages and, in the same step, gives each a new receipt handle, hides it for the visibility timeout and adds one to its receive count. Two receivers at the same time get different messages. A message can be delivered again once its visibility timeout passes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIHJlY2VpdmUgdGFrZXMgdGhlIG9sZGVzdCB2aXNpYmxlIG1lc3NhZ2VzIGFuZCwgaW4gdGhlIHNhbWUgc3RlcCwgZ2l2ZXMgZWFjaCBhIG5ldyByZWNlaXB0IGhhbmRsZSwgaGlkZXMgaXQgZm9yIHRoZSB2aXNpYmlsaXR5IHRpbWVvdXQgYW5kIGFkZHMgb25lIHRvIGl0cyByZWNlaXZlIGNvdW50LiBUd28gcmVjZWl2ZXJzIGF0IHRoZSBzYW1lIHRpbWUgZ2V0IGRpZmZlcmVudCBtZXNzYWdlcy4gQSBtZXNzYWdlIGNhbiBiZSBkZWxpdmVyZWQgYWdhaW4gb25jZSBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0IHBhc3Nlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0icmEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJyZyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNmVlN2I3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPkZpbmQgdmlzaWJsZSBtZXNzYWdlczwvdGV4dD4KPHRleHQgeD0iNzYiIHk9Ijc5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+PHRzcGFuIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnZpc2libGUgbm93PC90c3Bhbj4gwrcgb2xkZXN0IGZpcnN0PC90ZXh0Pgo8bGluZSB4MT0iMjAwIiB5MT0iOTAiIHgyPSIyMDAiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI3JhKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIzMDAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlNraXAgbWVzc2FnZXMgaW4gdXNlPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMTUzIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dGFrZW4gYnkgYW5vdGhlciByZWNlaXZlcjwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9IjE2NCIgeDI9IjIwMCIgeTI9IjE4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjcmEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEycHgiPkhhbmQgb3V0IGluIHRoZSBzYW1lIHN0ZXA8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIyMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPm5ldyByZWNlaXB0IGhhbmRsZSDCtyBoaWRkZW48dHNwYW4geD0iNzYiIGR5PSIxMiI+cmVjZWl2ZSBjb3VudCArIDE8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iMzg4IiB5PSI0MiIgd2lkdGg9IjQyNCIgaGVpZ2h0PSIxOTYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjAwIiB5PSI2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+VFdPIENPTkNVUlJFTlQgUkVDRUlWRVJTPC90ZXh0Pgo8cmVjdCB4PSI0MDQiIHk9Ijc4IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjI0IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0NzkiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEEgZ2V0cyBtMTwvdGV4dD4KPHJlY3QgeD0iNDA0IiB5PSIxMDgiIHdpZHRoPSIxNTAiIGhlaWdodD0iMjQiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjQ3OSIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEIgZ2V0cyBtMjwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSI3OCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz48dGV4dCB4PSI2MTIiIHk9IjkzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5tMSAgaW4gZmxpZ2h0IChBKTwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxMDQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+PHRleHQgeD0iNjEyIiB5PSIxMTkiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPm0yICBpbiBmbGlnaHQgKEIpPC90ZXh0Pgo8cmVjdCB4PSI2MDAiIHk9IjEzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz48dGV4dCB4PSI2MTIiIHk9IjE0NSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6Izk0YTNiOCI+bTMgIHZpc2libGUgwrcgbmV4dDwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxNTYiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+PHRleHQgeD0iNjEyIiB5PSIxNzEiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM5NGEzYjgiPm00ICB2aXNpYmxlIMK3IG5leHQ8L3RleHQ+CjxsaW5lIHgxPSI1NTYiIHkxPSI5MCIgeDI9IjU5NiIgeTI9Ijg4IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8bGluZSB4MT0iNTU2IiB5MT0iMTIwIiB4Mj0iNTk2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSI0MDQiIHk9IjE5NiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzMCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjYwMCIgeT0iMjE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmVhY2ggcmVjZWl2ZXIgZ2V0cyBkaWZmZXJlbnQgbWVzc2FnZXM8L3RleHQ+Cjwvc3ZnPg==)

Two receivers never get the same message at the same time. ApproximateReceiveCount is the actual receive count.

#### Receipt handles & visibility

Each receive saves a new receipt handle with the message. `DeleteMessage` and `ChangeMessageVisibility` find the message by that handle, including after an adapter restart or through another adapter instance.

A delete or visibility change whose handle matches no message returns `ReceiptHandleIsInvalid`. That includes a message already deleted, or received again under a newer handle. The visibility timeout defaults to 30 seconds. `ChangeMessageVisibility` can extend it with no lock-duration maximum, and zero makes the message available again immediately. Retention can delete a message while it is in flight.

![The receipt handle is saved with the message in PostgreSQL and survives adapter restart. Visibility uses a stored deadline within SQS bounds, without a broker lock ceiling.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgcmVjZWlwdCBoYW5kbGUgaXMgc2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMIGFuZCBzdXJ2aXZlcyBhZGFwdGVyIHJlc3RhcnQuIFZpc2liaWxpdHkgdXNlcyBhIHN0b3JlZCBkZWFkbGluZSB3aXRoaW4gU1FTIGJvdW5kcywgd2l0aG91dCBhIGJyb2tlciBsb2NrIGNlaWxpbmcuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InZhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIyNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzA0Nzg1NyI+UkVDRUlQVCBIQU5ETEVTIFNVUlZJVkUgUkVTVEFSVFM8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSIzOCIgd2lkdGg9IjM2MCIgaGVpZ2h0PSIxNDIiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMzI0IiBoZWlnaHQ9IjM0IiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMjA2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+cmVjZWlwdCBoYW5kbGUgPSAzZjJh4oCmLTkxYTI8L3RleHQ+Cjx0ZXh0IHg9IjIwNiIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+c2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMPC90ZXh0Pgo8bGluZSB4MT0iMjA2IiB5MT0iMTIwIiB4Mj0iMjA2IiB5Mj0iMTM2IiBzdHJva2Utd2lkdGg9IjEuNiIgc3Ryb2tlLWRhc2hhcnJheT0iMyAzIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iMjA2IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+YWRhcHRlciByZXN0YXJ0czwvdGV4dD4KPHRleHQgeD0iMjA2IiB5PSIxNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+RGVsZXRlTWVzc2FnZSBhbmQgQ2hhbmdlTWVzc2FnZVZpc2liaWxpdHkgc3RpbGwgd29yazwvdGV4dD4KPGxpbmUgeDE9IjM5OCIgeTE9IjM0IiB4Mj0iMzk4IiB5Mj0iMTg0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQyNCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPk5PIFZJU0lCSUxJVFkgQ0FQPC90ZXh0Pgo8cmVjdCB4PSI0MjQiIHk9IjM4IiB3aWR0aD0iMzg2IiBoZWlnaHQ9IjE0MiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8bGluZSB4MT0iNDQ2IiB5MT0iMTA0IiB4Mj0iODA2IiB5Mj0iMTA0IiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6I2NiZDVlMSIvPgo8cmVjdCB4PSI0NDYiIHk9Ijg4IiB3aWR0aD0iNzgiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNhN2YzZDA7c3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNTI4IiB5PSI4OCIgd2lkdGg9Ijc4IiBoZWlnaHQ9IjE4IiByeD0iNCIgc3Ryb2tlLXdpZHRoPSIxIiBzdHlsZT0iZmlsbDojYTdmM2QwO3N0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjYxMCIgeT0iODgiIHdpZHRoPSIxMjAiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNDc4NTc7c3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjczNCIgeTE9Ijk3IiB4Mj0iODAwIiB5Mj0iOTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCN2YSkiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0ODQiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+dGltZW91dDwvdGV4dD4KPHRleHQgeD0iNTY2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNjY4IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNzcyIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZWQgdGltZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5DaGFuZ2VNZXNzYWdlVmlzaWJpbGl0eSB1cGRhdGVzIHRoZSBkZWFkbGluZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxNTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2NDc0OGIiPihubyBtZXNzYWdlLWxvY2sgdGltZSBsaW1pdCk8L3RleHQ+Cjwvc3ZnPg==)

![The receipt handle is saved with the message in PostgreSQL and survives adapter restart. Visibility uses a stored deadline within SQS bounds, without a broker lock ceiling.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgcmVjZWlwdCBoYW5kbGUgaXMgc2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMIGFuZCBzdXJ2aXZlcyBhZGFwdGVyIHJlc3RhcnQuIFZpc2liaWxpdHkgdXNlcyBhIHN0b3JlZCBkZWFkbGluZSB3aXRoaW4gU1FTIGJvdW5kcywgd2l0aG91dCBhIGJyb2tlciBsb2NrIGNlaWxpbmcuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InZhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIyNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzZlZTdiNyI+UkVDRUlQVCBIQU5ETEVTIFNVUlZJVkUgUkVTVEFSVFM8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSIzOCIgd2lkdGg9IjM2MCIgaGVpZ2h0PSIxNDIiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMzI0IiBoZWlnaHQ9IjM0IiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjA2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+cmVjZWlwdCBoYW5kbGUgPSAzZjJh4oCmLTkxYTI8L3RleHQ+Cjx0ZXh0IHg9IjIwNiIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+c2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMPC90ZXh0Pgo8bGluZSB4MT0iMjA2IiB5MT0iMTIwIiB4Mj0iMjA2IiB5Mj0iMTM2IiBzdHJva2Utd2lkdGg9IjEuNiIgc3Ryb2tlLWRhc2hhcnJheT0iMyAzIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iMjA2IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+YWRhcHRlciByZXN0YXJ0czwvdGV4dD4KPHRleHQgeD0iMjA2IiB5PSIxNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+RGVsZXRlTWVzc2FnZSBhbmQgQ2hhbmdlTWVzc2FnZVZpc2liaWxpdHkgc3RpbGwgd29yazwvdGV4dD4KPGxpbmUgeDE9IjM5OCIgeTE9IjM0IiB4Mj0iMzk4IiB5Mj0iMTg0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQyNCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPk5PIFZJU0lCSUxJVFkgQ0FQPC90ZXh0Pgo8cmVjdCB4PSI0MjQiIHk9IjM4IiB3aWR0aD0iMzg2IiBoZWlnaHQ9IjE0MiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8bGluZSB4MT0iNDQ2IiB5MT0iMTA0IiB4Mj0iODA2IiB5Mj0iMTA0IiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6IzQ3NTU2OSIvPgo8cmVjdCB4PSI0NDYiIHk9Ijg4IiB3aWR0aD0iNzgiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNDc4NTc7c3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNTI4IiB5PSI4OCIgd2lkdGg9Ijc4IiBoZWlnaHQ9IjE4IiByeD0iNCIgc3Ryb2tlLXdpZHRoPSIxIiBzdHlsZT0iZmlsbDojMDQ3ODU3O3N0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjYxMCIgeT0iODgiIHdpZHRoPSIxMjAiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiM2ZWU3Yjc7c3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjczNCIgeTE9Ijk3IiB4Mj0iODAwIiB5Mj0iOTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCN2YSkiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI0ODQiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+dGltZW91dDwvdGV4dD4KPHRleHQgeD0iNTY2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNjY4IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNzcyIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZWQgdGltZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5DaGFuZ2VNZXNzYWdlVmlzaWJpbGl0eSB1cGRhdGVzIHRoZSBkZWFkbGluZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxNTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM5NGEzYjgiPihubyBtZXNzYWdlLWxvY2sgdGltZSBsaW1pdCk8L3RleHQ+Cjwvc3ZnPg==)

Receipt handles are saved with messages, so they still work after an adapter restart. Visibility has no lock-duration limit.

#### Dead-letter & retention

When source and DLQ belong to the same supported SQS-owned message database transaction, receive moves messages at `maxReceiveCount` atomically with claiming the rest. Both changes commit or neither does. Cross-database/store transfers are unsupported: sharing a provider, physical server or control log is not a shared message transaction, and no other service's tables are used. The DLQ retains ordinary queue operations and cleanup. A FIFO move creates a new message in the DLQ, with a new `MessageId`, a receive count of zero and a new send time.

A background task deletes messages sent longer ago than the queue's retention period, including messages in flight; receiving does not reset that time. The retention period defaults to four days and is kept between 60 seconds and 14 days, so a missing or too-short value cannot delete new messages straight away. One worker per database removes expired messages in batches, pauses during database maintenance, and continues if one queue fails. Limits on rows per pass and time per batch cap the load.

![Within the same supported SQS-owned message database transaction, receive moves exhausted messages to the DLQ and hands out the rest. Cross-database/store moves are unsupported. Background cleanup enforces retention; consumers still tolerate redelivery.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJXaXRoaW4gdGhlIHNhbWUgc3VwcG9ydGVkIFNRUy1vd25lZCBtZXNzYWdlIGRhdGFiYXNlIHRyYW5zYWN0aW9uLCByZWNlaXZlIG1vdmVzIGV4aGF1c3RlZCBtZXNzYWdlcyB0byB0aGUgRExRIGFuZCBoYW5kcyBvdXQgdGhlIHJlc3QuIENyb3NzLWRhdGFiYXNlL3N0b3JlIG1vdmVzIGFyZSB1bnN1cHBvcnRlZC4gQmFja2dyb3VuZCBjbGVhbnVwIGVuZm9yY2VzIHJldGVudGlvbjsgY29uc3VtZXJzIHN0aWxsIHRvbGVyYXRlIHJlZGVsaXZlcnkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImRhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2RjMjYyNiIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5ERUFELUxFVFRFUiBNT1ZFIElOIE9ORSBUUkFOU0FDVElPTjwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjEwMSIgeT0iNTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTFweCI+bWVzc2FnZXMgZHVlPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5vbmUgdHJhbnNhY3Rpb248L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI1MCIgeDI9IjIxMiIgeTI9IjUwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNkeCkiIHN0eWxlPSJzdHJva2U6I2RjMjYyNiIvPgo8dGV4dCB4PSIxOTQiIHk9IjQzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZmlsbDojZGMyNjI2Ij7iiaUgbWF4PC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNzQiIHgyPSIyMTIiIHkyPSI3NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZGEpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMTk0IiB5PSI5MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+Jmx0OyBtYXg8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iMzIiIHdpZHRoPSIyMjIiIGhlaWdodD0iMzIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2ZmZmJlYjtzdHJva2U6I2ZkZTY4YSIvPgo8dGV4dCB4PSIzMjUiIHk9IjUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTFweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2I0NTMwOSI+bW92ZSB0byBkZWFkLWxldHRlciBxdWV1ZTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI2NiIgd2lkdGg9IjIyMiIgaGVpZ2h0PSIzMCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjMyNSIgeT0iODUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+cmV0dXJuZWQgdG8gdGhlIHJlY2VpdmVyPC90ZXh0Pgo8cmVjdCB4PSI0NTIiIHk9IjMyIiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjY0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjYzMSIgeT0iNTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTFweCI+b25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI2MzEiIHk9Ijc5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPm1vdmUgYW5kIHJlY2VpdmUgc3VjY2VlZCB0b2dldGhlcjwvdGV4dD4KPHRleHQgeD0iMjYiIHk9IjEyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+UkVURU5USU9OIENMRUFOVVAgwrcgT04gU0VORCBUSU1FPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTM4IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+CjxyZWN0IHg9IjYwIiB5PSIxNjYiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNmZWYyZjI7c3Ryb2tlOiNkYzI2MjYiLz4KPHJlY3QgeD0iNDIwIiB5PSIxNjYiIHdpZHRoPSIzNTAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjQyMCIgeTE9IjE1NiIgeDI9IjQyMCIgeTI9IjE5OCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQgMyIgc3R5bGU9InN0cm9rZTojMzM0MTU1Ii8+Cjx0ZXh0IHg9IjQyMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMzM0MTU1Ij5ub3cg4oiSIHJldGVudGlvbjwvdGV4dD4KPHRleHQgeD0iMjQwIiB5PSIxODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiNkYzI2MjYiPnNlbmQgdGltZSBiZWZvcmUgY3V0b2ZmIOKGkiByZW1vdmVkPC90ZXh0Pgo8dGV4dCB4PSI1OTUiIHk9IjE4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+d2l0aGluIHJldGVudGlvbiDihpIga2VwdDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5yZXRlbnRpb24gNjBzLTE0ZCDCtyBiYXRjaGVkIGNsZWFudXAgwrcgb25lIHdvcmtlciBwZXIgZGF0YWJhc2UgwrcgYmFja3Mgb2ZmIGR1cmluZyBtYWludGVuYW5jZTwvdGV4dD4KPC9zdmc+)

![Within the same supported SQS-owned message database transaction, receive moves exhausted messages to the DLQ and hands out the rest. Cross-database/store moves are unsupported. Background cleanup enforces retention; consumers still tolerate redelivery.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJXaXRoaW4gdGhlIHNhbWUgc3VwcG9ydGVkIFNRUy1vd25lZCBtZXNzYWdlIGRhdGFiYXNlIHRyYW5zYWN0aW9uLCByZWNlaXZlIG1vdmVzIGV4aGF1c3RlZCBtZXNzYWdlcyB0byB0aGUgRExRIGFuZCBoYW5kcyBvdXQgdGhlIHJlc3QuIENyb3NzLWRhdGFiYXNlL3N0b3JlIG1vdmVzIGFyZSB1bnN1cHBvcnRlZC4gQmFja2dyb3VuZCBjbGVhbnVwIGVuZm9yY2VzIHJldGVudGlvbjsgY29uc3VtZXJzIHN0aWxsIHRvbGVyYXRlIHJlZGVsaXZlcnkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImRhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2Y4NzE3MSIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5ERUFELUxFVFRFUiBNT1ZFIElOIE9ORSBUUkFOU0FDVElPTjwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjEwMSIgeT0iNTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTFweCI+bWVzc2FnZXMgZHVlPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5vbmUgdHJhbnNhY3Rpb248L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI1MCIgeDI9IjIxMiIgeTI9IjUwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNkeCkiIHN0eWxlPSJzdHJva2U6I2Y4NzE3MSIvPgo8dGV4dCB4PSIxOTQiIHk9IjQzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZmlsbDojZjg3MTcxIj7iiaUgbWF4PC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNzQiIHgyPSIyMTIiIHkyPSI3NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZGEpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMTk0IiB5PSI5MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+Jmx0OyBtYXg8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iMzIiIHdpZHRoPSIyMjIiIGhlaWdodD0iMzIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzQyMjAwNjtzdHJva2U6IzkyNDAwZSIvPgo8dGV4dCB4PSIzMjUiIHk9IjUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTFweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2ZiYmYyNCI+bW92ZSB0byBkZWFkLWxldHRlciBxdWV1ZTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI2NiIgd2lkdGg9IjIyMiIgaGVpZ2h0PSIzMCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjMyNSIgeT0iODUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+cmV0dXJuZWQgdG8gdGhlIHJlY2VpdmVyPC90ZXh0Pgo8cmVjdCB4PSI0NTIiIHk9IjMyIiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjY0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjYzMSIgeT0iNTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTFweCI+b25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI2MzEiIHk9Ijc5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPm1vdmUgYW5kIHJlY2VpdmUgc3VjY2VlZCB0b2dldGhlcjwvdGV4dD4KPHRleHQgeD0iMjYiIHk9IjEyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+UkVURU5USU9OIENMRUFOVVAgwrcgT04gU0VORCBUSU1FPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTM4IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+CjxyZWN0IHg9IjYwIiB5PSIxNjYiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiM0NTBhMGE7c3Ryb2tlOiNmODcxNzEiLz4KPHJlY3QgeD0iNDIwIiB5PSIxNjYiIHdpZHRoPSIzNTAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjQyMCIgeTE9IjE1NiIgeDI9IjQyMCIgeTI9IjE5OCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQgMyIgc3R5bGU9InN0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQyMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZmlsbDojY2JkNWUxIj5ub3cg4oiSIHJldGVudGlvbjwvdGV4dD4KPHRleHQgeD0iMjQwIiB5PSIxODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNmODcxNzEiPnNlbmQgdGltZSBiZWZvcmUgY3V0b2ZmIOKGkiByZW1vdmVkPC90ZXh0Pgo8dGV4dCB4PSI1OTUiIHk9IjE4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+d2l0aGluIHJldGVudGlvbiDihpIga2VwdDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5yZXRlbnRpb24gNjBzLTE0ZCDCtyBiYXRjaGVkIGNsZWFudXAgwrcgb25lIHdvcmtlciBwZXIgZGF0YWJhc2UgwrcgYmFja3Mgb2ZmIGR1cmluZyBtYWludGVuYW5jZTwvdGV4dD4KPC9zdmc+)

Atomic DLQ moves require the same supported SQS-owned database transaction. Cross-store moves are unsupported. Retention cleanup removes aged messages.

#### FIFO ordering & dedup

A FIFO queue stores each message's `MessageGroupId` and orders delivery within each group. A receive returns only the oldest message of each group that has nothing in flight (no message in that group is currently received and still hidden). Because arrival positions only increase, that is always the group's next message, and exactly one message is in flight per group at a time. Groups are independent, so different receivers can process different groups at once, coordinated only by PostgreSQL. When a message's visibility timeout passes, it is first in its group again, so a redelivery stays in sequence.

Each FIFO send requires `MessageGroupId` and returns a `SequenceNumber`: the message's arrival position as a 20-digit, zero-padded number.

Deduplication markers live in a separate PostgreSQL table keyed by queue and deduplication ID. An explicit `MessageDeduplicationId` takes precedence; otherwise, on a queue with content-based deduplication, the key is the SHA-256 of the body, excluding attributes. The message insert and deduplication marker are part of one transaction. A duplicate within 5 minutes saves no new message and returns the original `MessageId` and `SequenceNumber`. Marker retention is independent of message retention, so receiving or deleting the original does not shorten the deduplication window.

While a message is in flight, no other message from its group is delivered until it is deleted or its visibility timeout passes. That does not stop a timed-out worker from finishing a message it already received, so consumers must make repeated processing safe.

![FIFO receives deliver the next message of each group that has nothing in flight. Each send returns a 20-digit, zero-padded sequence number. Explicit or content-based deduplication is recorded in a separate PostgreSQL table with a five-minute window; a repeated send returns the original message ID and sequence number.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJGSUZPIHJlY2VpdmVzIGRlbGl2ZXIgdGhlIG5leHQgbWVzc2FnZSBvZiBlYWNoIGdyb3VwIHRoYXQgaGFzIG5vdGhpbmcgaW4gZmxpZ2h0LiBFYWNoIHNlbmQgcmV0dXJucyBhIDIwLWRpZ2l0LCB6ZXJvLXBhZGRlZCBzZXF1ZW5jZSBudW1iZXIuIEV4cGxpY2l0IG9yIGNvbnRlbnQtYmFzZWQgZGVkdXBsaWNhdGlvbiBpcyByZWNvcmRlZCBpbiBhIHNlcGFyYXRlIFBvc3RncmVTUUwgdGFibGUgd2l0aCBhIGZpdmUtbWludXRlIHdpbmRvdzsgYSByZXBlYXRlZCBzZW5kIHJldHVybnMgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgSUQgYW5kIHNlcXVlbmNlIG51bWJlci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZnMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PUkRFUiBXSVRISU4gQSBHUk9VUDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQwIiB5PSI1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+bWVzc2FnZXMgb3JkZXJlZCB3aXRoaW4gZWFjaCBncm91cDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjcxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMzM0MTU1Ij5lYWNoIGdyb3VwJ3Mgb2xkZXN0IG1lc3NhZ2UsIGlmIG5vdGhpbmcgaW4gZmxpZ2h0ICDihpIgIGRlbGl2ZXJlZDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9Ijg3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U2VxdWVuY2VOdW1iZXI6IDIwIGRpZ2l0cywgemVyby1wYWRkZWQsIGFsd2F5cyBpbmNyZWFzaW5nPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQwIiB5PSIxMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgb3JkZXJzPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMDQ3ODU3Ij5tNDEgKGhlYWQsIGluIGZsaWdodCkgwrcgbTQyIMK3IG00MyDigKY8L3RleHQ+Cjx0ZXh0IHg9IjQwIiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vbmUgaW4gZmxpZ2h0IMK3IG00MiB3YWl0cyB1bnRpbCBtNDEgaXMgZGVsZXRlZCBvciB0aW1lcyBvdXQ8L3RleHQ+CjxyZWN0IHg9IjQzMCIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTIzIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmdyb3VwIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMDQ3ODU3Ij5tNTggKGhlYWQsIGluIGZsaWdodCkgwrcgbTU5IOKApjwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5ncm91cHMgYXJlIGNvbmN1cnJlbnQgwrcgYSBkaWZmZXJlbnQgcmVjZWl2ZXIgZHJhaW5zIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjI2IiB5PSIxOTAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNiNDUzMDkiPkRFRFVQTElDQVRJT04gwrcgNS1NSU5VVEUgV0lORE9XPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTk2IiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTUxIiB5PSIyMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPmV4cGxpY2l0IElEIG9yIFNIQS0yNTYoYm9keSk8L3RleHQ+CjxsaW5lIHgxPSIyNzYiIHkxPSIyMTYiIHgyPSIzMTIiIHkyPSIyMTYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZzKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjMxNCIgeT0iMTk2IiB3aWR0aD0iNDk2IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZiZWI7c3Ryb2tlOiNmZGU2OGEiLz4KPHRleHQgeD0iNTYyIiB5PSIyMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojYjQ1MzA5Ij5yZXBlYXQgcmV0dXJucyBvcmlnaW5hbCBJRHM8L3RleHQ+Cjx0ZXh0IHg9IjU2MiIgeT0iMjI5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojYjQ1MzA5Ij5tZXNzYWdlIGFuZCBkZWR1cCBtYXJrZXIgc2F2ZWQgdG9nZXRoZXI8L3RleHQ+Cjwvc3ZnPg==)

![FIFO receives deliver the next message of each group that has nothing in flight. Each send returns a 20-digit, zero-padded sequence number. Explicit or content-based deduplication is recorded in a separate PostgreSQL table with a five-minute window; a repeated send returns the original message ID and sequence number.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJGSUZPIHJlY2VpdmVzIGRlbGl2ZXIgdGhlIG5leHQgbWVzc2FnZSBvZiBlYWNoIGdyb3VwIHRoYXQgaGFzIG5vdGhpbmcgaW4gZmxpZ2h0LiBFYWNoIHNlbmQgcmV0dXJucyBhIDIwLWRpZ2l0LCB6ZXJvLXBhZGRlZCBzZXF1ZW5jZSBudW1iZXIuIEV4cGxpY2l0IG9yIGNvbnRlbnQtYmFzZWQgZGVkdXBsaWNhdGlvbiBpcyByZWNvcmRlZCBpbiBhIHNlcGFyYXRlIFBvc3RncmVTUUwgdGFibGUgd2l0aCBhIGZpdmUtbWludXRlIHdpbmRvdzsgYSByZXBlYXRlZCBzZW5kIHJldHVybnMgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgSUQgYW5kIHNlcXVlbmNlIG51bWJlci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZnMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PUkRFUiBXSVRISU4gQSBHUk9VUDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQwIiB5PSI1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+bWVzc2FnZXMgb3JkZXJlZCB3aXRoaW4gZWFjaCBncm91cDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjcxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojY2JkNWUxIj5lYWNoIGdyb3VwJ3Mgb2xkZXN0IG1lc3NhZ2UsIGlmIG5vdGhpbmcgaW4gZmxpZ2h0ICDihpIgIGRlbGl2ZXJlZDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9Ijg3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U2VxdWVuY2VOdW1iZXI6IDIwIGRpZ2l0cywgemVyby1wYWRkZWQsIGFsd2F5cyBpbmNyZWFzaW5nPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjQwIiB5PSIxMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgb3JkZXJzPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNmVlN2I3Ij5tNDEgKGhlYWQsIGluIGZsaWdodCkgwrcgbTQyIMK3IG00MyDigKY8L3RleHQ+Cjx0ZXh0IHg9IjQwIiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vbmUgaW4gZmxpZ2h0IMK3IG00MiB3YWl0cyB1bnRpbCBtNDEgaXMgZGVsZXRlZCBvciB0aW1lcyBvdXQ8L3RleHQ+CjxyZWN0IHg9IjQzMCIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTIzIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmdyb3VwIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNmVlN2I3Ij5tNTggKGhlYWQsIGluIGZsaWdodCkgwrcgbTU5IOKApjwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5ncm91cHMgYXJlIGNvbmN1cnJlbnQgwrcgYSBkaWZmZXJlbnQgcmVjZWl2ZXIgZHJhaW5zIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjI2IiB5PSIxOTAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiNmYmJmMjQiPkRFRFVQTElDQVRJT04gwrcgNS1NSU5VVEUgV0lORE9XPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTk2IiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTUxIiB5PSIyMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPmV4cGxpY2l0IElEIG9yIFNIQS0yNTYoYm9keSk8L3RleHQ+CjxsaW5lIHgxPSIyNzYiIHkxPSIyMTYiIHgyPSIzMTIiIHkyPSIyMTYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZzKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjMxNCIgeT0iMTk2IiB3aWR0aD0iNDk2IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiM0MjIwMDY7c3Ryb2tlOiM5MjQwMGUiLz4KPHRleHQgeD0iNTYyIiB5PSIyMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojZmJiZjI0Ij5yZXBlYXQgcmV0dXJucyBvcmlnaW5hbCBJRHM8L3RleHQ+Cjx0ZXh0IHg9IjU2MiIgeT0iMjI5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojZmJiZjI0Ij5tZXNzYWdlIGFuZCBkZWR1cCBtYXJrZXIgc2F2ZWQgdG9nZXRoZXI8L3RleHQ+Cjwvc3ZnPg==)

FIFO receives deliver one message per group at a time. Sends return a SequenceNumber, and repeated sends within 5 minutes are suppressed, matched by an explicit ID or, with content-based deduplication, a body hash.

#### Limitations

Where SQS and the PostgreSQL adapter differ

* **Throughput behaves differently: one PostgreSQL server serves every queue.** All of a Cloud Adapter deployment's queues share one server, so its capacity bounds peak throughput and a heavy queue can affect the others. In Tensor9's round-trip test of a moderate-rate Standard queue, the adapter matched SQS throughput (about 300 vs 286 ops/s) with a lower p99 (140 ms vs 172 ms) but a slower median (p50 24 ms vs 15 ms). That is not a measured ceiling, and it does not cover FIFO queues or every host.
* **Recovery follows the database placement.** CloudNativePG keeps queue data on the Cloud Adapter deployment cluster's volumes. Rebuilding the cluster requires explicit data recovery or a drained cutover.
* **Messages are limited to 256 KiB by default.** The adapter's default limit is 262144 bytes, while native SQS now accepts up to 1 MiB. Sends are checked against the queue's declared limit.
* **FIFO send deduplication lasts 5 minutes.** A duplicate send within that window returns the original IDs. Reusing an ID after the window can create a new message. Consumer redelivery remains possible even within the window.
* **Stale receipt handles behave differently: they return an error.** `DeleteMessage` and `ChangeMessageVisibility` return `ReceiptHandleIsInvalid` when no message matches the handle.
* **Retention behaves differently: expired messages are removed periodically.** An expired message can remain until the next cleanup pass. Retention is kept between 60 seconds and 14 days; a too-short value is raised to 60 seconds so that new messages are not deleted.
* **Counts observe queue state, not application completion.** Requested message counts read the message database: eligible messages are visible, future-visible messages with a receipt are in flight, and future-visible messages without a receipt are initially delayed. These categories share one query snapshot and can change immediately afterward. Metadata-only reads do not require a message-table count. An unavailable requested count returns an explicit unsupported result rather than zero. Purge, expiry and dead-letter movement can reduce depth without completing the application's work.
* **Queue creation behaves differently: queues are created when the stack is deployed.** Tensor9 creates the database and each queue's table, and its dead-letter table, at deploy time. `CreateQueue`, `DeleteQueue` and `SetQueueAttributes` act on those tables. Switching a queue between Standard and FIFO is rejected, because it would replace the queue.

#### Other considerations

* **Moving from AWS.** The database and queue tables start empty, and existing SQS messages are not migrated. Drain each group before switching it, to preserve order.
* **Removing queues.** Each queue is created in one step, so a crash never leaves a half-created queue. When a queue is removed from the stack, Tensor9 deletes only queues it created; any other queue is detached and left in place. A queue that still holds messages is not deleted unless deletion is forced.
* **Who operates what.** On the managed hosts, the provider operates the database's durability, backups and high availability, and Tensor9 operates the adapter. On CloudNativePG, Tensor9 operates the database inside your cluster.

#### 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.** FIFO request-processing service levels have not been qualified for this mapping. Standard-queue measurements do not establish FIFO latency, throughput or availability. Cost estimates describe the selected service resources; operation coverage remains separate.

##### SQS FIFO · SQS request billing units

Feature: SQS FIFO.

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

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/2036a1f06226eb37931bb17817a26968fa5905bccb912a41ffaddd1fdbe107e7-light.svg)

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/a68e1eb256c0c009a0132052e78d3708566cde63f564b31b494e069b9138cb56-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.

| SQS request billing units (per second) | SQS (Simple Queue Service, FIFO queues) | 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.31 | PostgreSQL (one copy) | 80.90 | 79.58 |
| 1 | 1.31 | PostgreSQL (two copies) | 161.79 | 160.48 |
| 10 | 13.14 | PostgreSQL (one copy) | 80.90 | 67.76 |
| 10 | 13.14 | PostgreSQL (two copies) | 161.79 | 148.65 |
| 100 | 131.40 | PostgreSQL (one copy) | 80.90 | -50.50 |
| 100 | 131.40 | PostgreSQL (two copies) | 161.79 | 30.39 |
| 1,000 | 1,314.00 | PostgreSQL (one copy) | 293.58 | -1,020.42 |
| 1,000 | 1,314.00 | PostgreSQL (two copies) | 587.17 | -726.83 |
| 10,000 | 13,140.00 | PostgreSQL (one copy) | 2,278.68 | -10,861.32 |
| 10,000 | 13,140.00 | PostgreSQL (two copies) | 4,557.35 | -8,582.65 |

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

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| PostgreSQL (one copy) | Origin list price · SQS billing units | 0.0000005 | USD/64-KiB request units |
| PostgreSQL (one copy) | Representative message size | 1,024 | bytes |
| PostgreSQL (one copy) | Origin send batch fill | 1 | messages/request |
| PostgreSQL (one copy) | Origin receive batch fill | 1 | messages/request |
| PostgreSQL (one copy) | Origin delete batch fill | 1 | messages/request |
| PostgreSQL (one copy) | Deliveries per message | 1 | attempts |
| PostgreSQL (one copy) | Empty receive calls per message | 0 | requests |
| PostgreSQL (one copy) | Queue residence window | 60 | seconds |
| PostgreSQL (one copy) | Ordering and dedup work multiplier | 2 | multiplier |
| 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 · SQS billing units | 0.0000005 | USD/64-KiB request units |
| PostgreSQL (two copies) | Representative message size | 1,024 | bytes |
| PostgreSQL (two copies) | Origin send batch fill | 1 | messages/request |
| PostgreSQL (two copies) | Origin receive batch fill | 1 | messages/request |
| PostgreSQL (two copies) | Origin delete batch fill | 1 | messages/request |
| PostgreSQL (two copies) | Deliveries per message | 1 | attempts |
| PostgreSQL (two copies) | Empty receive calls per message | 0 | requests |
| PostgreSQL (two copies) | Queue residence window | 60 | seconds |
| PostgreSQL (two copies) | Ordering and dedup work multiplier | 2 | multiplier |
| 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 |

* 1-KiB messages, unbatched send/receive/delete; actual batch and delivery assumptions stay visible. 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.
* Native/deployment comparison scope: FIFO request-processing service levels have not been qualified for this mapping. Standard-queue measurements do not establish FIFO latency, throughput or availability.
* 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.
* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.
* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.
* 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, AWSQueueService offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json)
* 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-2205b0bb4fecd035329ea8f524e1a885b9bdcdab` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AWSQueueService offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json), [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).

**SQS FIFO → 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: SQS billing units | 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 · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Representative message size | 1,024 | bytes |
| Origin send batch fill | 1 | messages/request |
| Origin receive batch fill | 1 | messages/request |
| Origin delete batch fill | 1 | messages/request |
| Deliveries per message | 1 | attempts |
| Empty receive calls per message | 0 | requests |
| Queue residence window | 60 | seconds |
| Ordering and dedup work multiplier | 2 | multiplier |
| 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 |
| SQS billing units | 0 | 64-KiB request units |

* 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: FIFO request-processing service levels have not been qualified for this mapping. Standard-queue measurements do not establish FIFO latency, throughput or availability.

* 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.

* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.

* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.

* 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-2205b0bb4fecd035329ea8f524e1a885b9bdcdab` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AWSQueueService offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json), [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 Service Bus

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Dead-letter redrive | Dead-letter | Supported | Most usage | Service Bus moves a message at the delivery-count limit to the declared session-enabled DLQ, then allows the next message in its group to proceed |
| Content-based deduplication | FIFO | Supported | Most usage | broker-native duplicate detection over a content-hash message id, 5-minute window (the SQS constant), honored at apply-time when your queue declares content-based deduplication |
| Dedup echo (suppressed-send response) | FIFO | Partial | Most usage | a dedup-suppressed send returns a fresh MessageId rather than echoing the original's MessageId/SequenceNumber as SQS does, so do not correlate on it |
| FIFO ordering | FIFO | Supported | Common | sessions are broker-exclusive per group, so ordering holds across horizontally scaled consumers with session ownership stored in Service Bus |
| MessageDeduplicationId | FIFO | Supported | Most usage | the explicit tag takes precedence over the content hash (AWS's own rule) |
| ReceiveRequestAttemptId | FIFO | Out of scope | Most usage | native sessions and duplicate detection do not provide durable SQS receive-attempt replay; explicit attempt IDs are unsupported |
| SequenceNumber (send response) | FIFO | Out of scope | Most usage | Service Bus cannot return the broker sequence synchronously, so the send response omits it; the receive-side sequence number is real (queue-monotonic, which contains per-group monotonic) |
| DeleteQueue / ListQueues / SetQueueAttributes / tags | Queues | Partial | Full surface | Cloud Adapter manages logical queues, tags and supported edits; session-enabled entities remain provisioned through Terraform. Broker-owned policy changes are rejected |
| GetQueueAttributes (live message counts) | Queues | Out of scope | Full surface | AMQP provides no authoritative live counts; unavailable requested counts return an explicit unsupported result; declared configuration is catalog state |
| PurgeQueue | Queues | Supported | Most usage | a bounded accept/drain/dispose session loop (the same documented raciness window as SQS's own purge) |
| DelaySeconds (per message) | Send / receive | Out of scope | Common | rejected exactly as real SQS rejects per-message delay on a FIFO queue (a scheduled enqueue would break in-group order) |
| DeleteMessage | Send / receive | Supported | Common | completes the group head within its held session |
| ReceiveMessage | Send / receive | Supported | Common | session receivers: strict per-MessageGroupId order, one message in flight per group; receives are bounded by your MaxNumberOfMessages budget (extra messages are not received and discarded) |
| SendMessage | Send / receive | Supported | Common | MessageGroupId required (the AWS FIFO rule) and used as the session id |
| SendMessageBatch | Send / receive | Supported | Common | runs as sequential individual sends to preserve entry order and return a result for each entry |
| ChangeMessageVisibility | Visibility | Partial | Common | extend = session-lock renewal, zero = in-session immediate redelivery (order preserved); the visibility timeout is capped at 5 minutes, longer is rejected with an error |

#### Persistent queue management and total cost

Cloud Adapter retains a persistent PostgreSQL store for the queue catalog, tenancy and lifecycle/control state, normally shared with the Cloud Adapter deployment. Native broker or Cosmos message storage does not remove this resource. Include its allocated compute, storage, backups and selected HA costs alongside adapter and message-backend charges; an idle or serverless message backend does not imply a zero total installation floor. Backend-only curves omit these shared allocations unless their assumptions explicitly include them.

This control store is distinct from the SQS-owned message database. PostgreSQL-authority FIFO composites add recoverable message bodies, receipts, deduplication and outbox state to an explicitly configured SQS message database; they do not store messages in the shared control catalog. A separate logical database and login provide data/permission separation, but still share server CPU, storage, IOPS, WAL and connection limits when hosted on the same instance. Dedicated physical server/instance capacity is a separate allocation and cost decision.

#### Service Bus capacity and queue lifetime

Standard and Premium use the same AMQP mapping described below, with different resource isolation, configured message limits and charges. Standard shares namespace capacity; Premium reserves approved messaging units. A messaging unit is not a fixed messages-per-second guarantee. Check actual SKU, entity limits, sessions, duplicate-detection window and credential permissions before binding a queue. A larger native entity does not automatically raise the adapter's declared message limit.

Native receipts belong to broker receiver links. The configured five-minute visibility ceiling and restart limitation remain applicable in this native design. Losing a link or failing to observe settlement leaves an uncertain result; the adapter cannot turn lock loss into a successful delete. A consumer must tolerate redelivery and make external effects idempotent.

Cloud Adapter manages logical queues against a predeclared inventory of fresh, exclusively owned native entities. A deleted name recreated later receives a different entity; old work can reach only the retired one. Allocation history is retained, and exhausted inventory refuses a create before messaging effects. This finite inventory constrains cumulative queue churn, including uncertain/failed births, rather than just peak active queues. Provisioning more inventory is an explicit customer resource action. Declared settings and tags are catalog state; live counts need separate management authority and are not fabricated from AMQP traffic.

#### FIFO with PostgreSQL authority and broker wakeups

Native sessions provide group-ordered broker delivery, but do not create unlimited group concurrency or full SQS FIFO semantics. Receiver slots are bounded; unsettled heads occupy them, and a hot session can delay others. Broker duplicate detection suppresses duplicate transport sends; it does not preserve the original SQS MessageId/SequenceNumber response or durable ReceiveRequestAttemptId result. Native FIFO does not support ReceiveRequestAttemptId replay; that parameter requires a durable attempt authority and is explicitly unsupported. The native profile below keeps these differences visible.

The coordinated alternative adds a dedicated customer Azure PostgreSQL database. It stores full recoverable bodies, per-group sequence, five-minute dedup response, receipt attempts, visibility and pending notifications in one transaction. Service Bus carries small versioned wakeups, not the authoritative message body. Send succeeds after the database commit; duplicate sends return the original durable result. A publisher retries wakeups with stable identity, and bounded database scans recover lost notifications.

Receive claims only the oldest eligible authority messages. Delete and visibility changes compare the exact queue incarnation, purge generation and claim token. Restarting an AMQP link or releasing a notification session does not release a customer's SQL claim. Late or duplicate wakeups cannot insert messages. This avoids pretending that a broker acknowledgement and a database commit are one atomic operation.

The ordered-batch design conservatively blocks new group work until all unsettled members have expired or settled. Modified receive-attempt replays are explicitly unsupported; valid unchanged five-minute attempts replay the original set. This restriction remains distinct from the direct SQL engine's one-in-flight-per-group mechanism. Neither version claims unlimited within-group parallelism. Cross-store dead-letter moves are unsupported.

Standard/Premium affect notification costs and capacity, while PostgreSQL determines payload capacity, receipts and user visibility. Count both databases and broker operations, retained dedup/attempt state, outbox retries, repair scans and cleanup. Direct PostgreSQL is the simpler comparison when no broker integration justifies the extra resource. No native broker lock or message-size limit should be reused as the authority's capacity estimate.

#### How it works

Your application keeps its SQS SDK and uses the authenticated Cloud Adapter endpoint configured for the install. The adapter translates `SendMessage` and `ReceiveMessage` to Azure Service Bus and returns SQS responses, error codes and MD5 checksums. Native sessions govern broker ownership; they do not grant Azure provisioning authority.

For a `.fifo` queue, Tensor9 provisions a Service Bus queue with sessions enabled. The adapter uses the `MessageGroupId` as the session ID, and the `.fifo` suffix tells it to receive by session. Service Bus gives each session to one consumer at a time, and the adapter delivers one message per group at a time, so send order holds across many consumer instances.

![Before: on AWS the application's SQS SDK calls Amazon SQS FIFO. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS FIFO API with Azure Service Bus sessions.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMgRklGTy4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIHNhbWUgYXBwbGljYXRpb24gYW5kIFNESyBjYWxsIGEgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBpbXBsZW1lbnRzIHRoZSBTUVMgRklGTyBBUEkgd2l0aCBBenVyZSBTZXJ2aWNlIEJ1cyBzZXNzaW9ucy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyODgiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMS41cHgiPkFtYXpvbiBTUVM8L3RleHQ+Cjx0ZXh0IHg9IjI4OCIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+RklGTyDCtyBBV1MtbWFuYWdlZDwvdGV4dD4KPGxpbmUgeDE9IjQxOCIgeTE9IjQwIiB4Mj0iNDE4IiB5Mj0iMTYwIiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojY2JkNWUxIi8+CjxyZWN0IHg9IjQ2MiIgeT0iNDYiIHdpZHRoPSIzNjIiIGhlaWdodD0iMTE4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNDc2IiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzA0Nzg1NyI+T04gVEhFIFRBUkdFVCBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iNDc0IiB5PSI4MCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjUyMCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI1MjAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5zYW1lIFNESzwvdGV4dD4KPGxpbmUgeDE9IjU2NiIgeTE9IjExMyIgeDI9IjU5MCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSI1OTQiIHk9Ijc2IiB3aWR0aD0iMTEwIiBoZWlnaHQ9Ijc0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS43IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjY0OSIgeT0iMTAyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEycHgiPlRlbnNvcjk8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTE3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5zZXJ2aWNlPC90ZXh0Pgo8dGV4dCB4PSI2NDkiIHk9IjEzMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+YWRhcHRlcjwvdGV4dD4KPGxpbmUgeDE9IjcwNCIgeTE9IjExMyIgeDI9IjcyOCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSI3MzIiIHk9IjgwIiB3aWR0aD0iODQiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzc0IiB5PSIxMDciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTBweCI+U2VydmljZSBCdXM8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+c2Vzc2lvbnM8L3RleHQ+Cjwvc3ZnPg==)

![Before: on AWS the application's SQS SDK calls Amazon SQS FIFO. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS FIFO API with Azure Service Bus sessions.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMgRklGTy4gQWZ0ZXI6IGluIHRoZSB0YXJnZXQgY2xvdWQgdGhlIHNhbWUgYXBwbGljYXRpb24gYW5kIFNESyBjYWxsIGEgVGVuc29yOSBhZGFwdGVyLCB3aGljaCBpbXBsZW1lbnRzIHRoZSBTUVMgRklGTyBBUEkgd2l0aCBBenVyZSBTZXJ2aWNlIEJ1cyBzZXNzaW9ucy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyODgiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMS41cHgiPkFtYXpvbiBTUVM8L3RleHQ+Cjx0ZXh0IHg9IjI4OCIgeT0iMTI2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+RklGTyDCtyBBV1MtbWFuYWdlZDwvdGV4dD4KPGxpbmUgeDE9IjQxOCIgeTE9IjQwIiB4Mj0iNDE4IiB5Mj0iMTYwIiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojNDc1NTY5Ii8+CjxyZWN0IHg9IjQ2MiIgeT0iNDYiIHdpZHRoPSIzNjIiIGhlaWdodD0iMTE4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNDc2IiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzZlZTdiNyI+T04gVEhFIFRBUkdFVCBDTE9VRDwvdGV4dD4KPHJlY3QgeD0iNDc0IiB5PSI4MCIgd2lkdGg9IjkyIiBoZWlnaHQ9IjY2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjUyMCIgeT0iMTEwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI1MjAiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5zYW1lIFNESzwvdGV4dD4KPGxpbmUgeDE9IjU2NiIgeTE9IjExMyIgeDI9IjU5MCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSI1OTQiIHk9Ijc2IiB3aWR0aD0iMTEwIiBoZWlnaHQ9Ijc0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS43IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjY0OSIgeT0iMTAyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEycHgiPlRlbnNvcjk8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTE3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5zZXJ2aWNlPC90ZXh0Pgo8dGV4dCB4PSI2NDkiIHk9IjEzMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+YWRhcHRlcjwvdGV4dD4KPGxpbmUgeDE9IjcwNCIgeTE9IjExMyIgeDI9IjcyOCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSI3MzIiIHk9IjgwIiB3aWR0aD0iODQiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzc0IiB5PSIxMDciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTBweCI+U2VydmljZSBCdXM8L3RleHQ+Cjx0ZXh0IHg9Ijc3NCIgeT0iMTI1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+c2Vzc2lvbnM8L3RleHQ+Cjwvc3ZnPg==)

The application keeps its SQS SDK. A Tensor9 adapter translates FIFO queue calls to Service Bus sessions.

#### Architecture

The adapter talks to Service Bus Standard over AMQP 1.0. On send, it sets the session ID from `MessageGroupId`. On receive, it delivers one message per group, renews the session lock while the visibility timeout runs, and completes or releases messages so their delivery counts stay correct. It signs in with your AKS Workload Identity, with no static secret.

Session receives run separately from sending and from standard-queue receives, so a FIFO receive never blocks them.

Tensor9 creates the queue when the stack is deployed, before the first message arrives, with sessions enabled, duplicate detection over a 5-minute window, a 5-minute session lock (ten times the adapter's lock-renewal interval), dead-lettering of expired messages, and automatic forwarding to your dead-letter queue. Microsoft operates Service Bus's durability, backups and high availability; Tensor9 operates the adapter.

![The SQS SDK calls the authenticated Cloud Adapter endpoint. The adapter maps MessageGroupId to a native Service Bus session, allowing one message in flight per group and bounded active receiver slots.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgU1FTIFNESyBjYWxscyB0aGUgYXV0aGVudGljYXRlZCBDbG91ZCBBZGFwdGVyIGVuZHBvaW50LiBUaGUgYWRhcHRlciBtYXBzIE1lc3NhZ2VHcm91cElkIHRvIGEgbmF0aXZlIFNlcnZpY2UgQnVzIHNlc3Npb24sIGFsbG93aW5nIG9uZSBtZXNzYWdlIGluIGZsaWdodCBwZXIgZ3JvdXAgYW5kIGJvdW5kZWQgYWN0aXZlIHJlY2VpdmVyIHNsb3RzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iYXIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjgiIHk9IjM0IiB3aWR0aD0iODIwIiBoZWlnaHQ9IjIwOCIgcng9IjE2IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjI2IiB5PSI1NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjgiPkNVU1RPTUVSJ1MgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjI0IiB5PSIxMDgiIHdpZHRoPSIxMTIiIGhlaWdodD0iOTIiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iODAiIHk9IjE0NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxM3B4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iODAiIHk9IjE2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjgwIiB5PSIxODEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTM2IiB5MT0iMTU0IiB4Mj0iMTg0IiB5Mj0iMTU0IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYXIpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iMTYwIiB5PSIxNDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5TUVMgQVBJPC90ZXh0Pgo8cmVjdCB4PSIxODgiIHk9IjcyIiB3aWR0aD0iMjI0IiBoZWlnaHQ9IjE1MiIgcng9IjEzIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzMDAiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEzcHgiPlRlbnNvcjkgYWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMzAwIiB5PSIxMDgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmltcGxlbWVudHMgU1FTIEZJRk88L3RleHQ+CjxyZWN0IHg9IjIwMiIgeT0iMTIwIiB3aWR0aD0iMTk2IiBoZWlnaHQ9IjQyIiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMzAwIiB5PSIxMzciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnNlbmRzICsgc3RhbmRhcmQgcmVjZWl2ZXM8L3RleHQ+Cjx0ZXh0IHg9IjMwMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+aW5kZXBlbmRlbnQgb2YgRklGTyByZWNlaXZlczwvdGV4dD4KPHJlY3QgeD0iMjAyIiB5PSIxNzAiIHdpZHRoPSIxOTYiIGhlaWdodD0iNDQiIHJ4PSI4IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSIzMDAiIHk9IjE4NyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+RklGTyBzZXNzaW9uIHJlY2VpdmVzPC90ZXh0Pgo8dGV4dCB4PSIzMDAiIHk9IjIwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnN0cmljdCBwZXItZ3JvdXAgb3JkZXI8L3RleHQ+CjxsaW5lIHgxPSI0MTIiIHkxPSIxNDgiIHgyPSI0NjAiIHkyPSIxNDgiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhcikiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSI0MzYiIHk9IjE0MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPkFNUVAgMS4wPC90ZXh0Pgo8dGV4dCB4PSI0MzYiIHk9IjE2MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPm5vIGtleTwvdGV4dD4KPHJlY3QgeD0iNDY0IiB5PSI3MiIgd2lkdGg9IjM0OCIgaGVpZ2h0PSIxNTIiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjM4IiB5PSI5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPkF6dXJlIFNlcnZpY2UgQnVzIChTdGFuZGFyZCk8L3RleHQ+Cjx0ZXh0IHg9IjYzOCIgeT0iMTA4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNjQ3NDhiIj5zZXNzaW9uLWVuYWJsZWQgcXVldWU8L3RleHQ+CjxyZWN0IHg9IjQ4MCIgeT0iMTIwIiB3aWR0aD0iMzE2IiBoZWlnaHQ9IjI4IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNDkyIiB5PSIxMzgiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMwNDc4NTciPnNlc3Npb24gQTwvdGV4dD4KPHRleHQgeD0iNzkyIiB5PSIxMzgiIHRleHQtYW5jaG9yPSJlbmQiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPm0xIOKGkiBtMiDihpIgbTM8L3RleHQ+CjxyZWN0IHg9IjQ4MCIgeT0iMTUyIiB3aWR0aD0iMzE2IiBoZWlnaHQ9IjI4IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNDkyIiB5PSIxNzAiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMwNDc4NTciPnNlc3Npb24gQjwvdGV4dD4KPHRleHQgeD0iNzkyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJlbmQiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPm0xIOKGkiBtMjwvdGV4dD4KPHJlY3QgeD0iNDgwIiB5PSIxODQiIHdpZHRoPSIzMTYiIGhlaWdodD0iMjgiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0OTIiIHk9IjIwMiIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6IzA0Nzg1NyI+c2Vzc2lvbiBDPC90ZXh0Pgo8dGV4dCB4PSI3OTIiIHk9IjIwMiIgdGV4dC1hbmNob3I9ImVuZCIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6IzMzNDE1NSI+bTEg4oaSIG0yIOKGkiBtMzwvdGV4dD4KPC9zdmc+)

![The SQS SDK calls the authenticated Cloud Adapter endpoint. The adapter maps MessageGroupId to a native Service Bus session, allowing one message in flight per group and bounded active receiver slots.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjUwIiB2aWV3Qm94PSIwIDAgODM2IDI1MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgU1FTIFNESyBjYWxscyB0aGUgYXV0aGVudGljYXRlZCBDbG91ZCBBZGFwdGVyIGVuZHBvaW50LiBUaGUgYWRhcHRlciBtYXBzIE1lc3NhZ2VHcm91cElkIHRvIGEgbmF0aXZlIFNlcnZpY2UgQnVzIHNlc3Npb24sIGFsbG93aW5nIG9uZSBtZXNzYWdlIGluIGZsaWdodCBwZXIgZ3JvdXAgYW5kIGJvdW5kZWQgYWN0aXZlIHJlY2VpdmVyIHNsb3RzLiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iYXIiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjgiIHk9IjM0IiB3aWR0aD0iODIwIiBoZWlnaHQ9IjIwOCIgcng9IjE2IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjI2IiB5PSI1NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGIiPkNVU1RPTUVSJ1MgQ0xPVUQ8L3RleHQ+CjxyZWN0IHg9IjI0IiB5PSIxMDgiIHdpZHRoPSIxMTIiIGhlaWdodD0iOTIiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iODAiIHk9IjE0NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxM3B4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iODAiIHk9IjE2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjgwIiB5PSIxODEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTM2IiB5MT0iMTU0IiB4Mj0iMTg0IiB5Mj0iMTU0IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYXIpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iMTYwIiB5PSIxNDYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5TUVMgQVBJPC90ZXh0Pgo8cmVjdCB4PSIxODgiIHk9IjcyIiB3aWR0aD0iMjI0IiBoZWlnaHQ9IjE1MiIgcng9IjEzIiBzdHJva2Utd2lkdGg9IjEuNyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzMDAiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEzcHgiPlRlbnNvcjkgYWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMzAwIiB5PSIxMDgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmltcGxlbWVudHMgU1FTIEZJRk88L3RleHQ+CjxyZWN0IHg9IjIwMiIgeT0iMTIwIiB3aWR0aD0iMTk2IiBoZWlnaHQ9IjQyIiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzAwIiB5PSIxMzciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnNlbmRzICsgc3RhbmRhcmQgcmVjZWl2ZXM8L3RleHQ+Cjx0ZXh0IHg9IjMwMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+aW5kZXBlbmRlbnQgb2YgRklGTyByZWNlaXZlczwvdGV4dD4KPHJlY3QgeD0iMjAyIiB5PSIxNzAiIHdpZHRoPSIxOTYiIGhlaWdodD0iNDQiIHJ4PSI4IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSIzMDAiIHk9IjE4NyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+RklGTyBzZXNzaW9uIHJlY2VpdmVzPC90ZXh0Pgo8dGV4dCB4PSIzMDAiIHk9IjIwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnN0cmljdCBwZXItZ3JvdXAgb3JkZXI8L3RleHQ+CjxsaW5lIHgxPSI0MTIiIHkxPSIxNDgiIHgyPSI0NjAiIHkyPSIxNDgiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNhcikiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSI0MzYiIHk9IjE0MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPkFNUVAgMS4wPC90ZXh0Pgo8dGV4dCB4PSI0MzYiIHk9IjE2MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPm5vIGtleTwvdGV4dD4KPHJlY3QgeD0iNDY0IiB5PSI3MiIgd2lkdGg9IjM0OCIgaGVpZ2h0PSIxNTIiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjM4IiB5PSI5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPkF6dXJlIFNlcnZpY2UgQnVzIChTdGFuZGFyZCk8L3RleHQ+Cjx0ZXh0IHg9IjYzOCIgeT0iMTA4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojOTRhM2I4Ij5zZXNzaW9uLWVuYWJsZWQgcXVldWU8L3RleHQ+CjxyZWN0IHg9IjQ4MCIgeT0iMTIwIiB3aWR0aD0iMzE2IiBoZWlnaHQ9IjI4IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNDkyIiB5PSIxMzgiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiM2ZWU3YjciPnNlc3Npb24gQTwvdGV4dD4KPHRleHQgeD0iNzkyIiB5PSIxMzgiIHRleHQtYW5jaG9yPSJlbmQiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPm0xIOKGkiBtMiDihpIgbTM8L3RleHQ+CjxyZWN0IHg9IjQ4MCIgeT0iMTUyIiB3aWR0aD0iMzE2IiBoZWlnaHQ9IjI4IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNDkyIiB5PSIxNzAiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiM2ZWU3YjciPnNlc3Npb24gQjwvdGV4dD4KPHRleHQgeD0iNzkyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJlbmQiIHN0eWxlPSJmb250OjEwcHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPm0xIOKGkiBtMjwvdGV4dD4KPHJlY3QgeD0iNDgwIiB5PSIxODQiIHdpZHRoPSIzMTYiIGhlaWdodD0iMjgiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0OTIiIHk9IjIwMiIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6IzZlZTdiNyI+c2Vzc2lvbiBDPC90ZXh0Pgo8dGV4dCB4PSI3OTIiIHk9IjIwMiIgdGV4dC1hbmNob3I9ImVuZCIgc3R5bGU9ImZvbnQ6MTBweCAnU0YgTW9ubycsTWVubG8sbW9ub3NwYWNlO2ZpbGw6I2NiZDVlMSI+bTEg4oaSIG0yIOKGkiBtMzwvdGV4dD4KPC9zdmc+)

Each session is one MessageGroupId , so each group keeps strict order with one message in flight.

#### How sessions preserve group order

A Service Bus session groups messages under one ID and gives one consumer exclusive access to it. While that consumer holds the session, no other consumer can receive its messages. Messages arrive in the order they were queued, and the adapter allows one message in flight per group. Service Bus assigns each active group to one consumer even when several application pods receive from the same queue, so your pods need no shared lock table, leader election or partition assignment.

* **One message in flight per group.** A group's next message is delivered only after the current one is deleted, as with the PostgreSQL FIFO option. This limits a single group to one message per round trip, in exchange for strict order.
* **A slow consumer keeps its group.** The adapter renews the session lock while your visibility timeout runs. `ChangeMessageVisibility` with a longer timeout renews the lock; zero makes the message available again at once, in order.
* **Receive counts stay accurate.** When the adapter gives up a session, it first releases the in-flight message so its delivery count goes up, moving a failing message toward its redrive limit instead of resetting it. It also receives no more messages than the remaining `MaxNumberOfMessages`, so no message is received and dropped, which would raise its count.

![Each MessageGroupId is a Service Bus session. Service Bus gives each session to one consumer at a time, so two consumer pods hold different groups, with one message in flight per group. Service Bus tracks which consumer holds each session; the adapters share no lock table.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjY0IiB2aWV3Qm94PSIwIDAgODM2IDI2NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFYWNoIE1lc3NhZ2VHcm91cElkIGlzIGEgU2VydmljZSBCdXMgc2Vzc2lvbi4gU2VydmljZSBCdXMgZ2l2ZXMgZWFjaCBzZXNzaW9uIHRvIG9uZSBjb25zdW1lciBhdCBhIHRpbWUsIHNvIHR3byBjb25zdW1lciBwb2RzIGhvbGQgZGlmZmVyZW50IGdyb3Vwcywgd2l0aCBvbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwLiBTZXJ2aWNlIEJ1cyB0cmFja3Mgd2hpY2ggY29uc3VtZXIgaG9sZHMgZWFjaCBzZXNzaW9uOyB0aGUgYWRhcHRlcnMgc2hhcmUgbm8gbG9jayB0YWJsZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InNhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj4KPC9kZWZzPgo8dGV4dCB4PSIyMCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiMwNDc4NTciPlNFU1NJT04tRU5BQkxFRCBRVUVVRTwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+QlJPS0VSIEdSQU5UUyBFQUNIIFNFU1NJT04gVE8gT05FIENPTlNVTUVSPC90ZXh0Pgo8cmVjdCB4PSIyMCIgeT0iMzYiIHdpZHRoPSIyNTAiIGhlaWdodD0iMjEyIiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjM2IiB5PSI1MiIgd2lkdGg9IjIxOCIgaGVpZ2h0PSI1MiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojYTdmM2QwIi8+Cjx0ZXh0IHg9IjQ4IiB5PSI3MiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1Nztmb250LXdlaWdodDo3MDAiPmdyb3VwIEE8L3RleHQ+CjxyZWN0IHg9IjEyMCIgeT0iNjAiIHdpZHRoPSIzNCIgaGVpZ2h0PSIyMCIgcng9IjQiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiNhN2YzZDAiLz48dGV4dCB4PSIxMzciIHk9Ijc0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMDQ3ODU3Ij5tMTwvdGV4dD4KPHJlY3QgeD0iMTU4IiB5PSI2MCIgd2lkdGg9IjM0IiBoZWlnaHQ9IjIwIiByeD0iNCIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPjx0ZXh0IHg9IjE3NSIgeT0iNzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5tMjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSI2MCIgd2lkdGg9IjM0IiBoZWlnaHQ9IjIwIiByeD0iNCIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPjx0ZXh0IHg9IjIxMyIgeT0iNzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5tMzwvdGV4dD4KPHRleHQgeD0iNDgiIHk9Ijk2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMDQ3ODU3O2ZvbnQtc2l6ZTo5LjVweCI+b25lIG1lc3NhZ2UgaW4gZmxpZ2h0PC90ZXh0Pgo8cmVjdCB4PSIzNiIgeT0iMTE2IiB3aWR0aD0iMjE4IiBoZWlnaHQ9IjUyIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iNDgiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1Nztmb250LXdlaWdodDo3MDAiPmdyb3VwIEI8L3RleHQ+CjxyZWN0IHg9IjEyMCIgeT0iMTI0IiB3aWR0aD0iMzQiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojYTdmM2QwIi8+PHRleHQgeD0iMTM3IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiMwNDc4NTciPm0xPC90ZXh0Pgo8cmVjdCB4PSIxNTgiIHk9IjEyNCIgd2lkdGg9IjM0IiBoZWlnaHQ9IjIwIiByeD0iNCIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPjx0ZXh0IHg9IjE3NSIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+bTI8L3RleHQ+Cjx0ZXh0IHg9IjQ4IiB5PSIxNjAiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiMwNDc4NTc7Zm9udC1zaXplOjkuNXB4Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQ8L3RleHQ+CjxyZWN0IHg9IjM2IiB5PSIxODAiIHdpZHRoPSIyMTgiIGhlaWdodD0iNTIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2E3ZjNkMCIvPgo8dGV4dCB4PSI0OCIgeT0iMjAwIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3O2ZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgQzwvdGV4dD4KPHJlY3QgeD0iMTIwIiB5PSIxODgiIHdpZHRoPSIzNCIgaGVpZ2h0PSIyMCIgcng9IjQiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiNhN2YzZDAiLz48dGV4dCB4PSIxMzciIHk9IjIwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+bTE8L3RleHQ+CjxyZWN0IHg9IjE1OCIgeT0iMTg4IiB3aWR0aD0iMzQiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+PHRleHQgeD0iMTc1IiB5PSIyMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjNjQ3NDhiIj5tMjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxODgiIHdpZHRoPSIzNCIgaGVpZ2h0PSIyMCIgcng9IjQiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz48dGV4dCB4PSIyMTMiIHk9IjIwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPm0zPC90ZXh0Pgo8dGV4dCB4PSI0OCIgeT0iMjI0IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMDQ3ODU3O2ZvbnQtc2l6ZTo5LjVweCI+b25lIG1lc3NhZ2UgaW4gZmxpZ2h0PC90ZXh0Pgo8bGluZSB4MT0iMjcwIiB5MT0iNzgiIHgyPSI1NjIiIHkyPSI4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjc2EpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjI3MCIgeTE9IjE0MiIgeDI9IjU2MiIgeTI9IjEwNiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjc2EpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjI3MCIgeTE9IjIwNiIgeDI9IjU2MiIgeTI9IjE5MiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjc2EpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNTY2IiB5PSI0NCIgd2lkdGg9IjI1MCIgaGVpZ2h0PSI5NiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1ODAiIHk9IjY2IiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPmNvbnN1bWVyIHBvZCAxPC90ZXh0Pgo8cmVjdCB4PSI1ODAiIHk9Ijc4IiB3aWR0aD0iMTA2IiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjYzMyIgeT0iOTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPnNlc3Npb24gQTwvdGV4dD4KPHJlY3QgeD0iNjk0IiB5PSI3OCIgd2lkdGg9IjEwNiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI3NDciIHk9Ijk1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij5zZXNzaW9uIEI8L3RleHQ+Cjx0ZXh0IHg9IjU4MCIgeT0iMTI2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMDQ3ODU3Ij5leGNsdXNpdmUsIHNldCBieSBTZXJ2aWNlIEJ1czwvdGV4dD4KPHJlY3QgeD0iNTY2IiB5PSIxNTYiIHdpZHRoPSIyNTAiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTgwIiB5PSIxNzgiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+Y29uc3VtZXIgcG9kIDI8L3RleHQ+CjxyZWN0IHg9IjU4MCIgeT0iMTkwIiB3aWR0aD0iMTA2IiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjYzMyIgeT0iMjA3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMDQ3ODU3Ij5zZXNzaW9uIEM8L3RleHQ+Cjx0ZXh0IHg9IjcwMCIgeT0iMjA3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMDQ3ODU3Ij5leGNsdXNpdmU8L3RleHQ+Cjwvc3ZnPg==)

![Each MessageGroupId is a Service Bus session. Service Bus gives each session to one consumer at a time, so two consumer pods hold different groups, with one message in flight per group. Service Bus tracks which consumer holds each session; the adapters share no lock table.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjY0IiB2aWV3Qm94PSIwIDAgODM2IDI2NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJFYWNoIE1lc3NhZ2VHcm91cElkIGlzIGEgU2VydmljZSBCdXMgc2Vzc2lvbi4gU2VydmljZSBCdXMgZ2l2ZXMgZWFjaCBzZXNzaW9uIHRvIG9uZSBjb25zdW1lciBhdCBhIHRpbWUsIHNvIHR3byBjb25zdW1lciBwb2RzIGhvbGQgZGlmZmVyZW50IGdyb3Vwcywgd2l0aCBvbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwLiBTZXJ2aWNlIEJ1cyB0cmFja3Mgd2hpY2ggY29uc3VtZXIgaG9sZHMgZWFjaCBzZXNzaW9uOyB0aGUgYWRhcHRlcnMgc2hhcmUgbm8gbG9jayB0YWJsZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InNhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj4KPC9kZWZzPgo8dGV4dCB4PSIyMCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2ZWU3YjciPlNFU1NJT04tRU5BQkxFRCBRVUVVRTwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+QlJPS0VSIEdSQU5UUyBFQUNIIFNFU1NJT04gVE8gT05FIENPTlNVTUVSPC90ZXh0Pgo8cmVjdCB4PSIyMCIgeT0iMzYiIHdpZHRoPSIyNTAiIGhlaWdodD0iMjEyIiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjM2IiB5PSI1MiIgd2lkdGg9IjIxOCIgaGVpZ2h0PSI1MiIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ4IiB5PSI3MiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNztmb250LXdlaWdodDo3MDAiPmdyb3VwIEE8L3RleHQ+CjxyZWN0IHg9IjEyMCIgeT0iNjAiIHdpZHRoPSIzNCIgaGVpZ2h0PSIyMCIgcng9IjQiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSIxMzciIHk9Ijc0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZmlsbDojNmVlN2I3Ij5tMTwvdGV4dD4KPHJlY3QgeD0iMTU4IiB5PSI2MCIgd2lkdGg9IjM0IiBoZWlnaHQ9IjIwIiByeD0iNCIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPjx0ZXh0IHg9IjE3NSIgeT0iNzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5tMjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSI2MCIgd2lkdGg9IjM0IiBoZWlnaHQ9IjIwIiByeD0iNCIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPjx0ZXh0IHg9IjIxMyIgeT0iNzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5tMzwvdGV4dD4KPHRleHQgeD0iNDgiIHk9Ijk2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojNmVlN2I3O2ZvbnQtc2l6ZTo5LjVweCI+b25lIG1lc3NhZ2UgaW4gZmxpZ2h0PC90ZXh0Pgo8cmVjdCB4PSIzNiIgeT0iMTE2IiB3aWR0aD0iMjE4IiBoZWlnaHQ9IjUyIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNDgiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNztmb250LXdlaWdodDo3MDAiPmdyb3VwIEI8L3RleHQ+CjxyZWN0IHg9IjEyMCIgeT0iMTI0IiB3aWR0aD0iMzQiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojMDQ3ODU3Ii8+PHRleHQgeD0iMTM3IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2ZWU3YjciPm0xPC90ZXh0Pgo8cmVjdCB4PSIxNTgiIHk9IjEyNCIgd2lkdGg9IjM0IiBoZWlnaHQ9IjIwIiByeD0iNCIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPjx0ZXh0IHg9IjE3NSIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+bTI8L3RleHQ+Cjx0ZXh0IHg9IjQ4IiB5PSIxNjAiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2ZWU3Yjc7Zm9udC1zaXplOjkuNXB4Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQ8L3RleHQ+CjxyZWN0IHg9IjM2IiB5PSIxODAiIHdpZHRoPSIyMTgiIGhlaWdodD0iNTIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0OCIgeT0iMjAwIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3O2ZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgQzwvdGV4dD4KPHJlY3QgeD0iMTIwIiB5PSIxODgiIHdpZHRoPSIzNCIgaGVpZ2h0PSIyMCIgcng9IjQiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSIxMzciIHk9IjIwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+bTE8L3RleHQ+CjxyZWN0IHg9IjE1OCIgeT0iMTg4IiB3aWR0aD0iMzQiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+PHRleHQgeD0iMTc1IiB5PSIyMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjOTRhM2I4Ij5tMjwvdGV4dD4KPHJlY3QgeD0iMTk2IiB5PSIxODgiIHdpZHRoPSIzNCIgaGVpZ2h0PSIyMCIgcng9IjQiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz48dGV4dCB4PSIyMTMiIHk9IjIwMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPm0zPC90ZXh0Pgo8dGV4dCB4PSI0OCIgeT0iMjI0IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojNmVlN2I3O2ZvbnQtc2l6ZTo5LjVweCI+b25lIG1lc3NhZ2UgaW4gZmxpZ2h0PC90ZXh0Pgo8bGluZSB4MT0iMjcwIiB5MT0iNzgiIHgyPSI1NjIiIHkyPSI4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjc2EpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjI3MCIgeTE9IjE0MiIgeDI9IjU2MiIgeTI9IjEwNiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjc2EpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjI3MCIgeTE9IjIwNiIgeDI9IjU2MiIgeTI9IjE5MiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjc2EpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNTY2IiB5PSI0NCIgd2lkdGg9IjI1MCIgaGVpZ2h0PSI5NiIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1ODAiIHk9IjY2IiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPmNvbnN1bWVyIHBvZCAxPC90ZXh0Pgo8cmVjdCB4PSI1ODAiIHk9Ijc4IiB3aWR0aD0iMTA2IiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjYzMyIgeT0iOTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPnNlc3Npb24gQTwvdGV4dD4KPHJlY3QgeD0iNjk0IiB5PSI3OCIgd2lkdGg9IjEwNiIgaGVpZ2h0PSIyNiIgcng9IjYiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI3NDciIHk9Ijk1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij5zZXNzaW9uIEI8L3RleHQ+Cjx0ZXh0IHg9IjU4MCIgeT0iMTI2IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojNmVlN2I3Ij5leGNsdXNpdmUsIHNldCBieSBTZXJ2aWNlIEJ1czwvdGV4dD4KPHJlY3QgeD0iNTY2IiB5PSIxNTYiIHdpZHRoPSIyNTAiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjYiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTgwIiB5PSIxNzgiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTJweCI+Y29uc3VtZXIgcG9kIDI8L3RleHQ+CjxyZWN0IHg9IjU4MCIgeT0iMTkwIiB3aWR0aD0iMTA2IiBoZWlnaHQ9IjI2IiByeD0iNiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjYzMyIgeT0iMjA3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojNmVlN2I3Ij5zZXNzaW9uIEM8L3RleHQ+Cjx0ZXh0IHg9IjcwMCIgeT0iMjA3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojNmVlN2I3Ij5leGNsdXNpdmU8L3RleHQ+Cjwvc3ZnPg==)

Service Bus gives each group's session to exactly one consumer, so order holds as you add consumer pods.

#### Duplicate detection

Service Bus duplicate detection keeps a 5-minute history. Sends with the same deduplication key within that window queue one message. A consumer can still receive that message again after its visibility timeout. Service Bus keeps the deduplication history, so the adapter tracks nothing extra.

An explicit `MessageDeduplicationId` takes precedence. Otherwise the adapter uses a hash of the body on every `.fifo` send. It always sets this hash because its messaging permissions cannot read whether content-based deduplication is on. With duplicate detection enabled, Service Bus uses the hash to drop retries; with it disabled, the hash is only an ID. The adapter stores the SQS `MessageId` separately, as an application property, and returns it on receive, so equal-body messages sent outside the window keep distinct SQS IDs.

![On a .fifo send the adapter uses the MessageDeduplicationId, or a hash of the body, as the Service Bus message ID. Service Bus duplicate detection, with a 5-minute window, drops a repeated send instead of queuing it twice. Consumers can still receive a message again after its visibility timeout. The SQS MessageId is kept as an application property.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjMyIiB2aWV3Qm94PSIwIDAgODM2IDIzMiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBhIC5maWZvIHNlbmQgdGhlIGFkYXB0ZXIgdXNlcyB0aGUgTWVzc2FnZURlZHVwbGljYXRpb25JZCwgb3IgYSBoYXNoIG9mIHRoZSBib2R5LCBhcyB0aGUgU2VydmljZSBCdXMgbWVzc2FnZSBJRC4gU2VydmljZSBCdXMgZHVwbGljYXRlIGRldGVjdGlvbiwgd2l0aCBhIDUtbWludXRlIHdpbmRvdywgZHJvcHMgYSByZXBlYXRlZCBzZW5kIGluc3RlYWQgb2YgcXVldWluZyBpdCB0d2ljZS4gQ29uc3VtZXJzIGNhbiBzdGlsbCByZWNlaXZlIGEgbWVzc2FnZSBhZ2FpbiBhZnRlciBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0LiBUaGUgU1FTIE1lc3NhZ2VJZCBpcyBrZXB0IGFzIGFuIGFwcGxpY2F0aW9uIHByb3BlcnR5LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iZG0iIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjI0IiB5PSI0OCIgd2lkdGg9IjE1MiIgaGVpZ2h0PSI1NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIxMDAiIHk9IjcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjExLjVweCI+U2VuZE1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjEwMCIgeT0iOTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5ib2R5ID0gWDwvdGV4dD4KPHJlY3QgeD0iMjQiIHk9IjEzNCIgd2lkdGg9IjE1MiIgaGVpZ2h0PSI1NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIxMDAiIHk9IjE1OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMS41cHgiPlNlbmRNZXNzYWdlPC90ZXh0Pgo8dGV4dCB4PSIxMDAiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmJvZHkgPSBYIChyZXRyeSk8L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI3NSIgeDI9IjIwNiIgeTI9IjEwMCIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2RtKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxsaW5lIHgxPSIxNzYiIHkxPSIxNjEiIHgyPSIyMDYiIHkyPSIxMzIiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNkbSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSIyMTAiIHk9Ijc2IiB3aWR0aD0iMjIyIiBoZWlnaHQ9IjgwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS43IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjMyMSIgeT0iMTAwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEycHgiPlRlbnNvcjkgYWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMzIxIiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMwNDc4NTciPmRlZHVwIGtleSA9IGlkIG9yIGNvbnRlbnQgaGFzaDwvdGV4dD4KPHRleHQgeD0iMzIxIiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5TUVMgTWVzc2FnZUlkIOKGkiBhcHAgcHJvcGVydHk8L3RleHQ+CjxsaW5lIHgxPSI0MzIiIHkxPSIxMTYiIHgyPSI0NzIiIHkyPSIxMTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNkbSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSI0NzgiIHk9IjQ4IiB3aWR0aD0iMzM0IiBoZWlnaHQ9IjE0MCIgcng9IjEzIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI2NDUiIHk9IjcwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPkF6dXJlIFNlcnZpY2UgQnVzPC90ZXh0Pgo8dGV4dCB4PSI2NDUiIHk9Ijg2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNjQ3NDhiIj5kdXBsaWNhdGUgZGV0ZWN0aW9uIMK3IDUtbWluIHdpbmRvdzwvdGV4dD4KPHJlY3QgeD0iNDk2IiB5PSIxMDAiIHdpZHRoPSIzMDAiIGhlaWdodD0iMzIiIHJ4PSI3IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI1MTAiIHk9IjEyMCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+bTwvdGV4dD4KPHRleHQgeD0iNzgyIiB5PSIxMjAiIHRleHQtYW5jaG9yPSJlbmQiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+b25lIGVucXVldWUg4pyTPC90ZXh0Pgo8cmVjdCB4PSI0OTYiIHk9IjE0MiIgd2lkdGg9IjMwMCIgaGVpZ2h0PSIzMiIgcng9IjciIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZmZmYmViO3N0cm9rZTojZmRlNjhhIi8+Cjx0ZXh0IHg9IjUxMCIgeT0iMTYyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5yZXRyeTwvdGV4dD4KPHRleHQgeD0iNzgyIiB5PSIxNjIiIHRleHQtYW5jaG9yPSJlbmQiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojYjQ1MzA5Ij5kcm9wcGVkIGJ5IFNlcnZpY2UgQnVzPC90ZXh0Pgo8L3N2Zz4=)

![On a .fifo send the adapter uses the MessageDeduplicationId, or a hash of the body, as the Service Bus message ID. Service Bus duplicate detection, with a 5-minute window, drops a repeated send instead of queuing it twice. Consumers can still receive a message again after its visibility timeout. The SQS MessageId is kept as an application property.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjMyIiB2aWV3Qm94PSIwIDAgODM2IDIzMiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBhIC5maWZvIHNlbmQgdGhlIGFkYXB0ZXIgdXNlcyB0aGUgTWVzc2FnZURlZHVwbGljYXRpb25JZCwgb3IgYSBoYXNoIG9mIHRoZSBib2R5LCBhcyB0aGUgU2VydmljZSBCdXMgbWVzc2FnZSBJRC4gU2VydmljZSBCdXMgZHVwbGljYXRlIGRldGVjdGlvbiwgd2l0aCBhIDUtbWludXRlIHdpbmRvdywgZHJvcHMgYSByZXBlYXRlZCBzZW5kIGluc3RlYWQgb2YgcXVldWluZyBpdCB0d2ljZS4gQ29uc3VtZXJzIGNhbiBzdGlsbCByZWNlaXZlIGEgbWVzc2FnZSBhZ2FpbiBhZnRlciBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0LiBUaGUgU1FTIE1lc3NhZ2VJZCBpcyBrZXB0IGFzIGFuIGFwcGxpY2F0aW9uIHByb3BlcnR5LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz4KPG1hcmtlciBpZD0iZG0iIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8L2RlZnM+CjxyZWN0IHg9IjI0IiB5PSI0OCIgd2lkdGg9IjE1MiIgaGVpZ2h0PSI1NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIxMDAiIHk9IjcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjExLjVweCI+U2VuZE1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjEwMCIgeT0iOTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5ib2R5ID0gWDwvdGV4dD4KPHJlY3QgeD0iMjQiIHk9IjEzNCIgd2lkdGg9IjE1MiIgaGVpZ2h0PSI1NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIxMDAiIHk9IjE1OCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMS41cHgiPlNlbmRNZXNzYWdlPC90ZXh0Pgo8dGV4dCB4PSIxMDAiIHk9IjE3NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmJvZHkgPSBYIChyZXRyeSk8L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI3NSIgeDI9IjIwNiIgeTI9IjEwMCIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2RtKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxsaW5lIHgxPSIxNzYiIHkxPSIxNjEiIHgyPSIyMDYiIHkyPSIxMzIiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNkbSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSIyMTAiIHk9Ijc2IiB3aWR0aD0iMjIyIiBoZWlnaHQ9IjgwIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS43IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjMyMSIgeT0iMTAwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEycHgiPlRlbnNvcjkgYWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iMzIxIiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM2ZWU3YjciPmRlZHVwIGtleSA9IGlkIG9yIGNvbnRlbnQgaGFzaDwvdGV4dD4KPHRleHQgeD0iMzIxIiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5TUVMgTWVzc2FnZUlkIOKGkiBhcHAgcHJvcGVydHk8L3RleHQ+CjxsaW5lIHgxPSI0MzIiIHkxPSIxMTYiIHgyPSI0NzIiIHkyPSIxMTYiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNkbSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSI0NzgiIHk9IjQ4IiB3aWR0aD0iMzM0IiBoZWlnaHQ9IjE0MCIgcng9IjEzIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI2NDUiIHk9IjcwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPkF6dXJlIFNlcnZpY2UgQnVzPC90ZXh0Pgo8dGV4dCB4PSI2NDUiIHk9Ijg2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojOTRhM2I4Ij5kdXBsaWNhdGUgZGV0ZWN0aW9uIMK3IDUtbWluIHdpbmRvdzwvdGV4dD4KPHJlY3QgeD0iNDk2IiB5PSIxMDAiIHdpZHRoPSIzMDAiIGhlaWdodD0iMzIiIHJ4PSI3IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI1MTAiIHk9IjEyMCIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+bTwvdGV4dD4KPHRleHQgeD0iNzgyIiB5PSIxMjAiIHRleHQtYW5jaG9yPSJlbmQiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+b25lIGVucXVldWUg4pyTPC90ZXh0Pgo8cmVjdCB4PSI0OTYiIHk9IjE0MiIgd2lkdGg9IjMwMCIgaGVpZ2h0PSIzMiIgcng9IjciIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojNDIyMDA2O3N0cm9rZTojOTI0MDBlIi8+Cjx0ZXh0IHg9IjUxMCIgeT0iMTYyIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5yZXRyeTwvdGV4dD4KPHRleHQgeD0iNzgyIiB5PSIxNjIiIHRleHQtYW5jaG9yPSJlbmQiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojZmJiZjI0Ij5kcm9wcGVkIGJ5IFNlcnZpY2UgQnVzPC90ZXh0Pgo8L3N2Zz4=)

The adapter uses the MessageDeduplicationId, or a body hash, as the Service Bus message ID. Service Bus drops repeats within 5 minutes.

#### Dead-lettering

Service Bus dead-letters a message when its delivery count reaches the limit set by `maxReceiveCount`. The next message in that group can then be delivered.

The adapter cannot receive from Service Bus's built-in dead-letter subqueue, so Tensor9 sets up automatic forwarding to the dead-letter queue (DLQ) you declared, keeping the session ID. A FIFO queue needs a FIFO DLQ, which is created with sessions enabled. Messages whose time to live (TTL) expires are dead-lettered too, so you can inspect or recover them from the DLQ.

Declaring a non-`.fifo` DLQ for a `.fifo` queue stops the build with a clear error, rather than creating a queue whose dead letters would have nowhere valid to go.

![A message that fails delivery maxReceiveCount times is dead-lettered by Service Bus, and its group moves on. The dead-lettered message is forwarded to your declared FIFO dead-letter queue with its session ID, and expired messages go there too.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjI2IiB2aWV3Qm94PSIwIDAgODM2IDIyNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIG1lc3NhZ2UgdGhhdCBmYWlscyBkZWxpdmVyeSBtYXhSZWNlaXZlQ291bnQgdGltZXMgaXMgZGVhZC1sZXR0ZXJlZCBieSBTZXJ2aWNlIEJ1cywgYW5kIGl0cyBncm91cCBtb3ZlcyBvbi4gVGhlIGRlYWQtbGV0dGVyZWQgbWVzc2FnZSBpcyBmb3J3YXJkZWQgdG8geW91ciBkZWNsYXJlZCBGSUZPIGRlYWQtbGV0dGVyIHF1ZXVlIHdpdGggaXRzIHNlc3Npb24gSUQsIGFuZCBleHBpcmVkIG1lc3NhZ2VzIGdvIHRoZXJlIHRvby4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImRsIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj4KPC9kZWZzPgo8dGV4dCB4PSIyNCIgeT0iMzYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPlNPVVJDRSBRVUVVRTwvdGV4dD4KPHJlY3QgeD0iMjQiIHk9IjQ2IiB3aWR0aD0iMjE0IiBoZWlnaHQ9IjE0MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8cmVjdCB4PSI0MCIgeT0iNjQiIHdpZHRoPSIxODIiIGhlaWdodD0iMzQiIHJ4PSI4IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2ZmZmJlYjtzdHJva2U6I2ZkZTY4YSIvPgo8dGV4dCB4PSIxMzEiIHk9Ijg2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTEuNXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojYjQ1MzA5Ij5mYWlsZWQgbWVzc2FnZTwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjEyMiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzMzNDE1NSI+bmV4dDogbTIgwrcgbTMgwrcg4oCmPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTUwIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmdyb3VwIG1vdmVzIG9uPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTY4IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZm9udC1zaXplOjkuNXB4Ij5uZXh0IG1lc3NhZ2UgaXMgZGVsaXZlcmVkPC90ZXh0Pgo8bGluZSB4MT0iMjM4IiB5MT0iMTEwIiB4Mj0iMjg2IiB5Mj0iOTgiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNkbCkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8cmVjdCB4PSIyOTAiIHk9IjY0IiB3aWR0aD0iMTc2IiBoZWlnaHQ9Ijc2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjM3OCIgeT0iOTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPm1heFJlY2VpdmVDb3VudDwvdGV4dD4KPHRleHQgeD0iMzc4IiB5PSIxMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5OIGRlbGl2ZXJpZXMsPC90ZXh0Pgo8dGV4dCB4PSIzNzgiIHk9IjEyNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnRoZW4gZGVhZC1sZXR0ZXI8L3RleHQ+CjxsaW5lIHgxPSI0NjYiIHkxPSIxMDAiIHgyPSI1MTIiIHkyPSIxMDAiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNkbCkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSI0ODkiIHk9IjkyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+Zm9yd2FyZDwvdGV4dD4KPHJlY3QgeD0iNTE2IiB5PSI0NiIgd2lkdGg9IjI5NiIgaGVpZ2h0PSIxNDAiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNjY0IiB5PSI5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtc2l6ZToxMnB4Ij55b3VyIGRlY2xhcmVkIERMUTwvdGV4dD4KPHRleHQgeD0iNjY0IiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNlc3Npb24tZW5hYmxlZCDCtyBGSUZPIMK3IHNlc3Npb24gaWQga2VwdDwvdGV4dD4KPHRleHQgeD0iNjY0IiB5PSIxNDQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPmV4cGlyZWQgbWVzc2FnZXMgYXJlIGZvcndhcmRlZCB0b288L3RleHQ+Cjwvc3ZnPg==)

![A message that fails delivery maxReceiveCount times is dead-lettered by Service Bus, and its group moves on. The dead-lettered message is forwarded to your declared FIFO dead-letter queue with its session ID, and expired messages go there too.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjI2IiB2aWV3Qm94PSIwIDAgODM2IDIyNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIG1lc3NhZ2UgdGhhdCBmYWlscyBkZWxpdmVyeSBtYXhSZWNlaXZlQ291bnQgdGltZXMgaXMgZGVhZC1sZXR0ZXJlZCBieSBTZXJ2aWNlIEJ1cywgYW5kIGl0cyBncm91cCBtb3ZlcyBvbi4gVGhlIGRlYWQtbGV0dGVyZWQgbWVzc2FnZSBpcyBmb3J3YXJkZWQgdG8geW91ciBkZWNsYXJlZCBGSUZPIGRlYWQtbGV0dGVyIHF1ZXVlIHdpdGggaXRzIHNlc3Npb24gSUQsIGFuZCBleHBpcmVkIG1lc3NhZ2VzIGdvIHRoZXJlIHRvby4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImRsIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj4KPC9kZWZzPgo8dGV4dCB4PSIyNCIgeT0iMzYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPlNPVVJDRSBRVUVVRTwvdGV4dD4KPHJlY3QgeD0iMjQiIHk9IjQ2IiB3aWR0aD0iMjE0IiBoZWlnaHQ9IjE0MCIgcng9IjEyIiBzdHJva2Utd2lkdGg9IjEuNiIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8cmVjdCB4PSI0MCIgeT0iNjQiIHdpZHRoPSIxODIiIGhlaWdodD0iMzQiIHJ4PSI4IiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzQyMjAwNjtzdHJva2U6IzkyNDAwZSIvPgo8dGV4dCB4PSIxMzEiIHk9Ijg2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTEuNXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojZmJiZjI0Ij5mYWlsZWQgbWVzc2FnZTwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjEyMiIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6I2NiZDVlMSI+bmV4dDogbTIgwrcgbTMgwrcg4oCmPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTUwIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmdyb3VwIG1vdmVzIG9uPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTY4IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZm9udC1zaXplOjkuNXB4Ij5uZXh0IG1lc3NhZ2UgaXMgZGVsaXZlcmVkPC90ZXh0Pgo8bGluZSB4MT0iMjM4IiB5MT0iMTEwIiB4Mj0iMjg2IiB5Mj0iOTgiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNkbCkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8cmVjdCB4PSIyOTAiIHk9IjY0IiB3aWR0aD0iMTc2IiBoZWlnaHQ9Ijc2IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjM3OCIgeT0iOTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPm1heFJlY2VpdmVDb3VudDwvdGV4dD4KPHRleHQgeD0iMzc4IiB5PSIxMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5OIGRlbGl2ZXJpZXMsPC90ZXh0Pgo8dGV4dCB4PSIzNzgiIHk9IjEyNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPnRoZW4gZGVhZC1sZXR0ZXI8L3RleHQ+CjxsaW5lIHgxPSI0NjYiIHkxPSIxMDAiIHgyPSI1MTIiIHkyPSIxMDAiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNkbCkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSI0ODkiIHk9IjkyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+Zm9yd2FyZDwvdGV4dD4KPHJlY3QgeD0iNTE2IiB5PSI0NiIgd2lkdGg9IjI5NiIgaGVpZ2h0PSIxNDAiIHJ4PSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNjY0IiB5PSI5NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtc2l6ZToxMnB4Ij55b3VyIGRlY2xhcmVkIERMUTwvdGV4dD4KPHRleHQgeD0iNjY0IiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNlc3Npb24tZW5hYmxlZCDCtyBGSUZPIMK3IHNlc3Npb24gaWQga2VwdDwvdGV4dD4KPHRleHQgeD0iNjY0IiB5PSIxNDQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPmV4cGlyZWQgbWVzc2FnZXMgYXJlIGZvcndhcmRlZCB0b288L3RleHQ+Cjwvc3ZnPg==)

Service Bus forwards messages that reach maxReceiveCount to your declared DLQ, where the adapter can receive them.

#### Limitations

Where SQS FIFO and Service Bus differ

* **Duplicate sends behave differently: the dropped send returns a new `MessageId`.** SQS returns the original message's `MessageId` (and `SequenceNumber`) for a duplicate. Here the duplicate is still dropped (consumers can still get redeliveries), but its response contains a new ID that matches no delivered message. Do not wait for that ID.
* **`SequenceNumber` is not returned on send.** Service Bus cannot return its sequence number when a message is sent. Receive responses include it; it increases across the queue, and so within each group.
* **Visibility timeouts above 5 minutes are not supported.** The visibility timeout maps to the session lock, which Tensor9 sets to 5 minutes, ten times the adapter's renewal interval. A longer value returns an error rather than being shortened. `ChangeMessageVisibility` renews the lock.
* **Receipt handles behave differently: they stop working when the adapter restarts.** A handle needs a live session lock. After a restart, old handles are invalid, and the group's in-flight message is delivered again, in order, when its session lock expires, within 5 minutes.
* **Expiry behaves differently: it can affect a whole session.** SQS retention applies to each message. On Service Bus, an expired message at the front can expire its whole session. Expired messages are dead-lettered and can be recovered from the DLQ, but more may expire together than on SQS.
* **Single-group throughput behaves differently: one message per round trip.** Strict order allows one message in flight per group, against up to 10 per receive on SQS. Total throughput grows with the number of groups, so parallelism comes from many groups, not from batching within one.
* **Receives on an empty queue behave differently: they can wait longer than `WaitTimeSeconds`.** Service Bus controls how long accepting a session takes, and the adapter never cancels it partway, because that could leave a session lock held. A FIFO receive on an empty queue can overrun its wait by up to one accept window, about 60 seconds at worst; your monitoring shows the real figure on Azure.
* **Per-message `DelaySeconds` is not supported.** It is rejected, as SQS rejects it on a FIFO queue, because a delayed message would arrive after later messages in its group. For queue-level settings, Cloud Adapter manages the logical queue settings, but the messaging backend rejects a nonzero queue delay and new dead-letter routes.
* **You must drain a queue before changing its FIFO or deduplication settings.** Sessions and duplicate detection are fixed when the queue is created. Changing between standard and FIFO, or turning content-based deduplication on or off, deletes and re-creates the queue and loses its messages. Every FIFO build warns about this.
* **Sends without a deduplication ID behave differently: they are accepted.** SQS requires `MessageDeduplicationId` when content-based deduplication is off. The adapter cannot read that setting with its messaging permissions, so it accepts the send. Group order is kept, but you do not get the SQS validation error.

#### Other considerations

* **Moving from AWS.** The Service Bus namespace and queue start empty, and messages in SQS are not migrated. Switch over when the queue is drained, or write to both queues for a while, and drain each group so none switches partway through.
* **Who operates what.** Tensor9 creates the namespace and the queue, configured as described under Architecture, from your queue declarations, and runs the adapter next to your application. The declared `maxReceiveCount` sets when messages are forwarded to the DLQ. Microsoft operates Service Bus Standard: durability, backups and high availability. You operate the Azure subscription, cluster patching and monitoring. Sending and receiving need no queue-management credential.
* **FIFO must be selected explicitly.** Older deployments that used the earlier combined SQS-to-Service-Bus option supported standard queues only. Tensor9 does not convert them to FIFO; declare and select a FIFO queue to use sessions.

#### 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.

##### SQS FIFO · SQS request billing units

Feature: SQS FIFO.

Estimated monthly service charges by SQS request billing units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: East US; currency: USD.

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/8b0963a17ccc87d604bb96148a9803f3354f1bfeeeb3cd5e20f95e2ec3c67c74-light.svg)

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/b4aa01d0d6ac13e23e4ecc79f445b64853e7d726e43773c705cf8b18a3da091a-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.

| SQS request billing units (per second) | SQS (Simple Queue Service, FIFO queues) | Azure Service Bus | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 9.81 | 9.81 |
| 1 | 1.31 | 9.81 | 8.50 |
| 10 | 13.14 | 20.44 | 7.30 |
| 100 | 131.40 | 160.81 | 29.41 |
| 1,000 | 1,314.00 | 1,305.01 | -8.99 |
| 10,000 | 13,140.00 | 6,035.41 | -7,104.59 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Representative message size | 1,024 | bytes |
| Origin send batch fill | 1 | messages/request |
| Origin receive batch fill | 1 | messages/request |
| Origin delete batch fill | 1 | messages/request |
| Deliveries per message | 1 | attempts |
| Empty receive calls per message | 0 | requests |
| Queue residence window | 60 | seconds |
| Ordering and dedup work multiplier | 2 | multiplier |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target list price · provider operation | 0.0000008 | USD/provider operation |
| Target price guess · GiB-month | 0 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target price guess · 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 |
| Included before billing · provider operation | 13,000,000 | provider operation |
| Target monthly base charge · list price | 9.81193 | 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 |

* 1-KiB messages, unbatched send/receive/delete; actual batch and delivery assumptions stay visible. 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 → East US, 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.
* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.
* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.
* Azure Service Bus Standard bills a namespace base charge that includes 13 million operations a month, then graduated per-operation prices: USD 0.80 per million to 100 million, 0.50 to 2,500 million and 0.20 beyond. An operation is any API call (send, receive, complete) per 64 KB of message; the family's managed operations count calls, not 64 KB units. Standard has no storage charge (queue size quota up to 5 GB is included). More than 1,000 brokered connections bill USD 0.03 per connection-month, which this profile does not model.
* AWS Price List API, AWSQueueService offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json)
* 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-41a96e9bd678520a179bd0f5bb232496011160b0` / `2026-10-22.planning.2`. Curve: `workload-1`.

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

**SQS FIFO → Azure Service Bus: 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: East US. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: SQS billing units | 0.00 |
| Target: Target retained physical data | 0.00 |
| Target: Additional broker replica storage | 0.00 |
| Target: Published bytes | 0.00 |
| Target: Delivered bytes | 0.00 |
| Target: Target native provider operations after 13000000 included | 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 |
| Target: Target monthly base charge | 9.81 |
| **Origin service subtotal** | **0.00** |
| **Target service subtotal** | **9.81** |

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 · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Representative message size | 1,024 | bytes |
| Origin send batch fill | 1 | messages/request |
| Origin receive batch fill | 1 | messages/request |
| Origin delete batch fill | 1 | messages/request |
| Deliveries per message | 1 | attempts |
| Empty receive calls per message | 0 | requests |
| Queue residence window | 60 | seconds |
| Ordering and dedup work multiplier | 2 | multiplier |
| Target price guess · read | 0 | USD/read |
| Target price guess · write | 0 | USD/write |
| Target list price · provider operation | 0.0000008 | USD/provider operation |
| Target price guess · GiB-month | 0 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target price guess · 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 |
| Included before billing · provider operation | 13,000,000 | provider operation |
| Target monthly base charge · list price | 9.81193 | 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 |
| SQS billing units | 0 | 64-KiB request units |

* 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.

* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.

* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.

* Azure Service Bus Standard bills a namespace base charge that includes 13 million operations a month, then graduated per-operation prices: USD 0.80 per million to 100 million, 0.50 to 2,500 million and 0.20 beyond. An operation is any API call (send, receive, complete) per 64 KB of message; the family's managed operations count calls, not 64 KB units. Standard has no storage charge (queue size quota up to 5 GB is included). More than 1,000 brokered connections bill USD 0.03 per connection-month, which this profile does not model.

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

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

### Azure Cosmos DB (queue)

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Dead-letter redrive | Dead-letter | Out of scope | Most usage | cross-partition or cross-store transfer/redrive is unsupported; another queue/container is not part of the source partition transaction |
| Content-based deduplication | FIFO | Supported | Most usage | a content-hash dedup key over a 5-minute window (the SQS constant); content-based deduplication is honored when your queue declares it |
| Dedup echo (suppressed-send response) | FIFO | Supported | Most usage | a dedup-suppressed send echoes the original MessageId and SequenceNumber, matching the SQS response; Service Bus returns a new ID |
| FIFO ordering | FIFO | Supported | Common | a same-partition transaction orders each group; an unavailable predecessor blocks later messages; independent groups can progress concurrently |
| MessageDeduplicationId | FIFO | Supported | Most usage | the explicit tag takes precedence over the content hash (AWS's own rule); a FIFO send with neither a tag nor content-based-dedup is InvalidParameterValue, matching the AWS rejection; Service Bus does not reproduce this check |
| ReceiveRequestAttemptId | FIFO | Partial | Most usage | Queue scope replays an unchanged set for five minutes; modified claims require a new attempt; explicit attempt IDs are rejected in MessageGroup scope |
| SequenceNumber (send response) | FIFO | Supported | Most usage | returned on every FIFO send: the per-group sequence position, monotonic per group (Service Bus omits it) |
| CreateQueue / DeleteQueue / SetQueueAttributes / tags | Queues | Partial | Full surface | Cloud Adapter manages logical queues on provisioned containers, tags and supported defaults. Terraform owns the account, database and containers; nonzero queue delay and new dead-letter routes are rejected |
| GetQueueAttributes (approximate counts) | Queues | Partial | Full surface | approximate depth, cached about 5 s; recent sends, settlements and expiry may not yet be reflected |
| DelaySeconds (per message) | Send / receive | Out of scope | Common | rejected exactly as real SQS rejects per-message delay on a FIFO queue (a scheduled enqueue would break in-group order) |
| DeleteMessage | Send / receive | Supported | Common | settles only the exact durable receipt generation; a stale receipt cannot delete a newer claim |
| ReceiveMessage | Send / receive | Partial | Common | transactionally claims an ordered group prefix; conservative batches wait for all unsettled members before redelivery; MessageGroup scope selects one group per call |
| SendMessage | Send / receive | Supported | Common | MessageGroupId required (the AWS FIFO rule) and is the ordering unit; each send returns a real SequenceNumber (the per-group sequence position) |
| SendMessageBatch | Send / receive | Supported | Common | per-entry sends with a result for each entry |
| ChangeMessageVisibility | Visibility | Partial | Common | compares the current receipt and changes its member deadline; no broker lock ceiling; conservative batch redelivery waits for remaining live members |

#### How Cosmos serves SQS FIFO

The application keeps its SQS SDK, configured to use the adapter endpoint. Cosmos DB stores the message body and the state that makes it a queue: group sequence, duplicate-send result, current receipt, visibility deadline and lifecycle generation. Microsoft operates Cosmos; Tensor9 operates the adapter and queue procedures in the customer's Azure environment.

Queue-wide deduplication puts the whole queue in one logical partition. Explicit MessageGroup deduplication can put independent groups in separate partitions. This is a semantic choice, not a transparent throughput optimization: the latter can accept the same deduplication ID in two groups.

![SQS SDK to adapter to one partition-local Cosmos transaction over group, message, deduplication and receipt state.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3ODAiIGhlaWdodD0iMTUyIiB2aWV3Qm94PSIwIDAgNzgwIDE1MiIgcm9sZT0iaW1nIgphcmlhLWxhYmVsPSJTUVMgU0RLIHRvIGFkYXB0ZXIgdG8gb25lIHBhcnRpdGlvbi1sb2NhbCBDb3Ntb3MgdHJhbnNhY3Rpb24gb3ZlciBncm91cCwgbWVzc2FnZSwgZGVkdXBsaWNhdGlvbiBhbmQgcmVjZWlwdCBzdGF0ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPHJlY3QgeD0iMTAiIHk9IjM2IiB3aWR0aD0iMTMwIiBoZWlnaHQ9Ijc2IiByeD0iMTIiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzUiIHk9Ijc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZmlsbDojMGYxNzJhO2ZvbnQ6MTRweCBzYW5zLXNlcmlmIj5Zb3VyIFNRUyBTREs8L3RleHQ+CjxwYXRoIGQ9Ik0xNDAgNzQgSDIyNSBNMjE1IDY4IEwyMjUgNzQgTDIxNSA4MCIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6Izk0YTNiODtzdHJva2Utd2lkdGg6MiIvPgo8cmVjdCB4PSIyMjUiIHk9IjM2IiB3aWR0aD0iMTYwIiBoZWlnaHQ9Ijc2IiByeD0iMTIiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMzA1IiB5PSI2OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtmb250OjE0cHggc2Fucy1zZXJpZiI+U1FTIGFkYXB0ZXI8L3RleHQ+Cjx0ZXh0IHg9IjMwNSIgeT0iOTEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmaWxsOiM2NDc0OGI7Zm9udDoxMnB4IHNhbnMtc2VyaWYiPnZhbGlkYXRlIGFuZCB0cmFuc2xhdGU8L3RleHQ+CjxwYXRoIGQ9Ik0zODUgNzQgSDQ3MCBNNDYwIDY4IEw0NzAgNzQgTDQ2MCA4MCIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6Izk0YTNiODtzdHJva2Utd2lkdGg6MiIvPgo8cmVjdCB4PSI0NzAiIHk9IjE2IiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjExNiIgcng9IjEyIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjYyMCIgeT0iNDciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmaWxsOiMwZjE3MmE7Zm9udDoxNHB4IHNhbnMtc2VyaWYiPk9uZSBDb3Ntb3MgbG9naWNhbCBwYXJ0aXRpb248L3RleHQ+Cjx0ZXh0IHg9IjYyMCIgeT0iNzUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmaWxsOiM2NDc0OGI7Zm9udDoxMnB4IHNhbnMtc2VyaWYiPmdyb3VwICsgYm9keSArIGRlZHVwbGljYXRpb24gKyByZWNlaXB0PC90ZXh0Pgo8dGV4dCB4PSI2MjAiIHk9IjEwMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZpbGw6IzA0Nzg1Nztmb250OjEycHggc2Fucy1zZXJpZiI+Y29tbWl0IHRvZ2V0aGVyIG9yIGxlYXZlIG5vIGFjY2VwdGVkIHNlbmQ8L3RleHQ+Cjwvc3ZnPg==)

![SQS SDK to adapter to one partition-local Cosmos transaction over group, message, deduplication and receipt state.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3ODAiIGhlaWdodD0iMTUyIiB2aWV3Qm94PSIwIDAgNzgwIDE1MiIgcm9sZT0iaW1nIgphcmlhLWxhYmVsPSJTUVMgU0RLIHRvIGFkYXB0ZXIgdG8gb25lIHBhcnRpdGlvbi1sb2NhbCBDb3Ntb3MgdHJhbnNhY3Rpb24gb3ZlciBncm91cCwgbWVzc2FnZSwgZGVkdXBsaWNhdGlvbiBhbmQgcmVjZWlwdCBzdGF0ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPHJlY3QgeD0iMTAiIHk9IjM2IiB3aWR0aD0iMTMwIiBoZWlnaHQ9Ijc2IiByeD0iMTIiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzUiIHk9Ijc4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZmlsbDojZjFmNWY5O2ZvbnQ6MTRweCBzYW5zLXNlcmlmIj5Zb3VyIFNRUyBTREs8L3RleHQ+CjxwYXRoIGQ9Ik0xNDAgNzQgSDIyNSBNMjE1IDY4IEwyMjUgNzQgTDIxNSA4MCIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzY0NzQ4YjtzdHJva2Utd2lkdGg6MiIvPgo8cmVjdCB4PSIyMjUiIHk9IjM2IiB3aWR0aD0iMTYwIiBoZWlnaHQ9Ijc2IiByeD0iMTIiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMzA1IiB5PSI2OSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZpbGw6I2YxZjVmOTtmb250OjE0cHggc2Fucy1zZXJpZiI+U1FTIGFkYXB0ZXI8L3RleHQ+Cjx0ZXh0IHg9IjMwNSIgeT0iOTEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmaWxsOiM5NGEzYjg7Zm9udDoxMnB4IHNhbnMtc2VyaWYiPnZhbGlkYXRlIGFuZCB0cmFuc2xhdGU8L3RleHQ+CjxwYXRoIGQ9Ik0zODUgNzQgSDQ3MCBNNDYwIDY4IEw0NzAgNzQgTDQ2MCA4MCIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzY0NzQ4YjtzdHJva2Utd2lkdGg6MiIvPgo8cmVjdCB4PSI0NzAiIHk9IjE2IiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjExNiIgcng9IjEyIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjYyMCIgeT0iNDciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmaWxsOiNmMWY1Zjk7Zm9udDoxNHB4IHNhbnMtc2VyaWYiPk9uZSBDb3Ntb3MgbG9naWNhbCBwYXJ0aXRpb248L3RleHQ+Cjx0ZXh0IHg9IjYyMCIgeT0iNzUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmaWxsOiM5NGEzYjg7Zm9udDoxMnB4IHNhbnMtc2VyaWYiPmdyb3VwICsgYm9keSArIGRlZHVwbGljYXRpb24gKyByZWNlaXB0PC90ZXh0Pgo8dGV4dCB4PSI2MjAiIHk9IjEwMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZpbGw6IzZlZTdiNztmb250OjEycHggc2Fucy1zZXJpZiI+Y29tbWl0IHRvZ2V0aGVyIG9yIGxlYXZlIG5vIGFjY2VwdGVkIHNlbmQ8L3RleHQ+Cjwvc3ZnPg==)

#### Send, duplicate suppression and uncertain results

A partition-local procedure validates the queue generation, chooses the explicit MessageDeduplicationId or the SHA-256 body hash when content-based deduplication is enabled, and checks its five-minute expiry. Missing both forms is rejected. A live marker returns the original MessageId and SequenceNumber without another enqueue, including after the original message was consumed.

A new send writes message, marker and next group sequence in one transaction. There is no reserved sequence without its message. Database-side acceptance time determines expiry; TTL only removes state after its logical lifetime. A lost response after commit is uncertain until the same effective deduplication identity resolves it. Never retry with a new ID merely because the network timed out.

Batch sends split into same-partition chunks within transaction byte/operation limits, returning a result per entry. Some entries can commit while others fail; the entire SQS batch is not one transaction.

#### Ordered receive, durable receipts and batch restrictions

Receive transactionally claims the earliest eligible group prefix and records member receipt tokens, deadlines, receive counts and attempt identity. A later message cannot pass an earlier unavailable head. Independent groups can progress concurrently; one hot group still serializes. MessageGroup partitioning selects one group per receive, up to the overall ten-message budget.

Receipt handles identify the queue incarnation, purge generation and current claim. An adapter restart does not discard them. Delete settles only that exact claim; visibility changes update only its member. A stale receipt cannot delete a newer delivery. Visibility uses stored state, without a broker's five-minute lock ceiling; normal SQS validation and retention still apply. A consumer can keep executing after expiration, so external effects must remain idempotent.

The conservative batch protocol waits until all unsettled members have settled or expired before redelivery. It does not interleave a redelivery batch with still-live members. That reduces availability when visibility deadlines differ. In Queue scope, an unchanged ReceiveRequestAttemptId can replay its original set for five minutes, reset visibility and avoid incrementing the receive count. A modified or replaced claim requires a new attempt and returns an explicit unsupported result. MessageGroup scope rejects explicit attempt IDs before claiming because there is no cross-partition attempt coordinator. These are material differences from an unrestricted SQS batch/replay contract.

#### Persistent queue management and total cost

Cloud Adapter retains a persistent PostgreSQL store for the queue catalog, tenancy and lifecycle/control state, normally shared with the Cloud Adapter deployment. Native broker or Cosmos message storage does not remove this resource. Include its allocated compute, storage, backups and selected HA costs alongside adapter and message-backend charges; an idle or serverless message backend does not imply a zero total installation floor. Backend-only curves omit these shared allocations unless their assumptions explicitly include them.

This control store is distinct from the SQS-owned message database. PostgreSQL-authority FIFO composites add recoverable message bodies, receipts, deduplication and outbox state to an explicitly configured SQS message database; they do not store messages in the shared control catalog. A separate logical database and login provide data/permission separation, but still share server CPU, storage, IOPS, WAL and connection limits when hosted on the same instance. Dedicated physical server/instance capacity is a separate allocation and cost decision.

#### Cosmos capacity and partition choice

Serverless charges consumed request units and suits idle-heavy queues. Manual provisioned throughput suits steady demand; autoscale suits varying provisioned demand. They use the same queue protocol, with different configured RU budgets and minimum charges. Changing RU capacity does not remove transaction, document-size, hot-partition or retained-storage constraints. Throttling and retry-after consume the caller's time budget.

The transactional FIFO design chooses its deduplication scope explicitly. Queue-wide dedup keeps all groups, messages, attempts and markers in one logical partition so one server-side transaction can accept a send atomically. MessageGroup scope partitions by group only when that scope is explicitly requested. It must never silently weaken queue-wide duplicate suppression. A logical partition's 20-GB storage ceiling applies to the whole queue in Queue scope and to the busiest group in MessageGroup scope, including payload, indexes, markers, attempts, terminal evidence and cleanup lag. RU upgrades do not raise that ceiling; serverless can have a lower usable RU budget.

Admission validates the actual serialized body, attributes and transaction overhead before effects. The existing article's declared payload limit is distinct from the larger-body transactional design: the latter must fit the complete 2-MB/100-operation same-partition transaction budget. It never truncates an oversized transaction or splits one atomic acceptance into an unsafe marker-then-body sequence.

Compute cost from observed RU per successful operation plus conditional conflicts, retries, count queries, empty polls and cleanup; include stored bytes and the selected capacity floor. Missing body/attribute sizes, backlog, hottest-group fraction or measured index overhead leave storage/RU fit unknown. Serverless-to-provisioned conversion affects the account and is irreversible; it requires an explicit resource decision.

#### Transactional Cosmos FIFO and lifecycle

A bounded server-side procedure validates the partition generation, finds or replaces the dedup marker, allocates sequence and inserts the message atomically. A five-minute duplicate echoes the original IDs even after the message is deleted. TTL performs cleanup; explicit stored expiry decides deduplication and receipt eligibility. Receive conditionally claims the earliest eligible sequence, and Delete advances the group only for its exact receipt generation. This design differs from a collection of independent marker/head updates.

Queue-scope attempts fit inside that same partition and use conservative ordered-batch/replay behavior. MessageGroup scope serves one group per receive, up to ten ordered members, and rejects explicit ReceiveRequestAttemptId before claims because there is no cross-partition replay coordinator. Cross-partition dead-letter transfer/redrive is unsupported; sharing a Cosmos account does not make it atomic.

Queue-scope purge changes its local generation. Group-partitioned purge closes group registration, durably freezes every registered partition and only then opens the next generation. Interrupted work resumes from its saved progress and can reduce availability; success is not returned halfway. Dedup history survives purge until its original expiry. Delete permanently retires the incarnation, and recreate uses another one, so a delayed initializer, receipt or cleanup task cannot operate on the replacement queue.

#### Deployment, security and application changes

Provision the account, database, containers, indexes and versioned bounded server procedures explicitly. Validate their actual consistency, partition layout, capacity and credentials; a data credential does not confer management permission. The adapter uses the customer's workload identity and TLS to the configured Cosmos endpoint. Isolate tenant/account and queue identity in stored keys and authorization.

Retention is checked from durable acceptance/expiry state. Cleanup cannot erase a body still needed for valid response replay. Count observations require their own supported query and can lag concurrent sends, settlement and expiry; configured capacity and cached counts are not a throughput measurement.

Queues start empty. Drain each source group before cutover, keep stable dedup IDs on uncertain retries and handle per-entry batch failures. Select another backend if the application requires cross-partition atomic dead-letter moves, explicit receive-attempt replay in group-partitioned mode, or retained bytes above the authoritative partition's limit. Increasing RU or consumer count cannot remove these 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.

##### SQS FIFO · SQS request billing units

Feature: SQS FIFO.

Estimated monthly service charges by SQS request billing units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: East US; currency: USD.

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/06bc831a6318c02d7f0a5318b1a7f92ccbb8128f16bbbf322171d3029aa11e02-light.svg)

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/e86c8026f4d8d5aaaf400559783cdafebf4ddcbb2fe4d79a5ccd9c8f319d4b0b-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.

| SQS request billing units (per second) | SQS (Simple Queue Service, FIFO queues) | Azure Cosmos DB (queue) | Difference |
| -: | -: | -: | -: |
| 0 | 0.00 | 23.36 | 23.36 |
| 1 | 1.31 | 23.36 | 22.05 |
| 10 | 13.14 | 23.36 | 10.22 |
| 100 | 131.40 | 140.16 | 8.76 |
| 1,000 | 1,314.00 | 1,366.56 | 52.56 |
| 10,000 | 13,140.00 | 13,630.61 | 490.61 |

**Curve assumptions**

| Assumption | Value | Unit |
| - | -: | - |
| Origin list price · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Representative message size | 1,024 | bytes |
| Origin send batch fill | 1 | messages/request |
| Origin receive batch fill | 1 | messages/request |
| Origin delete batch fill | 1 | messages/request |
| Deliveries per message | 1 | attempts |
| Empty receive calls per message | 0 | requests |
| Queue residence window | 60 | seconds |
| Ordering and dedup work multiplier | 2 | multiplier |
| 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 price guess · 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 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 |
| 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 |

* 1-KiB messages, unbatched send/receive/delete; actual batch and delivery assumptions stay visible. 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 → East US, 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.
* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.
* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.
* Azure Cosmos DB provisioned throughput bills 100-RU/s blocks per hour and stored GB-months; operations within the provisioned RU/s have no separate charge. Blocks are sized from the family's reads at 1 RU and writes at 5.5 RU (1 KB items, no extra indexing) at full utilization after the planning peak factor, with the 400 RU/s smallest manual allocation as the floor (USD 23.36/month). Larger messages, indexing and query-based receives raise the RU charge; autoscale (USD 0.012 per 100 RU/s-hour) and serverless (USD 0.25 per million RUs) are not selected.
* AWS Price List API, AWSQueueService offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json)
* 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-4f4f008a52eb766d518aa4f34d3302fdb02b1a67` / `2026-10-22.planning.2`. Curve: `workload-1`.

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

**SQS FIFO → Azure Cosmos DB (queue): 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: East US. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: SQS billing units | 0.00 |
| Target: Target retained physical data | 0.00 |
| Target: Additional broker replica storage | 0.00 |
| Target: Published bytes | 0.00 |
| Target: Delivered bytes | 0.00 |
| Target: Target native provider operations | 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 · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Representative message size | 1,024 | bytes |
| Origin send batch fill | 1 | messages/request |
| Origin receive batch fill | 1 | messages/request |
| Origin delete batch fill | 1 | messages/request |
| Deliveries per message | 1 | attempts |
| Empty receive calls per message | 0 | requests |
| Queue residence window | 60 | seconds |
| Ordering and dedup work multiplier | 2 | multiplier |
| 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 price guess · 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 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 |
| 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 |
| SQS billing units | 0 | 64-KiB request units |

* 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.

* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.

* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.

* Azure Cosmos DB provisioned throughput bills 100-RU/s blocks per hour and stored GB-months; operations within the provisioned RU/s have no separate charge. Blocks are sized from the family's reads at 1 RU and writes at 5.5 RU (1 KB items, no extra indexing) at full utilization after the planning peak factor, with the 400 RU/s smallest manual allocation as the floor (USD 23.36/month). Larger messages, indexing and query-based receives raise the RU charge; autoscale (USD 0.012 per 100 RU/s-hour) and serverless (USD 0.25 per million RUs) are not selected.

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

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

### PostgreSQL Flexible Server

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Dead-letter redrive | Dead-letter | Supported | Most usage | fires automatically once a message passes maxReceiveCount |
| Content/ID deduplication | FIFO | Supported | Most usage | both modes are served: an explicit MessageDeduplicationId takes precedence over the content hash (AWS's own rule), and a content-based queue derives a stable digest of the body. The message insert and deduplication marker share one transaction. A duplicate rolls back its new row and returns the original message identifiers |
| FIFO ordering | FIFO | Supported | Common | per-MessageGroupId strict order with one message in flight per group; each receive takes the oldest message of each group, the same contract as the portable and Cloud SQL FIFO tiers |
| Message attributes | Messages | Supported | Common | - |
| GetQueueAttributes | Queues | Supported | Most usage | reads queue attributes, including approximate message counts |
| GetQueueUrl | Queues | Supported | Most usage | resolves the queue by name |
| DeleteMessage | Send / receive | Supported | Common | resolves by receipt handle; a stale handle returns ReceiptHandleIsInvalid |
| DeleteMessageBatch | Send / receive | Supported | Common | returns the result for each entry |
| ReceiveMessage | Send / receive | Supported | Common | long-poll (WaitTimeSeconds) honored; one message in flight per MessageGroupId |
| SendMessage | Send / receive | Supported | Common | MessageGroupId required on send (the AWS FIFO rule); MD5 checksums match what your SDK verifies |
| SendMessageBatch | Send / receive | Supported | Common | up to 10 messages per call, each with its MessageGroupId; returns the result for each entry |
| ChangeMessageVisibility | Visibility | Supported | Common | resolves by receipt handle; a stale handle is rejected rather than silently succeeding |

#### PostgreSQL hosting

Microsoft operates PostgreSQL Flexible Server, including zone-redundant HA and point-in-time recovery backups. The adapter uses short-lived Microsoft Entra tokens as database passwords. Queue data stays outside the customer's Kubernetes cluster and survives its rebuild. One server and database hold all queues for the deployment, sharing capacity and maintenance; the default server size is fixed because SQS supplies no source instance size. Tensor9 operates the queue schema and adapter. Queues start empty; existing SQS messages are not migrated. Drain each message group before cutover to preserve order.

#### Persistent queue management and total cost

Cloud Adapter retains a persistent PostgreSQL store for the queue catalog, tenancy and lifecycle/control state, normally shared with the Cloud Adapter deployment. Native broker or Cosmos message storage does not remove this resource. Include its allocated compute, storage, backups and selected HA costs alongside adapter and message-backend charges; an idle or serverless message backend does not imply a zero total installation floor. Backend-only curves omit these shared allocations unless their assumptions explicitly include them.

This control store is distinct from the SQS-owned message database. PostgreSQL-authority FIFO composites add recoverable message bodies, receipts, deduplication and outbox state to an explicitly configured SQS message database; they do not store messages in the shared control catalog. A separate logical database and login provide data/permission separation, but still share server CPU, storage, IOPS, WAL and connection limits when hosted on the same instance. Dedicated physical server/instance capacity is a separate allocation and cost decision.

#### Database placement and recovery

Azure Database for PostgreSQL Flexible Server is the durable queue database in your Azure subscription. The adapter connects over TLS using short-lived Microsoft Entra database credentials. Microsoft operates the server; choose the required HA and backup configuration explicitly. AKS replacement does not replace the database. Server failover can interrupt connections and leave an in-progress commit's response uncertain, so consumers retain their ordinary redelivery and retry handling.

#### Capacity and queue workload

The default shared message database holds multiple queues, each with its own table. Dedicated physical server/instance capacity isolates compute and I/O from other server workloads; a separate logical database alone does not. HA changes recovery, commit latency and price rather than FIFO semantics. Neither choice creates an unlimited queue service. Size connection pools, storage, IOPS and WAL for accepted sends, receives, deletes, visibility changes, retries and cleanup together. Long polls wait outside database transactions.

The single-message receive mechanism below permits one message in flight per group. If a group takes T seconds from receive to settlement, its useful completion rate is bounded by roughly 1/T, even when other groups are idle. A larger MaxNumberOfMessages can collect heads from multiple groups; it does not create a ten-message pipeline within one group. Adding consumers or database CPU does not remove that serialization. Compare the separate ordered-batch design before selecting a workload that depends on within-group batching.

Requested live counts scan the message population even for a single requested counter. Frequent depth polling over a large backlog competes for database I/O and pool capacity; receipt classification can change index/heap work. Price those queries separately from sends and completed message cycles. A fall in depth can reflect purge, expiry or dead-letter transfer rather than application completion.

The portable Standard-queue benchmark does not establish the capacity of this host, its HA configuration or a FIFO workload. Payload sizes, active-group skew, settlement time, backlog growth and matched native measurements determine whether a proposed size fits. Missing measurements leave capacity unknown.

#### Retries, batches and application changes

The application keeps its SQS SDK and uses the adapter's configured endpoint and authentication. Backend IAM, database schema permissions and TLS identity belong to the deployment; an AWS ARN or policy is not automatically a target-cloud authorization grant. Scope identities to the customer resources and keep rotated credentials out of message bodies and receipt handles.

A batch response reports each entry separately. Retry only failed entries whose outcome is known; a request timeout can follow a committed send or delete. Keep the same effective deduplication ID on uncertain retries. Duplicate enqueue suppression does not make consumer side effects exactly once. SDK retries and adapter retries share one bounded deadline, with backoff for provider throttling. An expired observer deadline does not prove a still-running native operation was cancelled.

Visibility expiration permits another delivery while an earlier worker can still be executing. Consumers use idempotent writes, choose a visibility duration that covers normal processing and handle stale receipt errors. Retention can expire a message in flight. Queues start empty: drain the source before cutover, group by group. Queue recreation and purge must invalidate old claims independently of public names; data cleanup can continue after logical retirement. Database or broker backup is a resource recovery mechanism, not an automatic replay of application side effects.

#### PostgreSQL queue behavior

Your application keeps its SQS SDK and uses the authenticated Cloud Adapter endpoint configured for the install. The adapter performs `SendMessage` and `ReceiveMessage` in the SQS-owned PostgreSQL message database and returns SQS responses, error codes and MD5 checksums. Its message-data login is separate from other services and the shared control catalog.

Each queue is a PostgreSQL table with one row per message. Sending, receiving, deleting, delays, visibility, dead-letter delivery and message counts all work on those rows. FIFO queues add ordering by message group, per-group sequence numbers and duplicate detection. Consumers can still receive a message more than once.

![Before: on AWS the application's SQS SDK calls Amazon SQS. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS API with one PostgreSQL table per queue.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMuIEFmdGVyOiBpbiB0aGUgdGFyZ2V0IGNsb3VkIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggaW1wbGVtZW50cyB0aGUgU1FTIEFQSSB3aXRoIG9uZSBQb3N0Z3JlU1FMIHRhYmxlIHBlciBxdWV1ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyODgiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gU1FTPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiNjYmQ1ZTEiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI3NzQiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMXB4Ij5Qb3N0Z3JlczwvdGV4dD4KPHRleHQgeD0iNzc0IiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj50YWJsZSBwZXIgcXVldWU8L3RleHQ+Cjwvc3ZnPg==)

![Before: on AWS the application's SQS SDK calls Amazon SQS. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS API with one PostgreSQL table per queue.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMuIEFmdGVyOiBpbiB0aGUgdGFyZ2V0IGNsb3VkIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggaW1wbGVtZW50cyB0aGUgU1FTIEFQSSB3aXRoIG9uZSBQb3N0Z3JlU1FMIHRhYmxlIHBlciBxdWV1ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyODgiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gU1FTPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiM0NzU1NjkiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI3NzQiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMXB4Ij5Qb3N0Z3JlczwvdGV4dD4KPHRleHQgeD0iNzc0IiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij50YWJsZSBwZXIgcXVldWU8L3RleHQ+Cjwvc3ZnPg==)

The application keeps its SQS SDK. The adapter stores each queue in a PostgreSQL table.

#### Architecture

The adapter keeps all queue state in PostgreSQL, including messages and receipt handles, so adapter instances can restart or scale out without losing track of in-flight messages. On Cloud SQL and Azure Flexible Server it signs in with short-lived Cloud SQL IAM or Microsoft Entra tokens used as database passwords, so no static secret is stored.

When the stack is deployed, Tensor9 creates one database per Cloud Adapter deployment and one table per declared queue. Each row holds the message body and attributes, its message group, its visibility time, its receipt handle, its receive count and the time it was sent. A FIFO queue orders messages within each message group; each row's arrival position gives its sequence number. A dead-letter queue is another queue table, and a background task deletes messages older than the queue's retention period.

CloudNativePG, Cloud SQL for PostgreSQL, Azure Flexible Server and Scaleway use the same adapter code and tables. They differ in where the data lives: the managed servers run outside your Kubernetes cluster, while CloudNativePG runs inside it. See the rebuild limitation below.

![The adapter stores messages, receipt handles, receive counts and visibility times in PostgreSQL: one table per queue, and another table for each dead-letter queue. A background task removes messages past their retention. FIFO messages also store their message group and sequence number, and each group has at most one message in flight.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQ0IiB2aWV3Qm94PSIwIDAgODM2IDI0NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciBzdG9yZXMgbWVzc2FnZXMsIHJlY2VpcHQgaGFuZGxlcywgcmVjZWl2ZSBjb3VudHMgYW5kIHZpc2liaWxpdHkgdGltZXMgaW4gUG9zdGdyZVNRTDogb25lIHRhYmxlIHBlciBxdWV1ZSwgYW5kIGFub3RoZXIgdGFibGUgZm9yIGVhY2ggZGVhZC1sZXR0ZXIgcXVldWUuIEEgYmFja2dyb3VuZCB0YXNrIHJlbW92ZXMgbWVzc2FnZXMgcGFzdCB0aGVpciByZXRlbnRpb24uIEZJRk8gbWVzc2FnZXMgYWxzbyBzdG9yZSB0aGVpciBtZXNzYWdlIGdyb3VwIGFuZCBzZXF1ZW5jZSBudW1iZXIsIGFuZCBlYWNoIGdyb3VwIGhhcyBhdCBtb3N0IG9uZSBtZXNzYWdlIGluIGZsaWdodC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InFhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIyNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDYiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyNiIgeT0iNDQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNCIgeT0iMTA0IiB3aWR0aD0iOTYiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzIiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNzIiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjcyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTIwIiB5MT0iMTQyIiB4Mj0iMTUyIiB5Mj0iMTQyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjcWEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iMTU0IiB5PSIxMTIiIHdpZHRoPSIxNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjI0IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTNweCI+VGVuc29yOSBhZGFwdGVyPC90ZXh0Pgo8dGV4dCB4PSIyMjQiIHk9IjE1NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c3RhdGUgaW4gUG9zdGdyZVNRTDwvdGV4dD4KPGxpbmUgeDE9IjI5NiIgeTE9IjE0MiIgeDI9IjM2MCIgeTI9IjE0MiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3FhKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+Cjx0ZXh0IHg9IjMyOCIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+U1FMPC90ZXh0Pgo8dGV4dCB4PSIzMjgiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPnRva2VuIHNpZ24taW48L3RleHQ+CjxyZWN0IHg9IjM2NCIgeT0iNTgiIHdpZHRoPSI0NTYiIGhlaWdodD0iMTY0IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjU5MSIgeT0iODIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5Qb3N0Z3JlU1FMPC90ZXh0Pgo8dGV4dCB4PSI1OTEiIHk9Ijk4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNjQ3NDhiIj5vbmUgZGF0YWJhc2UgcGVyIGFwcGxpYW5jZSDCtyBvbmUgdGFibGUgcGVyIHF1ZXVlPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjExMCIgd2lkdGg9IjIwNiIgaGVpZ2h0PSI3NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0ODMiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+bWVzc2FnZSByb3dzPC90ZXh0Pgo8dGV4dCB4PSI0ODMiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm9uZSByb3cgcGVyIG1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQ4MyIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+Ym9keSDCtyBhdHRyaWJ1dGVzIMK3IHNlbmQgdGltZTwvdGV4dD4KPHJlY3QgeD0iNTk4IiB5PSIxMTAiIHdpZHRoPSIyMDYiIGhlaWdodD0iNzQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNzAxIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+RklGTyBncm91cHM8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5ncm91cCBpZCDCtyBzZXF1ZW5jZSBudW1iZXI8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjE5MiIgd2lkdGg9IjQzNiIgaGVpZ2h0PSIyMiIgcng9IjYiIHN0cm9rZS13aWR0aD0iMSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1OTgiIHk9IjIwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6OS41cHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPnNhbWUgYWRhcHRlciBvbiBldmVyeSBQb3N0Z3JlU1FMIGhvc3Q8L3RleHQ+Cjwvc3ZnPg==)

![The adapter stores messages, receipt handles, receive counts and visibility times in PostgreSQL: one table per queue, and another table for each dead-letter queue. A background task removes messages past their retention. FIFO messages also store their message group and sequence number, and each group has at most one message in flight.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQ0IiB2aWV3Qm94PSIwIDAgODM2IDI0NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciBzdG9yZXMgbWVzc2FnZXMsIHJlY2VpcHQgaGFuZGxlcywgcmVjZWl2ZSBjb3VudHMgYW5kIHZpc2liaWxpdHkgdGltZXMgaW4gUG9zdGdyZVNRTDogb25lIHRhYmxlIHBlciBxdWV1ZSwgYW5kIGFub3RoZXIgdGFibGUgZm9yIGVhY2ggZGVhZC1sZXR0ZXIgcXVldWUuIEEgYmFja2dyb3VuZCB0YXNrIHJlbW92ZXMgbWVzc2FnZXMgcGFzdCB0aGVpciByZXRlbnRpb24uIEZJRk8gbWVzc2FnZXMgYWxzbyBzdG9yZSB0aGVpciBtZXNzYWdlIGdyb3VwIGFuZCBzZXF1ZW5jZSBudW1iZXIsIGFuZCBlYWNoIGdyb3VwIGhhcyBhdCBtb3N0IG9uZSBtZXNzYWdlIGluIGZsaWdodC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InFhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIyNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDYiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyNiIgeT0iNDQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNCIgeT0iMTA0IiB3aWR0aD0iOTYiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzIiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNzIiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjcyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTIwIiB5MT0iMTQyIiB4Mj0iMTUyIiB5Mj0iMTQyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjcWEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iMTU0IiB5PSIxMTIiIHdpZHRoPSIxNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjI0IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTNweCI+VGVuc29yOSBhZGFwdGVyPC90ZXh0Pgo8dGV4dCB4PSIyMjQiIHk9IjE1NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c3RhdGUgaW4gUG9zdGdyZVNRTDwvdGV4dD4KPGxpbmUgeDE9IjI5NiIgeTE9IjE0MiIgeDI9IjM2MCIgeTI9IjE0MiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3FhKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+Cjx0ZXh0IHg9IjMyOCIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+U1FMPC90ZXh0Pgo8dGV4dCB4PSIzMjgiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPnRva2VuIHNpZ24taW48L3RleHQ+CjxyZWN0IHg9IjM2NCIgeT0iNTgiIHdpZHRoPSI0NTYiIGhlaWdodD0iMTY0IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjU5MSIgeT0iODIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5Qb3N0Z3JlU1FMPC90ZXh0Pgo8dGV4dCB4PSI1OTEiIHk9Ijk4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojOTRhM2I4Ij5vbmUgZGF0YWJhc2UgcGVyIGFwcGxpYW5jZSDCtyBvbmUgdGFibGUgcGVyIHF1ZXVlPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjExMCIgd2lkdGg9IjIwNiIgaGVpZ2h0PSI3NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0ODMiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+bWVzc2FnZSByb3dzPC90ZXh0Pgo8dGV4dCB4PSI0ODMiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm9uZSByb3cgcGVyIG1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQ4MyIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+Ym9keSDCtyBhdHRyaWJ1dGVzIMK3IHNlbmQgdGltZTwvdGV4dD4KPHJlY3QgeD0iNTk4IiB5PSIxMTAiIHdpZHRoPSIyMDYiIGhlaWdodD0iNzQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNzAxIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+RklGTyBncm91cHM8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5ncm91cCBpZCDCtyBzZXF1ZW5jZSBudW1iZXI8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjE5MiIgd2lkdGg9IjQzNiIgaGVpZ2h0PSIyMiIgcng9IjYiIHN0cm9rZS13aWR0aD0iMSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1OTgiIHk9IjIwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6OS41cHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPnNhbWUgYWRhcHRlciBvbiBldmVyeSBQb3N0Z3JlU1FMIGhvc3Q8L3RleHQ+Cjwvc3ZnPg==)

Each queue, including each dead-letter queue, is a PostgreSQL table. The same adapter runs on every supported PostgreSQL host.

#### Receiving messages

One database step selects messages whose visibility timeout has passed, oldest first, up to the requested batch size. In the same step it gives each a new receipt handle, hides it for the visibility timeout, adds one to its receive count and returns it. Messages another receiver is taking at that moment are skipped. FIFO queues return the next eligible message in each group, keeping one in flight per group. When the visibility timeout passes, the message can be delivered again; that does not stop a worker still processing the earlier copy.

`ApproximateReceiveCount` is the actual number of receives, not an estimate. The MD5 checksums of the body and attributes are recomputed, so your SDK's checks pass. `DelaySeconds` sets when a message first becomes visible. Long polling waits up to `WaitTimeSeconds` (at most 20 seconds) and returns as soon as a message is available. `SendMessageBatch` inserts all entries at once and reports a result for each entry. Message bodies are stored in the queue table.

![A receive takes the oldest visible messages and, in the same step, gives each a new receipt handle, hides it for the visibility timeout and adds one to its receive count. Two receivers at the same time get different messages. A message can be delivered again once its visibility timeout passes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIHJlY2VpdmUgdGFrZXMgdGhlIG9sZGVzdCB2aXNpYmxlIG1lc3NhZ2VzIGFuZCwgaW4gdGhlIHNhbWUgc3RlcCwgZ2l2ZXMgZWFjaCBhIG5ldyByZWNlaXB0IGhhbmRsZSwgaGlkZXMgaXQgZm9yIHRoZSB2aXNpYmlsaXR5IHRpbWVvdXQgYW5kIGFkZHMgb25lIHRvIGl0cyByZWNlaXZlIGNvdW50LiBUd28gcmVjZWl2ZXJzIGF0IHRoZSBzYW1lIHRpbWUgZ2V0IGRpZmZlcmVudCBtZXNzYWdlcy4gQSBtZXNzYWdlIGNhbiBiZSBkZWxpdmVyZWQgYWdhaW4gb25jZSBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0IHBhc3Nlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0icmEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJyZyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojMDQ3ODU3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPkZpbmQgdmlzaWJsZSBtZXNzYWdlczwvdGV4dD4KPHRleHQgeD0iNzYiIHk9Ijc5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+PHRzcGFuIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnZpc2libGUgbm93PC90c3Bhbj4gwrcgb2xkZXN0IGZpcnN0PC90ZXh0Pgo8bGluZSB4MT0iMjAwIiB5MT0iOTAiIHgyPSIyMDAiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI3JhKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIzMDAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlNraXAgbWVzc2FnZXMgaW4gdXNlPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMTUzIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dGFrZW4gYnkgYW5vdGhlciByZWNlaXZlcjwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9IjE2NCIgeDI9IjIwMCIgeTI9IjE4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjcmEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEycHgiPkhhbmQgb3V0IGluIHRoZSBzYW1lIHN0ZXA8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIyMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPm5ldyByZWNlaXB0IGhhbmRsZSDCtyBoaWRkZW48dHNwYW4geD0iNzYiIGR5PSIxMiI+cmVjZWl2ZSBjb3VudCArIDE8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iMzg4IiB5PSI0MiIgd2lkdGg9IjQyNCIgaGVpZ2h0PSIxOTYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjAwIiB5PSI2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+VFdPIENPTkNVUlJFTlQgUkVDRUlWRVJTPC90ZXh0Pgo8cmVjdCB4PSI0MDQiIHk9Ijc4IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjI0IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0NzkiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEEgZ2V0cyBtMTwvdGV4dD4KPHJlY3QgeD0iNDA0IiB5PSIxMDgiIHdpZHRoPSIxNTAiIGhlaWdodD0iMjQiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjQ3OSIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEIgZ2V0cyBtMjwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSI3OCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz48dGV4dCB4PSI2MTIiIHk9IjkzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5tMSAgaW4gZmxpZ2h0IChBKTwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxMDQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+PHRleHQgeD0iNjEyIiB5PSIxMTkiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPm0yICBpbiBmbGlnaHQgKEIpPC90ZXh0Pgo8cmVjdCB4PSI2MDAiIHk9IjEzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz48dGV4dCB4PSI2MTIiIHk9IjE0NSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzY0NzQ4YiI+bTMgIHZpc2libGUgwrcgbmV4dDwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxNTYiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+PHRleHQgeD0iNjEyIiB5PSIxNzEiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiM2NDc0OGIiPm00ICB2aXNpYmxlIMK3IG5leHQ8L3RleHQ+CjxsaW5lIHgxPSI1NTYiIHkxPSI5MCIgeDI9IjU5NiIgeTI9Ijg4IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8bGluZSB4MT0iNTU2IiB5MT0iMTIwIiB4Mj0iNTk2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSI0MDQiIHk9IjE5NiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzMCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjYwMCIgeT0iMjE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmVhY2ggcmVjZWl2ZXIgZ2V0cyBkaWZmZXJlbnQgbWVzc2FnZXM8L3RleHQ+Cjwvc3ZnPg==)

![A receive takes the oldest visible messages and, in the same step, gives each a new receipt handle, hides it for the visibility timeout and adds one to its receive count. Two receivers at the same time get different messages. A message can be delivered again once its visibility timeout passes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIHJlY2VpdmUgdGFrZXMgdGhlIG9sZGVzdCB2aXNpYmxlIG1lc3NhZ2VzIGFuZCwgaW4gdGhlIHNhbWUgc3RlcCwgZ2l2ZXMgZWFjaCBhIG5ldyByZWNlaXB0IGhhbmRsZSwgaGlkZXMgaXQgZm9yIHRoZSB2aXNpYmlsaXR5IHRpbWVvdXQgYW5kIGFkZHMgb25lIHRvIGl0cyByZWNlaXZlIGNvdW50LiBUd28gcmVjZWl2ZXJzIGF0IHRoZSBzYW1lIHRpbWUgZ2V0IGRpZmZlcmVudCBtZXNzYWdlcy4gQSBtZXNzYWdlIGNhbiBiZSBkZWxpdmVyZWQgYWdhaW4gb25jZSBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0IHBhc3Nlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0icmEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJyZyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNmVlN2I3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPkZpbmQgdmlzaWJsZSBtZXNzYWdlczwvdGV4dD4KPHRleHQgeD0iNzYiIHk9Ijc5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+PHRzcGFuIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnZpc2libGUgbm93PC90c3Bhbj4gwrcgb2xkZXN0IGZpcnN0PC90ZXh0Pgo8bGluZSB4MT0iMjAwIiB5MT0iOTAiIHgyPSIyMDAiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI3JhKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIzMDAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlNraXAgbWVzc2FnZXMgaW4gdXNlPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMTUzIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dGFrZW4gYnkgYW5vdGhlciByZWNlaXZlcjwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9IjE2NCIgeDI9IjIwMCIgeTI9IjE4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjcmEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEycHgiPkhhbmQgb3V0IGluIHRoZSBzYW1lIHN0ZXA8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIyMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPm5ldyByZWNlaXB0IGhhbmRsZSDCtyBoaWRkZW48dHNwYW4geD0iNzYiIGR5PSIxMiI+cmVjZWl2ZSBjb3VudCArIDE8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iMzg4IiB5PSI0MiIgd2lkdGg9IjQyNCIgaGVpZ2h0PSIxOTYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjAwIiB5PSI2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+VFdPIENPTkNVUlJFTlQgUkVDRUlWRVJTPC90ZXh0Pgo8cmVjdCB4PSI0MDQiIHk9Ijc4IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjI0IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0NzkiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEEgZ2V0cyBtMTwvdGV4dD4KPHJlY3QgeD0iNDA0IiB5PSIxMDgiIHdpZHRoPSIxNTAiIGhlaWdodD0iMjQiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjQ3OSIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEIgZ2V0cyBtMjwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSI3OCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz48dGV4dCB4PSI2MTIiIHk9IjkzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5tMSAgaW4gZmxpZ2h0IChBKTwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxMDQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+PHRleHQgeD0iNjEyIiB5PSIxMTkiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPm0yICBpbiBmbGlnaHQgKEIpPC90ZXh0Pgo8cmVjdCB4PSI2MDAiIHk9IjEzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz48dGV4dCB4PSI2MTIiIHk9IjE0NSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6Izk0YTNiOCI+bTMgIHZpc2libGUgwrcgbmV4dDwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxNTYiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+PHRleHQgeD0iNjEyIiB5PSIxNzEiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM5NGEzYjgiPm00ICB2aXNpYmxlIMK3IG5leHQ8L3RleHQ+CjxsaW5lIHgxPSI1NTYiIHkxPSI5MCIgeDI9IjU5NiIgeTI9Ijg4IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8bGluZSB4MT0iNTU2IiB5MT0iMTIwIiB4Mj0iNTk2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSI0MDQiIHk9IjE5NiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzMCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjYwMCIgeT0iMjE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmVhY2ggcmVjZWl2ZXIgZ2V0cyBkaWZmZXJlbnQgbWVzc2FnZXM8L3RleHQ+Cjwvc3ZnPg==)

Two receivers never get the same message at the same time. ApproximateReceiveCount is the actual receive count.

#### Receipt handles & visibility

Each receive saves a new receipt handle with the message. `DeleteMessage` and `ChangeMessageVisibility` find the message by that handle, including after an adapter restart or through another adapter instance.

A delete or visibility change whose handle matches no message returns `ReceiptHandleIsInvalid`. That includes a message already deleted, or received again under a newer handle. The visibility timeout defaults to 30 seconds. `ChangeMessageVisibility` can extend it with no lock-duration maximum, and zero makes the message available again immediately. Retention can delete a message while it is in flight.

![The receipt handle is saved with the message in PostgreSQL and survives adapter restart. Visibility uses a stored deadline within SQS bounds, without a broker lock ceiling.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgcmVjZWlwdCBoYW5kbGUgaXMgc2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMIGFuZCBzdXJ2aXZlcyBhZGFwdGVyIHJlc3RhcnQuIFZpc2liaWxpdHkgdXNlcyBhIHN0b3JlZCBkZWFkbGluZSB3aXRoaW4gU1FTIGJvdW5kcywgd2l0aG91dCBhIGJyb2tlciBsb2NrIGNlaWxpbmcuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InZhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIyNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzA0Nzg1NyI+UkVDRUlQVCBIQU5ETEVTIFNVUlZJVkUgUkVTVEFSVFM8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSIzOCIgd2lkdGg9IjM2MCIgaGVpZ2h0PSIxNDIiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMzI0IiBoZWlnaHQ9IjM0IiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMjA2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+cmVjZWlwdCBoYW5kbGUgPSAzZjJh4oCmLTkxYTI8L3RleHQ+Cjx0ZXh0IHg9IjIwNiIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+c2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMPC90ZXh0Pgo8bGluZSB4MT0iMjA2IiB5MT0iMTIwIiB4Mj0iMjA2IiB5Mj0iMTM2IiBzdHJva2Utd2lkdGg9IjEuNiIgc3Ryb2tlLWRhc2hhcnJheT0iMyAzIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iMjA2IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+YWRhcHRlciByZXN0YXJ0czwvdGV4dD4KPHRleHQgeD0iMjA2IiB5PSIxNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+RGVsZXRlTWVzc2FnZSBhbmQgQ2hhbmdlTWVzc2FnZVZpc2liaWxpdHkgc3RpbGwgd29yazwvdGV4dD4KPGxpbmUgeDE9IjM5OCIgeTE9IjM0IiB4Mj0iMzk4IiB5Mj0iMTg0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQyNCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPk5PIFZJU0lCSUxJVFkgQ0FQPC90ZXh0Pgo8cmVjdCB4PSI0MjQiIHk9IjM4IiB3aWR0aD0iMzg2IiBoZWlnaHQ9IjE0MiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8bGluZSB4MT0iNDQ2IiB5MT0iMTA0IiB4Mj0iODA2IiB5Mj0iMTA0IiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6I2NiZDVlMSIvPgo8cmVjdCB4PSI0NDYiIHk9Ijg4IiB3aWR0aD0iNzgiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNhN2YzZDA7c3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNTI4IiB5PSI4OCIgd2lkdGg9Ijc4IiBoZWlnaHQ9IjE4IiByeD0iNCIgc3Ryb2tlLXdpZHRoPSIxIiBzdHlsZT0iZmlsbDojYTdmM2QwO3N0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjYxMCIgeT0iODgiIHdpZHRoPSIxMjAiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNDc4NTc7c3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjczNCIgeTE9Ijk3IiB4Mj0iODAwIiB5Mj0iOTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCN2YSkiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0ODQiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+dGltZW91dDwvdGV4dD4KPHRleHQgeD0iNTY2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNjY4IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNzcyIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZWQgdGltZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5DaGFuZ2VNZXNzYWdlVmlzaWJpbGl0eSB1cGRhdGVzIHRoZSBkZWFkbGluZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxNTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2NDc0OGIiPihubyBtZXNzYWdlLWxvY2sgdGltZSBsaW1pdCk8L3RleHQ+Cjwvc3ZnPg==)

![The receipt handle is saved with the message in PostgreSQL and survives adapter restart. Visibility uses a stored deadline within SQS bounds, without a broker lock ceiling.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgcmVjZWlwdCBoYW5kbGUgaXMgc2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMIGFuZCBzdXJ2aXZlcyBhZGFwdGVyIHJlc3RhcnQuIFZpc2liaWxpdHkgdXNlcyBhIHN0b3JlZCBkZWFkbGluZSB3aXRoaW4gU1FTIGJvdW5kcywgd2l0aG91dCBhIGJyb2tlciBsb2NrIGNlaWxpbmcuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InZhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIyNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzZlZTdiNyI+UkVDRUlQVCBIQU5ETEVTIFNVUlZJVkUgUkVTVEFSVFM8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSIzOCIgd2lkdGg9IjM2MCIgaGVpZ2h0PSIxNDIiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMzI0IiBoZWlnaHQ9IjM0IiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjA2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+cmVjZWlwdCBoYW5kbGUgPSAzZjJh4oCmLTkxYTI8L3RleHQ+Cjx0ZXh0IHg9IjIwNiIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+c2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMPC90ZXh0Pgo8bGluZSB4MT0iMjA2IiB5MT0iMTIwIiB4Mj0iMjA2IiB5Mj0iMTM2IiBzdHJva2Utd2lkdGg9IjEuNiIgc3Ryb2tlLWRhc2hhcnJheT0iMyAzIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iMjA2IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+YWRhcHRlciByZXN0YXJ0czwvdGV4dD4KPHRleHQgeD0iMjA2IiB5PSIxNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+RGVsZXRlTWVzc2FnZSBhbmQgQ2hhbmdlTWVzc2FnZVZpc2liaWxpdHkgc3RpbGwgd29yazwvdGV4dD4KPGxpbmUgeDE9IjM5OCIgeTE9IjM0IiB4Mj0iMzk4IiB5Mj0iMTg0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQyNCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPk5PIFZJU0lCSUxJVFkgQ0FQPC90ZXh0Pgo8cmVjdCB4PSI0MjQiIHk9IjM4IiB3aWR0aD0iMzg2IiBoZWlnaHQ9IjE0MiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8bGluZSB4MT0iNDQ2IiB5MT0iMTA0IiB4Mj0iODA2IiB5Mj0iMTA0IiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6IzQ3NTU2OSIvPgo8cmVjdCB4PSI0NDYiIHk9Ijg4IiB3aWR0aD0iNzgiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNDc4NTc7c3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNTI4IiB5PSI4OCIgd2lkdGg9Ijc4IiBoZWlnaHQ9IjE4IiByeD0iNCIgc3Ryb2tlLXdpZHRoPSIxIiBzdHlsZT0iZmlsbDojMDQ3ODU3O3N0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjYxMCIgeT0iODgiIHdpZHRoPSIxMjAiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiM2ZWU3Yjc7c3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjczNCIgeTE9Ijk3IiB4Mj0iODAwIiB5Mj0iOTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCN2YSkiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI0ODQiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+dGltZW91dDwvdGV4dD4KPHRleHQgeD0iNTY2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNjY4IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNzcyIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZWQgdGltZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5DaGFuZ2VNZXNzYWdlVmlzaWJpbGl0eSB1cGRhdGVzIHRoZSBkZWFkbGluZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxNTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM5NGEzYjgiPihubyBtZXNzYWdlLWxvY2sgdGltZSBsaW1pdCk8L3RleHQ+Cjwvc3ZnPg==)

Receipt handles are saved with messages, so they still work after an adapter restart. Visibility has no lock-duration limit.

#### Dead-letter & retention

When source and DLQ belong to the same supported SQS-owned message database transaction, receive moves messages at `maxReceiveCount` atomically with claiming the rest. Both changes commit or neither does. Cross-database/store transfers are unsupported: sharing a provider, physical server or control log is not a shared message transaction, and no other service's tables are used. The DLQ retains ordinary queue operations and cleanup. A FIFO move creates a new message in the DLQ, with a new `MessageId`, a receive count of zero and a new send time.

A background task deletes messages sent longer ago than the queue's retention period, including messages in flight; receiving does not reset that time. The retention period defaults to four days and is kept between 60 seconds and 14 days, so a missing or too-short value cannot delete new messages straight away. One worker per database removes expired messages in batches, pauses during database maintenance, and continues if one queue fails. Limits on rows per pass and time per batch cap the load.

![Within the same supported SQS-owned message database transaction, receive moves exhausted messages to the DLQ and hands out the rest. Cross-database/store moves are unsupported. Background cleanup enforces retention; consumers still tolerate redelivery.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJXaXRoaW4gdGhlIHNhbWUgc3VwcG9ydGVkIFNRUy1vd25lZCBtZXNzYWdlIGRhdGFiYXNlIHRyYW5zYWN0aW9uLCByZWNlaXZlIG1vdmVzIGV4aGF1c3RlZCBtZXNzYWdlcyB0byB0aGUgRExRIGFuZCBoYW5kcyBvdXQgdGhlIHJlc3QuIENyb3NzLWRhdGFiYXNlL3N0b3JlIG1vdmVzIGFyZSB1bnN1cHBvcnRlZC4gQmFja2dyb3VuZCBjbGVhbnVwIGVuZm9yY2VzIHJldGVudGlvbjsgY29uc3VtZXJzIHN0aWxsIHRvbGVyYXRlIHJlZGVsaXZlcnkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImRhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2RjMjYyNiIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5ERUFELUxFVFRFUiBNT1ZFIElOIE9ORSBUUkFOU0FDVElPTjwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjEwMSIgeT0iNTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTFweCI+bWVzc2FnZXMgZHVlPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5vbmUgdHJhbnNhY3Rpb248L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI1MCIgeDI9IjIxMiIgeTI9IjUwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNkeCkiIHN0eWxlPSJzdHJva2U6I2RjMjYyNiIvPgo8dGV4dCB4PSIxOTQiIHk9IjQzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZmlsbDojZGMyNjI2Ij7iiaUgbWF4PC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNzQiIHgyPSIyMTIiIHkyPSI3NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZGEpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMTk0IiB5PSI5MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+Jmx0OyBtYXg8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iMzIiIHdpZHRoPSIyMjIiIGhlaWdodD0iMzIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2ZmZmJlYjtzdHJva2U6I2ZkZTY4YSIvPgo8dGV4dCB4PSIzMjUiIHk9IjUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTFweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2I0NTMwOSI+bW92ZSB0byBkZWFkLWxldHRlciBxdWV1ZTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI2NiIgd2lkdGg9IjIyMiIgaGVpZ2h0PSIzMCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjMyNSIgeT0iODUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+cmV0dXJuZWQgdG8gdGhlIHJlY2VpdmVyPC90ZXh0Pgo8cmVjdCB4PSI0NTIiIHk9IjMyIiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjY0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjYzMSIgeT0iNTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTFweCI+b25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI2MzEiIHk9Ijc5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPm1vdmUgYW5kIHJlY2VpdmUgc3VjY2VlZCB0b2dldGhlcjwvdGV4dD4KPHRleHQgeD0iMjYiIHk9IjEyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+UkVURU5USU9OIENMRUFOVVAgwrcgT04gU0VORCBUSU1FPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTM4IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+CjxyZWN0IHg9IjYwIiB5PSIxNjYiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNmZWYyZjI7c3Ryb2tlOiNkYzI2MjYiLz4KPHJlY3QgeD0iNDIwIiB5PSIxNjYiIHdpZHRoPSIzNTAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjQyMCIgeTE9IjE1NiIgeDI9IjQyMCIgeTI9IjE5OCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQgMyIgc3R5bGU9InN0cm9rZTojMzM0MTU1Ii8+Cjx0ZXh0IHg9IjQyMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMzM0MTU1Ij5ub3cg4oiSIHJldGVudGlvbjwvdGV4dD4KPHRleHQgeD0iMjQwIiB5PSIxODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiNkYzI2MjYiPnNlbmQgdGltZSBiZWZvcmUgY3V0b2ZmIOKGkiByZW1vdmVkPC90ZXh0Pgo8dGV4dCB4PSI1OTUiIHk9IjE4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+d2l0aGluIHJldGVudGlvbiDihpIga2VwdDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5yZXRlbnRpb24gNjBzLTE0ZCDCtyBiYXRjaGVkIGNsZWFudXAgwrcgb25lIHdvcmtlciBwZXIgZGF0YWJhc2UgwrcgYmFja3Mgb2ZmIGR1cmluZyBtYWludGVuYW5jZTwvdGV4dD4KPC9zdmc+)

![Within the same supported SQS-owned message database transaction, receive moves exhausted messages to the DLQ and hands out the rest. Cross-database/store moves are unsupported. Background cleanup enforces retention; consumers still tolerate redelivery.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJXaXRoaW4gdGhlIHNhbWUgc3VwcG9ydGVkIFNRUy1vd25lZCBtZXNzYWdlIGRhdGFiYXNlIHRyYW5zYWN0aW9uLCByZWNlaXZlIG1vdmVzIGV4aGF1c3RlZCBtZXNzYWdlcyB0byB0aGUgRExRIGFuZCBoYW5kcyBvdXQgdGhlIHJlc3QuIENyb3NzLWRhdGFiYXNlL3N0b3JlIG1vdmVzIGFyZSB1bnN1cHBvcnRlZC4gQmFja2dyb3VuZCBjbGVhbnVwIGVuZm9yY2VzIHJldGVudGlvbjsgY29uc3VtZXJzIHN0aWxsIHRvbGVyYXRlIHJlZGVsaXZlcnkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImRhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2Y4NzE3MSIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5ERUFELUxFVFRFUiBNT1ZFIElOIE9ORSBUUkFOU0FDVElPTjwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjEwMSIgeT0iNTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTFweCI+bWVzc2FnZXMgZHVlPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5vbmUgdHJhbnNhY3Rpb248L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI1MCIgeDI9IjIxMiIgeTI9IjUwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNkeCkiIHN0eWxlPSJzdHJva2U6I2Y4NzE3MSIvPgo8dGV4dCB4PSIxOTQiIHk9IjQzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZmlsbDojZjg3MTcxIj7iiaUgbWF4PC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNzQiIHgyPSIyMTIiIHkyPSI3NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZGEpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMTk0IiB5PSI5MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+Jmx0OyBtYXg8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iMzIiIHdpZHRoPSIyMjIiIGhlaWdodD0iMzIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzQyMjAwNjtzdHJva2U6IzkyNDAwZSIvPgo8dGV4dCB4PSIzMjUiIHk9IjUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTFweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2ZiYmYyNCI+bW92ZSB0byBkZWFkLWxldHRlciBxdWV1ZTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI2NiIgd2lkdGg9IjIyMiIgaGVpZ2h0PSIzMCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjMyNSIgeT0iODUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+cmV0dXJuZWQgdG8gdGhlIHJlY2VpdmVyPC90ZXh0Pgo8cmVjdCB4PSI0NTIiIHk9IjMyIiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjY0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjYzMSIgeT0iNTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTFweCI+b25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI2MzEiIHk9Ijc5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPm1vdmUgYW5kIHJlY2VpdmUgc3VjY2VlZCB0b2dldGhlcjwvdGV4dD4KPHRleHQgeD0iMjYiIHk9IjEyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+UkVURU5USU9OIENMRUFOVVAgwrcgT04gU0VORCBUSU1FPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTM4IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+CjxyZWN0IHg9IjYwIiB5PSIxNjYiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiM0NTBhMGE7c3Ryb2tlOiNmODcxNzEiLz4KPHJlY3QgeD0iNDIwIiB5PSIxNjYiIHdpZHRoPSIzNTAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjQyMCIgeTE9IjE1NiIgeDI9IjQyMCIgeTI9IjE5OCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQgMyIgc3R5bGU9InN0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQyMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZmlsbDojY2JkNWUxIj5ub3cg4oiSIHJldGVudGlvbjwvdGV4dD4KPHRleHQgeD0iMjQwIiB5PSIxODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNmODcxNzEiPnNlbmQgdGltZSBiZWZvcmUgY3V0b2ZmIOKGkiByZW1vdmVkPC90ZXh0Pgo8dGV4dCB4PSI1OTUiIHk9IjE4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+d2l0aGluIHJldGVudGlvbiDihpIga2VwdDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5yZXRlbnRpb24gNjBzLTE0ZCDCtyBiYXRjaGVkIGNsZWFudXAgwrcgb25lIHdvcmtlciBwZXIgZGF0YWJhc2UgwrcgYmFja3Mgb2ZmIGR1cmluZyBtYWludGVuYW5jZTwvdGV4dD4KPC9zdmc+)

Atomic DLQ moves require the same supported SQS-owned database transaction. Cross-store moves are unsupported. Retention cleanup removes aged messages.

#### FIFO ordering & dedup

A FIFO queue stores each message's `MessageGroupId` and orders delivery within each group. A receive returns only the oldest message of each group that has nothing in flight (no message in that group is currently received and still hidden). Because arrival positions only increase, that is always the group's next message, and exactly one message is in flight per group at a time. Groups are independent, so different receivers can process different groups at once, coordinated only by PostgreSQL. When a message's visibility timeout passes, it is first in its group again, so a redelivery stays in sequence.

Each FIFO send requires `MessageGroupId` and returns a `SequenceNumber`: the message's arrival position as a 20-digit, zero-padded number.

Deduplication markers live in a separate PostgreSQL table keyed by queue and deduplication ID. An explicit `MessageDeduplicationId` takes precedence; otherwise, on a queue with content-based deduplication, the key is the SHA-256 of the body, excluding attributes. The message insert and deduplication marker are part of one transaction. A duplicate within 5 minutes saves no new message and returns the original `MessageId` and `SequenceNumber`. Marker retention is independent of message retention, so receiving or deleting the original does not shorten the deduplication window.

While a message is in flight, no other message from its group is delivered until it is deleted or its visibility timeout passes. That does not stop a timed-out worker from finishing a message it already received, so consumers must make repeated processing safe.

![FIFO receives deliver the next message of each group that has nothing in flight. Each send returns a 20-digit, zero-padded sequence number. Explicit or content-based deduplication is recorded in a separate PostgreSQL table with a five-minute window; a repeated send returns the original message ID and sequence number.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJGSUZPIHJlY2VpdmVzIGRlbGl2ZXIgdGhlIG5leHQgbWVzc2FnZSBvZiBlYWNoIGdyb3VwIHRoYXQgaGFzIG5vdGhpbmcgaW4gZmxpZ2h0LiBFYWNoIHNlbmQgcmV0dXJucyBhIDIwLWRpZ2l0LCB6ZXJvLXBhZGRlZCBzZXF1ZW5jZSBudW1iZXIuIEV4cGxpY2l0IG9yIGNvbnRlbnQtYmFzZWQgZGVkdXBsaWNhdGlvbiBpcyByZWNvcmRlZCBpbiBhIHNlcGFyYXRlIFBvc3RncmVTUUwgdGFibGUgd2l0aCBhIGZpdmUtbWludXRlIHdpbmRvdzsgYSByZXBlYXRlZCBzZW5kIHJldHVybnMgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgSUQgYW5kIHNlcXVlbmNlIG51bWJlci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZnMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PUkRFUiBXSVRISU4gQSBHUk9VUDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQwIiB5PSI1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+bWVzc2FnZXMgb3JkZXJlZCB3aXRoaW4gZWFjaCBncm91cDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjcxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMzM0MTU1Ij5lYWNoIGdyb3VwJ3Mgb2xkZXN0IG1lc3NhZ2UsIGlmIG5vdGhpbmcgaW4gZmxpZ2h0ICDihpIgIGRlbGl2ZXJlZDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9Ijg3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U2VxdWVuY2VOdW1iZXI6IDIwIGRpZ2l0cywgemVyby1wYWRkZWQsIGFsd2F5cyBpbmNyZWFzaW5nPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQwIiB5PSIxMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgb3JkZXJzPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMDQ3ODU3Ij5tNDEgKGhlYWQsIGluIGZsaWdodCkgwrcgbTQyIMK3IG00MyDigKY8L3RleHQ+Cjx0ZXh0IHg9IjQwIiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vbmUgaW4gZmxpZ2h0IMK3IG00MiB3YWl0cyB1bnRpbCBtNDEgaXMgZGVsZXRlZCBvciB0aW1lcyBvdXQ8L3RleHQ+CjxyZWN0IHg9IjQzMCIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTIzIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmdyb3VwIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMDQ3ODU3Ij5tNTggKGhlYWQsIGluIGZsaWdodCkgwrcgbTU5IOKApjwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5ncm91cHMgYXJlIGNvbmN1cnJlbnQgwrcgYSBkaWZmZXJlbnQgcmVjZWl2ZXIgZHJhaW5zIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjI2IiB5PSIxOTAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNiNDUzMDkiPkRFRFVQTElDQVRJT04gwrcgNS1NSU5VVEUgV0lORE9XPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTk2IiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTUxIiB5PSIyMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPmV4cGxpY2l0IElEIG9yIFNIQS0yNTYoYm9keSk8L3RleHQ+CjxsaW5lIHgxPSIyNzYiIHkxPSIyMTYiIHgyPSIzMTIiIHkyPSIyMTYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZzKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjMxNCIgeT0iMTk2IiB3aWR0aD0iNDk2IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZiZWI7c3Ryb2tlOiNmZGU2OGEiLz4KPHRleHQgeD0iNTYyIiB5PSIyMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojYjQ1MzA5Ij5yZXBlYXQgcmV0dXJucyBvcmlnaW5hbCBJRHM8L3RleHQ+Cjx0ZXh0IHg9IjU2MiIgeT0iMjI5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojYjQ1MzA5Ij5tZXNzYWdlIGFuZCBkZWR1cCBtYXJrZXIgc2F2ZWQgdG9nZXRoZXI8L3RleHQ+Cjwvc3ZnPg==)

![FIFO receives deliver the next message of each group that has nothing in flight. Each send returns a 20-digit, zero-padded sequence number. Explicit or content-based deduplication is recorded in a separate PostgreSQL table with a five-minute window; a repeated send returns the original message ID and sequence number.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJGSUZPIHJlY2VpdmVzIGRlbGl2ZXIgdGhlIG5leHQgbWVzc2FnZSBvZiBlYWNoIGdyb3VwIHRoYXQgaGFzIG5vdGhpbmcgaW4gZmxpZ2h0LiBFYWNoIHNlbmQgcmV0dXJucyBhIDIwLWRpZ2l0LCB6ZXJvLXBhZGRlZCBzZXF1ZW5jZSBudW1iZXIuIEV4cGxpY2l0IG9yIGNvbnRlbnQtYmFzZWQgZGVkdXBsaWNhdGlvbiBpcyByZWNvcmRlZCBpbiBhIHNlcGFyYXRlIFBvc3RncmVTUUwgdGFibGUgd2l0aCBhIGZpdmUtbWludXRlIHdpbmRvdzsgYSByZXBlYXRlZCBzZW5kIHJldHVybnMgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgSUQgYW5kIHNlcXVlbmNlIG51bWJlci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZnMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PUkRFUiBXSVRISU4gQSBHUk9VUDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQwIiB5PSI1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+bWVzc2FnZXMgb3JkZXJlZCB3aXRoaW4gZWFjaCBncm91cDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjcxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojY2JkNWUxIj5lYWNoIGdyb3VwJ3Mgb2xkZXN0IG1lc3NhZ2UsIGlmIG5vdGhpbmcgaW4gZmxpZ2h0ICDihpIgIGRlbGl2ZXJlZDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9Ijg3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U2VxdWVuY2VOdW1iZXI6IDIwIGRpZ2l0cywgemVyby1wYWRkZWQsIGFsd2F5cyBpbmNyZWFzaW5nPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjQwIiB5PSIxMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgb3JkZXJzPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNmVlN2I3Ij5tNDEgKGhlYWQsIGluIGZsaWdodCkgwrcgbTQyIMK3IG00MyDigKY8L3RleHQ+Cjx0ZXh0IHg9IjQwIiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vbmUgaW4gZmxpZ2h0IMK3IG00MiB3YWl0cyB1bnRpbCBtNDEgaXMgZGVsZXRlZCBvciB0aW1lcyBvdXQ8L3RleHQ+CjxyZWN0IHg9IjQzMCIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTIzIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmdyb3VwIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNmVlN2I3Ij5tNTggKGhlYWQsIGluIGZsaWdodCkgwrcgbTU5IOKApjwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5ncm91cHMgYXJlIGNvbmN1cnJlbnQgwrcgYSBkaWZmZXJlbnQgcmVjZWl2ZXIgZHJhaW5zIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjI2IiB5PSIxOTAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiNmYmJmMjQiPkRFRFVQTElDQVRJT04gwrcgNS1NSU5VVEUgV0lORE9XPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTk2IiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTUxIiB5PSIyMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPmV4cGxpY2l0IElEIG9yIFNIQS0yNTYoYm9keSk8L3RleHQ+CjxsaW5lIHgxPSIyNzYiIHkxPSIyMTYiIHgyPSIzMTIiIHkyPSIyMTYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZzKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjMxNCIgeT0iMTk2IiB3aWR0aD0iNDk2IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiM0MjIwMDY7c3Ryb2tlOiM5MjQwMGUiLz4KPHRleHQgeD0iNTYyIiB5PSIyMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojZmJiZjI0Ij5yZXBlYXQgcmV0dXJucyBvcmlnaW5hbCBJRHM8L3RleHQ+Cjx0ZXh0IHg9IjU2MiIgeT0iMjI5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojZmJiZjI0Ij5tZXNzYWdlIGFuZCBkZWR1cCBtYXJrZXIgc2F2ZWQgdG9nZXRoZXI8L3RleHQ+Cjwvc3ZnPg==)

FIFO receives deliver one message per group at a time. Sends return a SequenceNumber, and repeated sends within 5 minutes are suppressed, matched by an explicit ID or, with content-based deduplication, a body hash.

#### Limitations

Where SQS and the PostgreSQL adapter differ

* **Throughput behaves differently: one PostgreSQL server serves every queue.** All of a Cloud Adapter deployment's queues share one server, so its capacity bounds peak throughput and a heavy queue can affect the others. In Tensor9's round-trip test of a moderate-rate Standard queue, the adapter matched SQS throughput (about 300 vs 286 ops/s) with a lower p99 (140 ms vs 172 ms) but a slower median (p50 24 ms vs 15 ms). That is not a measured ceiling, and it does not cover FIFO queues or every host.
* **Recovery follows the database placement.** The managed database is outside the Cloud Adapter deployment cluster, so replacing that cluster does not replace the queue data. Database availability and recovery still depend on the selected server, HA and backup configuration.
* **Messages are limited to 256 KiB by default.** The adapter's default limit is 262144 bytes, while native SQS now accepts up to 1 MiB. Sends are checked against the queue's declared limit.
* **FIFO send deduplication lasts 5 minutes.** A duplicate send within that window returns the original IDs. Reusing an ID after the window can create a new message. Consumer redelivery remains possible even within the window.
* **Stale receipt handles behave differently: they return an error.** `DeleteMessage` and `ChangeMessageVisibility` return `ReceiptHandleIsInvalid` when no message matches the handle.
* **Retention behaves differently: expired messages are removed periodically.** An expired message can remain until the next cleanup pass. Retention is kept between 60 seconds and 14 days; a too-short value is raised to 60 seconds so that new messages are not deleted.
* **Counts observe queue state, not application completion.** Requested message counts read the message database: eligible messages are visible, future-visible messages with a receipt are in flight, and future-visible messages without a receipt are initially delayed. These categories share one query snapshot and can change immediately afterward. Metadata-only reads do not require a message-table count. An unavailable requested count returns an explicit unsupported result rather than zero. Purge, expiry and dead-letter movement can reduce depth without completing the application's work.
* **Queue creation behaves differently: queues are created when the stack is deployed.** Tensor9 creates the database and each queue's table, and its dead-letter table, at deploy time. `CreateQueue`, `DeleteQueue` and `SetQueueAttributes` act on those tables. Switching a queue between Standard and FIFO is rejected, because it would replace the queue.

#### Other considerations

* **Moving from AWS.** The database and queue tables start empty, and existing SQS messages are not migrated. Drain each group before switching it, to preserve order.
* **Removing queues.** Each queue is created in one step, so a crash never leaves a half-created queue. When a queue is removed from the stack, Tensor9 deletes only queues it created; any other queue is detached and left in place. A queue that still holds messages is not deleted unless deletion is forced.
* **Who operates what.** On the managed hosts, the provider operates the database's durability, backups and high availability, and Tensor9 operates the adapter. On CloudNativePG, Tensor9 operates the database inside your cluster.

#### 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.

##### SQS FIFO · SQS request billing units

Feature: SQS FIFO.

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

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

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/e75fa1cd33f68d8167ed8125f99e3ed3eebc336a88ffb31fe1842bd19da58384-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.

| SQS request billing units (per second) | SQS (Simple Queue Service, FIFO queues) | Target scenario | PostgreSQL Flexible Server | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | PostgreSQL Flexible Server (one copy) | 141.44 | 141.44 |
| 0 | 0.00 | PostgreSQL Flexible Server (two copies) | 282.88 | 282.88 |
| 1 | 1.31 | PostgreSQL Flexible Server (one copy) | 141.44 | 140.13 |
| 1 | 1.31 | PostgreSQL Flexible Server (two copies) | 282.88 | 281.57 |
| 10 | 13.14 | PostgreSQL Flexible Server (one copy) | 141.44 | 128.30 |
| 10 | 13.14 | PostgreSQL Flexible Server (two copies) | 282.88 | 269.74 |
| 100 | 131.40 | PostgreSQL Flexible Server (one copy) | 141.44 | 10.04 |
| 100 | 131.40 | PostgreSQL Flexible Server (two copies) | 282.88 | 151.48 |
| 1,000 | 1,314.00 | PostgreSQL Flexible Server (one copy) | 531.26 | -782.74 |
| 1,000 | 1,314.00 | PostgreSQL Flexible Server (two copies) | 1,062.52 | -251.48 |
| 10,000 | 13,140.00 | PostgreSQL Flexible Server (one copy) | 4,169.58 | -8,970.42 |
| 10,000 | 13,140.00 | PostgreSQL Flexible Server (two copies) | 8,339.16 | -4,800.84 |

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

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| PostgreSQL Flexible Server (one copy) | Origin list price · SQS billing units | 0.0000005 | USD/64-KiB request units |
| PostgreSQL Flexible Server (one copy) | Representative message size | 1,024 | bytes |
| PostgreSQL Flexible Server (one copy) | Origin send batch fill | 1 | messages/request |
| PostgreSQL Flexible Server (one copy) | Origin receive batch fill | 1 | messages/request |
| PostgreSQL Flexible Server (one copy) | Origin delete batch fill | 1 | messages/request |
| PostgreSQL Flexible Server (one copy) | Deliveries per message | 1 | attempts |
| PostgreSQL Flexible Server (one copy) | Empty receive calls per message | 0 | requests |
| PostgreSQL Flexible Server (one copy) | Queue residence window | 60 | seconds |
| PostgreSQL Flexible Server (one copy) | Ordering and dedup work multiplier | 2 | multiplier |
| PostgreSQL Flexible Server (one copy) | Target price guess · read | 0 | USD/read |
| PostgreSQL Flexible Server (one copy) | Target price guess · write | 0 | USD/write |
| PostgreSQL Flexible Server (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL Flexible Server (one copy) | Target list price · GiB-month | 0.115 | USD/GiB-month |
| PostgreSQL Flexible Server (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL Flexible Server (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL Flexible Server (one copy) | Target list price · network GiB | 0.087 | USD/network GiB |
| PostgreSQL Flexible Server (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL Flexible Server (one copy) | Target list price · vCPU-hour | 0.053 | USD/vCPU-hour |
| PostgreSQL Flexible Server (one copy) | Target list price · GiB-hour | 0.009 | USD/GiB-hour |
| PostgreSQL Flexible Server (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL Flexible Server (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL Flexible Server (one copy) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL Flexible Server (one copy) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL Flexible Server (one copy) | Target monthly base charge | 0 | USD/month |
| PostgreSQL Flexible Server (one copy) | Target service minimum | 16.09 | USD/month |
| PostgreSQL Flexible Server (one copy) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL Flexible Server (one copy) | Minimum primary RAM | 8 | GiB |
| PostgreSQL Flexible Server (one copy) | Minimum primary disk | 100 | GiB |
| PostgreSQL Flexible Server (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| PostgreSQL Flexible Server (one copy) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL Flexible Server (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL Flexible Server (one copy) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL Flexible Server (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL Flexible Server (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL Flexible Server (one copy) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL Flexible Server (one copy) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL Flexible Server (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL Flexible Server (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL Flexible Server (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL Flexible Server (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL Flexible Server (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| PostgreSQL Flexible Server (two copies) | Origin list price · SQS billing units | 0.0000005 | USD/64-KiB request units |
| PostgreSQL Flexible Server (two copies) | Representative message size | 1,024 | bytes |
| PostgreSQL Flexible Server (two copies) | Origin send batch fill | 1 | messages/request |
| PostgreSQL Flexible Server (two copies) | Origin receive batch fill | 1 | messages/request |
| PostgreSQL Flexible Server (two copies) | Origin delete batch fill | 1 | messages/request |
| PostgreSQL Flexible Server (two copies) | Deliveries per message | 1 | attempts |
| PostgreSQL Flexible Server (two copies) | Empty receive calls per message | 0 | requests |
| PostgreSQL Flexible Server (two copies) | Queue residence window | 60 | seconds |
| PostgreSQL Flexible Server (two copies) | Ordering and dedup work multiplier | 2 | multiplier |
| PostgreSQL Flexible Server (two copies) | Target price guess · read | 0 | USD/read |
| PostgreSQL Flexible Server (two copies) | Target price guess · write | 0 | USD/write |
| PostgreSQL Flexible Server (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| PostgreSQL Flexible Server (two copies) | Target list price · GiB-month | 0.115 | USD/GiB-month |
| PostgreSQL Flexible Server (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| PostgreSQL Flexible Server (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| PostgreSQL Flexible Server (two copies) | Target list price · network GiB | 0.087 | USD/network GiB |
| PostgreSQL Flexible Server (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| PostgreSQL Flexible Server (two copies) | Target list price · vCPU-hour | 0.053 | USD/vCPU-hour |
| PostgreSQL Flexible Server (two copies) | Target list price · GiB-hour | 0.009 | USD/GiB-hour |
| PostgreSQL Flexible Server (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| PostgreSQL Flexible Server (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| PostgreSQL Flexible Server (two copies) | Target price guess · input token | 0 | USD/input token |
| PostgreSQL Flexible Server (two copies) | Target price guess · output token | 0 | USD/output token |
| PostgreSQL Flexible Server (two copies) | Target monthly base charge | 0 | USD/month |
| PostgreSQL Flexible Server (two copies) | Target service minimum | 16.09 | USD/month |
| PostgreSQL Flexible Server (two copies) | Minimum primary CPU | 2 | vCPU |
| PostgreSQL Flexible Server (two copies) | Minimum primary RAM | 8 | GiB |
| PostgreSQL Flexible Server (two copies) | Minimum primary disk | 100 | GiB |
| PostgreSQL Flexible Server (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| PostgreSQL Flexible Server (two copies) | Allocated share of provisioned cost | 1 | fraction |
| PostgreSQL Flexible Server (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| PostgreSQL Flexible Server (two copies) | Planning peak / mean work | 2 | multiplier |
| PostgreSQL Flexible Server (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| PostgreSQL Flexible Server (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| PostgreSQL Flexible Server (two copies) | Planning disk utilization | 0.8 | fraction |
| PostgreSQL Flexible Server (two copies) | Maintenance and log disk reserve | 20 | GiB |
| PostgreSQL Flexible Server (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| PostgreSQL Flexible Server (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| PostgreSQL Flexible Server (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| PostgreSQL Flexible Server (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| PostgreSQL Flexible Server (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* 1-KiB messages, unbatched send/receive/delete; actual batch and delivery assumptions stay visible. 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.
* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.
* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.
* Azure Database for PostgreSQL Flexible Server bills vCores with a fixed memory ratio per series; the vCPU and memory rates decompose the General Purpose and Memory Optimized v5 prices. High availability bills the standby's compute and storage as a second copy. The minimum is the smallest Burstable server, which does not support high availability; the smallest General Purpose server (2 vCores) costs USD 133.62 per month. Additional IOPS, backup storage and reserved capacity 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: E96ds\_v5 has 96 vCores and 672 GiB ([https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-compute](https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-compute)); Premium SSD storage holds up to 32,767 GiB ([https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-storage](https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-storage)).
* 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, AWSQueueService offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json)
* 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-d6e6756733e57b05fe1084c81427de33e78217f0` / `2026-10-22.planning.2`. Curve: `workload-1`.

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

**SQS FIFO → PostgreSQL Flexible Server: 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: SQS billing units | 0.00 |
| Target: Provisioned primary CPU | 77.38 |
| Target: Provisioned primary RAM | 52.56 |
| Target: Provisioned primary disk | 11.50 |
| 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** | **141.44** |

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 · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Representative message size | 1,024 | bytes |
| Origin send batch fill | 1 | messages/request |
| Origin receive batch fill | 1 | messages/request |
| Origin delete batch fill | 1 | messages/request |
| Deliveries per message | 1 | attempts |
| Empty receive calls per message | 0 | requests |
| Queue residence window | 60 | seconds |
| Ordering and dedup work multiplier | 2 | multiplier |
| 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.115 | 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 list price · vCPU-hour | 0.053 | USD/vCPU-hour |
| Target list price · GiB-hour | 0.009 | 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 | 16.09 | 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 |
| SQS billing units | 0 | 64-KiB request units |

* 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.

* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.

* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.

* Azure Database for PostgreSQL Flexible Server bills vCores with a fixed memory ratio per series; the vCPU and memory rates decompose the General Purpose and Memory Optimized v5 prices. High availability bills the standby's compute and storage as a second copy. The minimum is the smallest Burstable server, which does not support high availability; the smallest General Purpose server (2 vCores) costs USD 133.62 per month. Additional IOPS, backup storage and reserved capacity 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: E96ds\_v5 has 96 vCores and 672 GiB ([https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-compute](https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-compute)); Premium SSD storage holds up to 32,767 GiB ([https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-storage](https://learn.microsoft.com/en-us/azure/postgresql/compute-storage/concepts-storage)).

* 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-d6e6756733e57b05fe1084c81427de33e78217f0` / `2026-10-22.planning.2`. Scenario: `planning-example`.

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

## On Google Cloud

### Cloud SQL for PostgreSQL

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Dead-letter redrive | Dead-letter | Supported | Most usage | fires automatically once a message passes maxReceiveCount |
| Content/ID deduplication | FIFO | Supported | Most usage | both modes are served: an explicit MessageDeduplicationId takes precedence over the content hash (AWS's own rule), and a content-based queue derives a stable digest of the body. The message insert and deduplication marker share one transaction. A duplicate rolls back its new row and returns the original message identifiers |
| FIFO ordering | FIFO | Supported | Common | per-MessageGroupId strict order with one-in-flight per group (each receive takes the oldest message of each group, the same contract as the portable and Flexible Server FIFO tiers) |
| Message attributes | Messages | Supported | Common | - |
| GetQueueAttributes | Queues | Supported | Most usage | reads queue attributes, including approximate message counts |
| GetQueueUrl | Queues | Supported | Most usage | resolves the queue by name |
| DeleteMessage | Send / receive | Supported | Common | resolves by receipt handle; a stale handle returns ReceiptHandleIsInvalid |
| DeleteMessageBatch | Send / receive | Supported | Common | returns the result for each entry |
| ReceiveMessage | Send / receive | Supported | Common | long-poll (WaitTimeSeconds) honored; one message in flight per MessageGroupId |
| SendMessage | Send / receive | Supported | Common | MessageGroupId required on send (the AWS FIFO rule); MD5 checksums match what your SDK verifies |
| SendMessageBatch | Send / receive | Supported | Common | up to 10 messages per call, each with its MessageGroupId; returns the result for each entry |
| ChangeMessageVisibility | Visibility | Supported | Common | resolves by receipt handle; a stale handle is rejected rather than silently succeeding |

#### PostgreSQL hosting

Google operates Cloud SQL for PostgreSQL, including database backups and HA. The adapter uses short-lived Cloud SQL IAM tokens as database passwords, without an Auth Proxy or static password. Queue data stays outside the customer's Kubernetes cluster and survives its rebuild. Tensor9 operates the queue schema and adapter. Queues start empty; existing SQS messages are not migrated. Drain each message group before cutover to preserve order.

#### Persistent queue management and total cost

Cloud Adapter retains a persistent PostgreSQL store for the queue catalog, tenancy and lifecycle/control state, normally shared with the Cloud Adapter deployment. Native broker or Cosmos message storage does not remove this resource. Include its allocated compute, storage, backups and selected HA costs alongside adapter and message-backend charges; an idle or serverless message backend does not imply a zero total installation floor. Backend-only curves omit these shared allocations unless their assumptions explicitly include them.

This control store is distinct from the SQS-owned message database. PostgreSQL-authority FIFO composites add recoverable message bodies, receipts, deduplication and outbox state to an explicitly configured SQS message database; they do not store messages in the shared control catalog. A separate logical database and login provide data/permission separation, but still share server CPU, storage, IOPS, WAL and connection limits when hosted on the same instance. Dedicated physical server/instance capacity is a separate allocation and cost decision.

#### Database placement and recovery

Cloud SQL is the durable queue database in your Google Cloud project. The adapter connects over TLS using short-lived IAM database credentials; Google operates the database. Zonal and high-availability configurations have different failure and maintenance behavior. Database backups and recovery policy belong to the selected configuration; they do not make every acknowledged queue operation immune to every database failure. GKE replacement does not replace this external database. Keep its identity and queue schema when rebuilding the application cluster.

#### Capacity and queue workload

The default shared message database holds multiple queues, each with its own table. Dedicated physical server/instance capacity isolates compute and I/O from other server workloads; a separate logical database alone does not. HA changes recovery, commit latency and price rather than FIFO semantics. Neither choice creates an unlimited queue service. Size connection pools, storage, IOPS and WAL for accepted sends, receives, deletes, visibility changes, retries and cleanup together. Long polls wait outside database transactions.

The single-message receive mechanism below permits one message in flight per group. If a group takes T seconds from receive to settlement, its useful completion rate is bounded by roughly 1/T, even when other groups are idle. A larger MaxNumberOfMessages can collect heads from multiple groups; it does not create a ten-message pipeline within one group. Adding consumers or database CPU does not remove that serialization. Compare the separate ordered-batch design before selecting a workload that depends on within-group batching.

Requested live counts scan the message population even for a single requested counter. Frequent depth polling over a large backlog competes for database I/O and pool capacity; receipt classification can change index/heap work. Price those queries separately from sends and completed message cycles. A fall in depth can reflect purge, expiry or dead-letter transfer rather than application completion.

The portable Standard-queue benchmark does not establish the capacity of this host, its HA configuration or a FIFO workload. Payload sizes, active-group skew, settlement time, backlog growth and matched native measurements determine whether a proposed size fits. Missing measurements leave capacity unknown.

#### Retries, batches and application changes

The application keeps its SQS SDK and uses the adapter's configured endpoint and authentication. Backend IAM, database schema permissions and TLS identity belong to the deployment; an AWS ARN or policy is not automatically a target-cloud authorization grant. Scope identities to the customer resources and keep rotated credentials out of message bodies and receipt handles.

A batch response reports each entry separately. Retry only failed entries whose outcome is known; a request timeout can follow a committed send or delete. Keep the same effective deduplication ID on uncertain retries. Duplicate enqueue suppression does not make consumer side effects exactly once. SDK retries and adapter retries share one bounded deadline, with backoff for provider throttling. An expired observer deadline does not prove a still-running native operation was cancelled.

Visibility expiration permits another delivery while an earlier worker can still be executing. Consumers use idempotent writes, choose a visibility duration that covers normal processing and handle stale receipt errors. Retention can expire a message in flight. Queues start empty: drain the source before cutover, group by group. Queue recreation and purge must invalidate old claims independently of public names; data cleanup can continue after logical retirement. Database or broker backup is a resource recovery mechanism, not an automatic replay of application side effects.

#### PostgreSQL queue behavior

Your application keeps its SQS SDK and uses the authenticated Cloud Adapter endpoint configured for the install. The adapter performs `SendMessage` and `ReceiveMessage` in the SQS-owned PostgreSQL message database and returns SQS responses, error codes and MD5 checksums. Its message-data login is separate from other services and the shared control catalog.

Each queue is a PostgreSQL table with one row per message. Sending, receiving, deleting, delays, visibility, dead-letter delivery and message counts all work on those rows. FIFO queues add ordering by message group, per-group sequence numbers and duplicate detection. Consumers can still receive a message more than once.

![Before: on AWS the application's SQS SDK calls Amazon SQS. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS API with one PostgreSQL table per queue.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMuIEFmdGVyOiBpbiB0aGUgdGFyZ2V0IGNsb3VkIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggaW1wbGVtZW50cyB0aGUgU1FTIEFQSSB3aXRoIG9uZSBQb3N0Z3JlU1FMIHRhYmxlIHBlciBxdWV1ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyODgiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gU1FTPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiNjYmQ1ZTEiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI3NzQiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMXB4Ij5Qb3N0Z3JlczwvdGV4dD4KPHRleHQgeD0iNzc0IiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj50YWJsZSBwZXIgcXVldWU8L3RleHQ+Cjwvc3ZnPg==)

![Before: on AWS the application's SQS SDK calls Amazon SQS. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS API with one PostgreSQL table per queue.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMuIEFmdGVyOiBpbiB0aGUgdGFyZ2V0IGNsb3VkIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggaW1wbGVtZW50cyB0aGUgU1FTIEFQSSB3aXRoIG9uZSBQb3N0Z3JlU1FMIHRhYmxlIHBlciBxdWV1ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyODgiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gU1FTPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiM0NzU1NjkiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI3NzQiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMXB4Ij5Qb3N0Z3JlczwvdGV4dD4KPHRleHQgeD0iNzc0IiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij50YWJsZSBwZXIgcXVldWU8L3RleHQ+Cjwvc3ZnPg==)

The application keeps its SQS SDK. The adapter stores each queue in a PostgreSQL table.

#### Architecture

The adapter keeps all queue state in PostgreSQL, including messages and receipt handles, so adapter instances can restart or scale out without losing track of in-flight messages. On Cloud SQL and Azure Flexible Server it signs in with short-lived Cloud SQL IAM or Microsoft Entra tokens used as database passwords, so no static secret is stored.

When the stack is deployed, Tensor9 creates one database per Cloud Adapter deployment and one table per declared queue. Each row holds the message body and attributes, its message group, its visibility time, its receipt handle, its receive count and the time it was sent. A FIFO queue orders messages within each message group; each row's arrival position gives its sequence number. A dead-letter queue is another queue table, and a background task deletes messages older than the queue's retention period.

CloudNativePG, Cloud SQL for PostgreSQL, Azure Flexible Server and Scaleway use the same adapter code and tables. They differ in where the data lives: the managed servers run outside your Kubernetes cluster, while CloudNativePG runs inside it. See the rebuild limitation below.

![The adapter stores messages, receipt handles, receive counts and visibility times in PostgreSQL: one table per queue, and another table for each dead-letter queue. A background task removes messages past their retention. FIFO messages also store their message group and sequence number, and each group has at most one message in flight.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQ0IiB2aWV3Qm94PSIwIDAgODM2IDI0NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciBzdG9yZXMgbWVzc2FnZXMsIHJlY2VpcHQgaGFuZGxlcywgcmVjZWl2ZSBjb3VudHMgYW5kIHZpc2liaWxpdHkgdGltZXMgaW4gUG9zdGdyZVNRTDogb25lIHRhYmxlIHBlciBxdWV1ZSwgYW5kIGFub3RoZXIgdGFibGUgZm9yIGVhY2ggZGVhZC1sZXR0ZXIgcXVldWUuIEEgYmFja2dyb3VuZCB0YXNrIHJlbW92ZXMgbWVzc2FnZXMgcGFzdCB0aGVpciByZXRlbnRpb24uIEZJRk8gbWVzc2FnZXMgYWxzbyBzdG9yZSB0aGVpciBtZXNzYWdlIGdyb3VwIGFuZCBzZXF1ZW5jZSBudW1iZXIsIGFuZCBlYWNoIGdyb3VwIGhhcyBhdCBtb3N0IG9uZSBtZXNzYWdlIGluIGZsaWdodC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InFhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIyNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDYiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyNiIgeT0iNDQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNCIgeT0iMTA0IiB3aWR0aD0iOTYiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzIiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNzIiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjcyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTIwIiB5MT0iMTQyIiB4Mj0iMTUyIiB5Mj0iMTQyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjcWEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iMTU0IiB5PSIxMTIiIHdpZHRoPSIxNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjI0IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTNweCI+VGVuc29yOSBhZGFwdGVyPC90ZXh0Pgo8dGV4dCB4PSIyMjQiIHk9IjE1NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c3RhdGUgaW4gUG9zdGdyZVNRTDwvdGV4dD4KPGxpbmUgeDE9IjI5NiIgeTE9IjE0MiIgeDI9IjM2MCIgeTI9IjE0MiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3FhKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+Cjx0ZXh0IHg9IjMyOCIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+U1FMPC90ZXh0Pgo8dGV4dCB4PSIzMjgiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPnRva2VuIHNpZ24taW48L3RleHQ+CjxyZWN0IHg9IjM2NCIgeT0iNTgiIHdpZHRoPSI0NTYiIGhlaWdodD0iMTY0IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjU5MSIgeT0iODIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5Qb3N0Z3JlU1FMPC90ZXh0Pgo8dGV4dCB4PSI1OTEiIHk9Ijk4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNjQ3NDhiIj5vbmUgZGF0YWJhc2UgcGVyIGFwcGxpYW5jZSDCtyBvbmUgdGFibGUgcGVyIHF1ZXVlPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjExMCIgd2lkdGg9IjIwNiIgaGVpZ2h0PSI3NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0ODMiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+bWVzc2FnZSByb3dzPC90ZXh0Pgo8dGV4dCB4PSI0ODMiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm9uZSByb3cgcGVyIG1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQ4MyIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+Ym9keSDCtyBhdHRyaWJ1dGVzIMK3IHNlbmQgdGltZTwvdGV4dD4KPHJlY3QgeD0iNTk4IiB5PSIxMTAiIHdpZHRoPSIyMDYiIGhlaWdodD0iNzQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNzAxIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+RklGTyBncm91cHM8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5ncm91cCBpZCDCtyBzZXF1ZW5jZSBudW1iZXI8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjE5MiIgd2lkdGg9IjQzNiIgaGVpZ2h0PSIyMiIgcng9IjYiIHN0cm9rZS13aWR0aD0iMSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1OTgiIHk9IjIwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6OS41cHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPnNhbWUgYWRhcHRlciBvbiBldmVyeSBQb3N0Z3JlU1FMIGhvc3Q8L3RleHQ+Cjwvc3ZnPg==)

![The adapter stores messages, receipt handles, receive counts and visibility times in PostgreSQL: one table per queue, and another table for each dead-letter queue. A background task removes messages past their retention. FIFO messages also store their message group and sequence number, and each group has at most one message in flight.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQ0IiB2aWV3Qm94PSIwIDAgODM2IDI0NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciBzdG9yZXMgbWVzc2FnZXMsIHJlY2VpcHQgaGFuZGxlcywgcmVjZWl2ZSBjb3VudHMgYW5kIHZpc2liaWxpdHkgdGltZXMgaW4gUG9zdGdyZVNRTDogb25lIHRhYmxlIHBlciBxdWV1ZSwgYW5kIGFub3RoZXIgdGFibGUgZm9yIGVhY2ggZGVhZC1sZXR0ZXIgcXVldWUuIEEgYmFja2dyb3VuZCB0YXNrIHJlbW92ZXMgbWVzc2FnZXMgcGFzdCB0aGVpciByZXRlbnRpb24uIEZJRk8gbWVzc2FnZXMgYWxzbyBzdG9yZSB0aGVpciBtZXNzYWdlIGdyb3VwIGFuZCBzZXF1ZW5jZSBudW1iZXIsIGFuZCBlYWNoIGdyb3VwIGhhcyBhdCBtb3N0IG9uZSBtZXNzYWdlIGluIGZsaWdodC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InFhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIyNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDYiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyNiIgeT0iNDQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNCIgeT0iMTA0IiB3aWR0aD0iOTYiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzIiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNzIiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjcyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTIwIiB5MT0iMTQyIiB4Mj0iMTUyIiB5Mj0iMTQyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjcWEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iMTU0IiB5PSIxMTIiIHdpZHRoPSIxNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjI0IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTNweCI+VGVuc29yOSBhZGFwdGVyPC90ZXh0Pgo8dGV4dCB4PSIyMjQiIHk9IjE1NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c3RhdGUgaW4gUG9zdGdyZVNRTDwvdGV4dD4KPGxpbmUgeDE9IjI5NiIgeTE9IjE0MiIgeDI9IjM2MCIgeTI9IjE0MiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3FhKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+Cjx0ZXh0IHg9IjMyOCIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+U1FMPC90ZXh0Pgo8dGV4dCB4PSIzMjgiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPnRva2VuIHNpZ24taW48L3RleHQ+CjxyZWN0IHg9IjM2NCIgeT0iNTgiIHdpZHRoPSI0NTYiIGhlaWdodD0iMTY0IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjU5MSIgeT0iODIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5Qb3N0Z3JlU1FMPC90ZXh0Pgo8dGV4dCB4PSI1OTEiIHk9Ijk4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojOTRhM2I4Ij5vbmUgZGF0YWJhc2UgcGVyIGFwcGxpYW5jZSDCtyBvbmUgdGFibGUgcGVyIHF1ZXVlPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjExMCIgd2lkdGg9IjIwNiIgaGVpZ2h0PSI3NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0ODMiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+bWVzc2FnZSByb3dzPC90ZXh0Pgo8dGV4dCB4PSI0ODMiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm9uZSByb3cgcGVyIG1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQ4MyIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+Ym9keSDCtyBhdHRyaWJ1dGVzIMK3IHNlbmQgdGltZTwvdGV4dD4KPHJlY3QgeD0iNTk4IiB5PSIxMTAiIHdpZHRoPSIyMDYiIGhlaWdodD0iNzQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNzAxIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+RklGTyBncm91cHM8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5ncm91cCBpZCDCtyBzZXF1ZW5jZSBudW1iZXI8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjE5MiIgd2lkdGg9IjQzNiIgaGVpZ2h0PSIyMiIgcng9IjYiIHN0cm9rZS13aWR0aD0iMSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1OTgiIHk9IjIwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6OS41cHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPnNhbWUgYWRhcHRlciBvbiBldmVyeSBQb3N0Z3JlU1FMIGhvc3Q8L3RleHQ+Cjwvc3ZnPg==)

Each queue, including each dead-letter queue, is a PostgreSQL table. The same adapter runs on every supported PostgreSQL host.

#### Receiving messages

One database step selects messages whose visibility timeout has passed, oldest first, up to the requested batch size. In the same step it gives each a new receipt handle, hides it for the visibility timeout, adds one to its receive count and returns it. Messages another receiver is taking at that moment are skipped. FIFO queues return the next eligible message in each group, keeping one in flight per group. When the visibility timeout passes, the message can be delivered again; that does not stop a worker still processing the earlier copy.

`ApproximateReceiveCount` is the actual number of receives, not an estimate. The MD5 checksums of the body and attributes are recomputed, so your SDK's checks pass. `DelaySeconds` sets when a message first becomes visible. Long polling waits up to `WaitTimeSeconds` (at most 20 seconds) and returns as soon as a message is available. `SendMessageBatch` inserts all entries at once and reports a result for each entry. Message bodies are stored in the queue table.

![A receive takes the oldest visible messages and, in the same step, gives each a new receipt handle, hides it for the visibility timeout and adds one to its receive count. Two receivers at the same time get different messages. A message can be delivered again once its visibility timeout passes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIHJlY2VpdmUgdGFrZXMgdGhlIG9sZGVzdCB2aXNpYmxlIG1lc3NhZ2VzIGFuZCwgaW4gdGhlIHNhbWUgc3RlcCwgZ2l2ZXMgZWFjaCBhIG5ldyByZWNlaXB0IGhhbmRsZSwgaGlkZXMgaXQgZm9yIHRoZSB2aXNpYmlsaXR5IHRpbWVvdXQgYW5kIGFkZHMgb25lIHRvIGl0cyByZWNlaXZlIGNvdW50LiBUd28gcmVjZWl2ZXJzIGF0IHRoZSBzYW1lIHRpbWUgZ2V0IGRpZmZlcmVudCBtZXNzYWdlcy4gQSBtZXNzYWdlIGNhbiBiZSBkZWxpdmVyZWQgYWdhaW4gb25jZSBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0IHBhc3Nlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0icmEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJyZyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojMDQ3ODU3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPkZpbmQgdmlzaWJsZSBtZXNzYWdlczwvdGV4dD4KPHRleHQgeD0iNzYiIHk9Ijc5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+PHRzcGFuIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnZpc2libGUgbm93PC90c3Bhbj4gwrcgb2xkZXN0IGZpcnN0PC90ZXh0Pgo8bGluZSB4MT0iMjAwIiB5MT0iOTAiIHgyPSIyMDAiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI3JhKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIzMDAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlNraXAgbWVzc2FnZXMgaW4gdXNlPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMTUzIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dGFrZW4gYnkgYW5vdGhlciByZWNlaXZlcjwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9IjE2NCIgeDI9IjIwMCIgeTI9IjE4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjcmEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEycHgiPkhhbmQgb3V0IGluIHRoZSBzYW1lIHN0ZXA8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIyMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPm5ldyByZWNlaXB0IGhhbmRsZSDCtyBoaWRkZW48dHNwYW4geD0iNzYiIGR5PSIxMiI+cmVjZWl2ZSBjb3VudCArIDE8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iMzg4IiB5PSI0MiIgd2lkdGg9IjQyNCIgaGVpZ2h0PSIxOTYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjAwIiB5PSI2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+VFdPIENPTkNVUlJFTlQgUkVDRUlWRVJTPC90ZXh0Pgo8cmVjdCB4PSI0MDQiIHk9Ijc4IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjI0IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0NzkiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEEgZ2V0cyBtMTwvdGV4dD4KPHJlY3QgeD0iNDA0IiB5PSIxMDgiIHdpZHRoPSIxNTAiIGhlaWdodD0iMjQiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjQ3OSIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEIgZ2V0cyBtMjwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSI3OCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz48dGV4dCB4PSI2MTIiIHk9IjkzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5tMSAgaW4gZmxpZ2h0IChBKTwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxMDQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+PHRleHQgeD0iNjEyIiB5PSIxMTkiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPm0yICBpbiBmbGlnaHQgKEIpPC90ZXh0Pgo8cmVjdCB4PSI2MDAiIHk9IjEzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz48dGV4dCB4PSI2MTIiIHk9IjE0NSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzY0NzQ4YiI+bTMgIHZpc2libGUgwrcgbmV4dDwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxNTYiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+PHRleHQgeD0iNjEyIiB5PSIxNzEiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiM2NDc0OGIiPm00ICB2aXNpYmxlIMK3IG5leHQ8L3RleHQ+CjxsaW5lIHgxPSI1NTYiIHkxPSI5MCIgeDI9IjU5NiIgeTI9Ijg4IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8bGluZSB4MT0iNTU2IiB5MT0iMTIwIiB4Mj0iNTk2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSI0MDQiIHk9IjE5NiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzMCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjYwMCIgeT0iMjE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmVhY2ggcmVjZWl2ZXIgZ2V0cyBkaWZmZXJlbnQgbWVzc2FnZXM8L3RleHQ+Cjwvc3ZnPg==)

![A receive takes the oldest visible messages and, in the same step, gives each a new receipt handle, hides it for the visibility timeout and adds one to its receive count. Two receivers at the same time get different messages. A message can be delivered again once its visibility timeout passes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIHJlY2VpdmUgdGFrZXMgdGhlIG9sZGVzdCB2aXNpYmxlIG1lc3NhZ2VzIGFuZCwgaW4gdGhlIHNhbWUgc3RlcCwgZ2l2ZXMgZWFjaCBhIG5ldyByZWNlaXB0IGhhbmRsZSwgaGlkZXMgaXQgZm9yIHRoZSB2aXNpYmlsaXR5IHRpbWVvdXQgYW5kIGFkZHMgb25lIHRvIGl0cyByZWNlaXZlIGNvdW50LiBUd28gcmVjZWl2ZXJzIGF0IHRoZSBzYW1lIHRpbWUgZ2V0IGRpZmZlcmVudCBtZXNzYWdlcy4gQSBtZXNzYWdlIGNhbiBiZSBkZWxpdmVyZWQgYWdhaW4gb25jZSBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0IHBhc3Nlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0icmEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJyZyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNmVlN2I3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPkZpbmQgdmlzaWJsZSBtZXNzYWdlczwvdGV4dD4KPHRleHQgeD0iNzYiIHk9Ijc5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+PHRzcGFuIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnZpc2libGUgbm93PC90c3Bhbj4gwrcgb2xkZXN0IGZpcnN0PC90ZXh0Pgo8bGluZSB4MT0iMjAwIiB5MT0iOTAiIHgyPSIyMDAiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI3JhKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIzMDAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlNraXAgbWVzc2FnZXMgaW4gdXNlPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMTUzIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dGFrZW4gYnkgYW5vdGhlciByZWNlaXZlcjwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9IjE2NCIgeDI9IjIwMCIgeTI9IjE4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjcmEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEycHgiPkhhbmQgb3V0IGluIHRoZSBzYW1lIHN0ZXA8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIyMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPm5ldyByZWNlaXB0IGhhbmRsZSDCtyBoaWRkZW48dHNwYW4geD0iNzYiIGR5PSIxMiI+cmVjZWl2ZSBjb3VudCArIDE8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iMzg4IiB5PSI0MiIgd2lkdGg9IjQyNCIgaGVpZ2h0PSIxOTYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjAwIiB5PSI2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+VFdPIENPTkNVUlJFTlQgUkVDRUlWRVJTPC90ZXh0Pgo8cmVjdCB4PSI0MDQiIHk9Ijc4IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjI0IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0NzkiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEEgZ2V0cyBtMTwvdGV4dD4KPHJlY3QgeD0iNDA0IiB5PSIxMDgiIHdpZHRoPSIxNTAiIGhlaWdodD0iMjQiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjQ3OSIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEIgZ2V0cyBtMjwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSI3OCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz48dGV4dCB4PSI2MTIiIHk9IjkzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5tMSAgaW4gZmxpZ2h0IChBKTwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxMDQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+PHRleHQgeD0iNjEyIiB5PSIxMTkiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPm0yICBpbiBmbGlnaHQgKEIpPC90ZXh0Pgo8cmVjdCB4PSI2MDAiIHk9IjEzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz48dGV4dCB4PSI2MTIiIHk9IjE0NSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6Izk0YTNiOCI+bTMgIHZpc2libGUgwrcgbmV4dDwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxNTYiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+PHRleHQgeD0iNjEyIiB5PSIxNzEiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM5NGEzYjgiPm00ICB2aXNpYmxlIMK3IG5leHQ8L3RleHQ+CjxsaW5lIHgxPSI1NTYiIHkxPSI5MCIgeDI9IjU5NiIgeTI9Ijg4IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8bGluZSB4MT0iNTU2IiB5MT0iMTIwIiB4Mj0iNTk2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSI0MDQiIHk9IjE5NiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzMCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjYwMCIgeT0iMjE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmVhY2ggcmVjZWl2ZXIgZ2V0cyBkaWZmZXJlbnQgbWVzc2FnZXM8L3RleHQ+Cjwvc3ZnPg==)

Two receivers never get the same message at the same time. ApproximateReceiveCount is the actual receive count.

#### Receipt handles & visibility

Each receive saves a new receipt handle with the message. `DeleteMessage` and `ChangeMessageVisibility` find the message by that handle, including after an adapter restart or through another adapter instance.

A delete or visibility change whose handle matches no message returns `ReceiptHandleIsInvalid`. That includes a message already deleted, or received again under a newer handle. The visibility timeout defaults to 30 seconds. `ChangeMessageVisibility` can extend it with no lock-duration maximum, and zero makes the message available again immediately. Retention can delete a message while it is in flight.

![The receipt handle is saved with the message in PostgreSQL and survives adapter restart. Visibility uses a stored deadline within SQS bounds, without a broker lock ceiling.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgcmVjZWlwdCBoYW5kbGUgaXMgc2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMIGFuZCBzdXJ2aXZlcyBhZGFwdGVyIHJlc3RhcnQuIFZpc2liaWxpdHkgdXNlcyBhIHN0b3JlZCBkZWFkbGluZSB3aXRoaW4gU1FTIGJvdW5kcywgd2l0aG91dCBhIGJyb2tlciBsb2NrIGNlaWxpbmcuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InZhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIyNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzA0Nzg1NyI+UkVDRUlQVCBIQU5ETEVTIFNVUlZJVkUgUkVTVEFSVFM8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSIzOCIgd2lkdGg9IjM2MCIgaGVpZ2h0PSIxNDIiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMzI0IiBoZWlnaHQ9IjM0IiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMjA2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+cmVjZWlwdCBoYW5kbGUgPSAzZjJh4oCmLTkxYTI8L3RleHQ+Cjx0ZXh0IHg9IjIwNiIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+c2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMPC90ZXh0Pgo8bGluZSB4MT0iMjA2IiB5MT0iMTIwIiB4Mj0iMjA2IiB5Mj0iMTM2IiBzdHJva2Utd2lkdGg9IjEuNiIgc3Ryb2tlLWRhc2hhcnJheT0iMyAzIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iMjA2IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+YWRhcHRlciByZXN0YXJ0czwvdGV4dD4KPHRleHQgeD0iMjA2IiB5PSIxNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+RGVsZXRlTWVzc2FnZSBhbmQgQ2hhbmdlTWVzc2FnZVZpc2liaWxpdHkgc3RpbGwgd29yazwvdGV4dD4KPGxpbmUgeDE9IjM5OCIgeTE9IjM0IiB4Mj0iMzk4IiB5Mj0iMTg0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQyNCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPk5PIFZJU0lCSUxJVFkgQ0FQPC90ZXh0Pgo8cmVjdCB4PSI0MjQiIHk9IjM4IiB3aWR0aD0iMzg2IiBoZWlnaHQ9IjE0MiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8bGluZSB4MT0iNDQ2IiB5MT0iMTA0IiB4Mj0iODA2IiB5Mj0iMTA0IiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6I2NiZDVlMSIvPgo8cmVjdCB4PSI0NDYiIHk9Ijg4IiB3aWR0aD0iNzgiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNhN2YzZDA7c3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNTI4IiB5PSI4OCIgd2lkdGg9Ijc4IiBoZWlnaHQ9IjE4IiByeD0iNCIgc3Ryb2tlLXdpZHRoPSIxIiBzdHlsZT0iZmlsbDojYTdmM2QwO3N0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjYxMCIgeT0iODgiIHdpZHRoPSIxMjAiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNDc4NTc7c3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjczNCIgeTE9Ijk3IiB4Mj0iODAwIiB5Mj0iOTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCN2YSkiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0ODQiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+dGltZW91dDwvdGV4dD4KPHRleHQgeD0iNTY2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNjY4IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNzcyIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZWQgdGltZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5DaGFuZ2VNZXNzYWdlVmlzaWJpbGl0eSB1cGRhdGVzIHRoZSBkZWFkbGluZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxNTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2NDc0OGIiPihubyBtZXNzYWdlLWxvY2sgdGltZSBsaW1pdCk8L3RleHQ+Cjwvc3ZnPg==)

![The receipt handle is saved with the message in PostgreSQL and survives adapter restart. Visibility uses a stored deadline within SQS bounds, without a broker lock ceiling.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgcmVjZWlwdCBoYW5kbGUgaXMgc2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMIGFuZCBzdXJ2aXZlcyBhZGFwdGVyIHJlc3RhcnQuIFZpc2liaWxpdHkgdXNlcyBhIHN0b3JlZCBkZWFkbGluZSB3aXRoaW4gU1FTIGJvdW5kcywgd2l0aG91dCBhIGJyb2tlciBsb2NrIGNlaWxpbmcuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InZhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIyNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzZlZTdiNyI+UkVDRUlQVCBIQU5ETEVTIFNVUlZJVkUgUkVTVEFSVFM8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSIzOCIgd2lkdGg9IjM2MCIgaGVpZ2h0PSIxNDIiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMzI0IiBoZWlnaHQ9IjM0IiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjA2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+cmVjZWlwdCBoYW5kbGUgPSAzZjJh4oCmLTkxYTI8L3RleHQ+Cjx0ZXh0IHg9IjIwNiIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+c2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMPC90ZXh0Pgo8bGluZSB4MT0iMjA2IiB5MT0iMTIwIiB4Mj0iMjA2IiB5Mj0iMTM2IiBzdHJva2Utd2lkdGg9IjEuNiIgc3Ryb2tlLWRhc2hhcnJheT0iMyAzIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iMjA2IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+YWRhcHRlciByZXN0YXJ0czwvdGV4dD4KPHRleHQgeD0iMjA2IiB5PSIxNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+RGVsZXRlTWVzc2FnZSBhbmQgQ2hhbmdlTWVzc2FnZVZpc2liaWxpdHkgc3RpbGwgd29yazwvdGV4dD4KPGxpbmUgeDE9IjM5OCIgeTE9IjM0IiB4Mj0iMzk4IiB5Mj0iMTg0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQyNCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPk5PIFZJU0lCSUxJVFkgQ0FQPC90ZXh0Pgo8cmVjdCB4PSI0MjQiIHk9IjM4IiB3aWR0aD0iMzg2IiBoZWlnaHQ9IjE0MiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8bGluZSB4MT0iNDQ2IiB5MT0iMTA0IiB4Mj0iODA2IiB5Mj0iMTA0IiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6IzQ3NTU2OSIvPgo8cmVjdCB4PSI0NDYiIHk9Ijg4IiB3aWR0aD0iNzgiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNDc4NTc7c3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNTI4IiB5PSI4OCIgd2lkdGg9Ijc4IiBoZWlnaHQ9IjE4IiByeD0iNCIgc3Ryb2tlLXdpZHRoPSIxIiBzdHlsZT0iZmlsbDojMDQ3ODU3O3N0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjYxMCIgeT0iODgiIHdpZHRoPSIxMjAiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiM2ZWU3Yjc7c3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjczNCIgeTE9Ijk3IiB4Mj0iODAwIiB5Mj0iOTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCN2YSkiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI0ODQiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+dGltZW91dDwvdGV4dD4KPHRleHQgeD0iNTY2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNjY4IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNzcyIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZWQgdGltZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5DaGFuZ2VNZXNzYWdlVmlzaWJpbGl0eSB1cGRhdGVzIHRoZSBkZWFkbGluZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxNTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM5NGEzYjgiPihubyBtZXNzYWdlLWxvY2sgdGltZSBsaW1pdCk8L3RleHQ+Cjwvc3ZnPg==)

Receipt handles are saved with messages, so they still work after an adapter restart. Visibility has no lock-duration limit.

#### Dead-letter & retention

When source and DLQ belong to the same supported SQS-owned message database transaction, receive moves messages at `maxReceiveCount` atomically with claiming the rest. Both changes commit or neither does. Cross-database/store transfers are unsupported: sharing a provider, physical server or control log is not a shared message transaction, and no other service's tables are used. The DLQ retains ordinary queue operations and cleanup. A FIFO move creates a new message in the DLQ, with a new `MessageId`, a receive count of zero and a new send time.

A background task deletes messages sent longer ago than the queue's retention period, including messages in flight; receiving does not reset that time. The retention period defaults to four days and is kept between 60 seconds and 14 days, so a missing or too-short value cannot delete new messages straight away. One worker per database removes expired messages in batches, pauses during database maintenance, and continues if one queue fails. Limits on rows per pass and time per batch cap the load.

![Within the same supported SQS-owned message database transaction, receive moves exhausted messages to the DLQ and hands out the rest. Cross-database/store moves are unsupported. Background cleanup enforces retention; consumers still tolerate redelivery.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJXaXRoaW4gdGhlIHNhbWUgc3VwcG9ydGVkIFNRUy1vd25lZCBtZXNzYWdlIGRhdGFiYXNlIHRyYW5zYWN0aW9uLCByZWNlaXZlIG1vdmVzIGV4aGF1c3RlZCBtZXNzYWdlcyB0byB0aGUgRExRIGFuZCBoYW5kcyBvdXQgdGhlIHJlc3QuIENyb3NzLWRhdGFiYXNlL3N0b3JlIG1vdmVzIGFyZSB1bnN1cHBvcnRlZC4gQmFja2dyb3VuZCBjbGVhbnVwIGVuZm9yY2VzIHJldGVudGlvbjsgY29uc3VtZXJzIHN0aWxsIHRvbGVyYXRlIHJlZGVsaXZlcnkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImRhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2RjMjYyNiIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5ERUFELUxFVFRFUiBNT1ZFIElOIE9ORSBUUkFOU0FDVElPTjwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjEwMSIgeT0iNTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTFweCI+bWVzc2FnZXMgZHVlPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5vbmUgdHJhbnNhY3Rpb248L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI1MCIgeDI9IjIxMiIgeTI9IjUwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNkeCkiIHN0eWxlPSJzdHJva2U6I2RjMjYyNiIvPgo8dGV4dCB4PSIxOTQiIHk9IjQzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZmlsbDojZGMyNjI2Ij7iiaUgbWF4PC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNzQiIHgyPSIyMTIiIHkyPSI3NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZGEpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMTk0IiB5PSI5MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+Jmx0OyBtYXg8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iMzIiIHdpZHRoPSIyMjIiIGhlaWdodD0iMzIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2ZmZmJlYjtzdHJva2U6I2ZkZTY4YSIvPgo8dGV4dCB4PSIzMjUiIHk9IjUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTFweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2I0NTMwOSI+bW92ZSB0byBkZWFkLWxldHRlciBxdWV1ZTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI2NiIgd2lkdGg9IjIyMiIgaGVpZ2h0PSIzMCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjMyNSIgeT0iODUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+cmV0dXJuZWQgdG8gdGhlIHJlY2VpdmVyPC90ZXh0Pgo8cmVjdCB4PSI0NTIiIHk9IjMyIiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjY0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjYzMSIgeT0iNTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTFweCI+b25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI2MzEiIHk9Ijc5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPm1vdmUgYW5kIHJlY2VpdmUgc3VjY2VlZCB0b2dldGhlcjwvdGV4dD4KPHRleHQgeD0iMjYiIHk9IjEyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+UkVURU5USU9OIENMRUFOVVAgwrcgT04gU0VORCBUSU1FPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTM4IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+CjxyZWN0IHg9IjYwIiB5PSIxNjYiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNmZWYyZjI7c3Ryb2tlOiNkYzI2MjYiLz4KPHJlY3QgeD0iNDIwIiB5PSIxNjYiIHdpZHRoPSIzNTAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjQyMCIgeTE9IjE1NiIgeDI9IjQyMCIgeTI9IjE5OCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQgMyIgc3R5bGU9InN0cm9rZTojMzM0MTU1Ii8+Cjx0ZXh0IHg9IjQyMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMzM0MTU1Ij5ub3cg4oiSIHJldGVudGlvbjwvdGV4dD4KPHRleHQgeD0iMjQwIiB5PSIxODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiNkYzI2MjYiPnNlbmQgdGltZSBiZWZvcmUgY3V0b2ZmIOKGkiByZW1vdmVkPC90ZXh0Pgo8dGV4dCB4PSI1OTUiIHk9IjE4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+d2l0aGluIHJldGVudGlvbiDihpIga2VwdDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5yZXRlbnRpb24gNjBzLTE0ZCDCtyBiYXRjaGVkIGNsZWFudXAgwrcgb25lIHdvcmtlciBwZXIgZGF0YWJhc2UgwrcgYmFja3Mgb2ZmIGR1cmluZyBtYWludGVuYW5jZTwvdGV4dD4KPC9zdmc+)

![Within the same supported SQS-owned message database transaction, receive moves exhausted messages to the DLQ and hands out the rest. Cross-database/store moves are unsupported. Background cleanup enforces retention; consumers still tolerate redelivery.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJXaXRoaW4gdGhlIHNhbWUgc3VwcG9ydGVkIFNRUy1vd25lZCBtZXNzYWdlIGRhdGFiYXNlIHRyYW5zYWN0aW9uLCByZWNlaXZlIG1vdmVzIGV4aGF1c3RlZCBtZXNzYWdlcyB0byB0aGUgRExRIGFuZCBoYW5kcyBvdXQgdGhlIHJlc3QuIENyb3NzLWRhdGFiYXNlL3N0b3JlIG1vdmVzIGFyZSB1bnN1cHBvcnRlZC4gQmFja2dyb3VuZCBjbGVhbnVwIGVuZm9yY2VzIHJldGVudGlvbjsgY29uc3VtZXJzIHN0aWxsIHRvbGVyYXRlIHJlZGVsaXZlcnkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImRhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2Y4NzE3MSIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5ERUFELUxFVFRFUiBNT1ZFIElOIE9ORSBUUkFOU0FDVElPTjwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjEwMSIgeT0iNTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTFweCI+bWVzc2FnZXMgZHVlPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5vbmUgdHJhbnNhY3Rpb248L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI1MCIgeDI9IjIxMiIgeTI9IjUwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNkeCkiIHN0eWxlPSJzdHJva2U6I2Y4NzE3MSIvPgo8dGV4dCB4PSIxOTQiIHk9IjQzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZmlsbDojZjg3MTcxIj7iiaUgbWF4PC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNzQiIHgyPSIyMTIiIHkyPSI3NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZGEpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMTk0IiB5PSI5MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+Jmx0OyBtYXg8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iMzIiIHdpZHRoPSIyMjIiIGhlaWdodD0iMzIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzQyMjAwNjtzdHJva2U6IzkyNDAwZSIvPgo8dGV4dCB4PSIzMjUiIHk9IjUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTFweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2ZiYmYyNCI+bW92ZSB0byBkZWFkLWxldHRlciBxdWV1ZTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI2NiIgd2lkdGg9IjIyMiIgaGVpZ2h0PSIzMCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjMyNSIgeT0iODUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+cmV0dXJuZWQgdG8gdGhlIHJlY2VpdmVyPC90ZXh0Pgo8cmVjdCB4PSI0NTIiIHk9IjMyIiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjY0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjYzMSIgeT0iNTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTFweCI+b25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI2MzEiIHk9Ijc5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPm1vdmUgYW5kIHJlY2VpdmUgc3VjY2VlZCB0b2dldGhlcjwvdGV4dD4KPHRleHQgeD0iMjYiIHk9IjEyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+UkVURU5USU9OIENMRUFOVVAgwrcgT04gU0VORCBUSU1FPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTM4IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+CjxyZWN0IHg9IjYwIiB5PSIxNjYiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiM0NTBhMGE7c3Ryb2tlOiNmODcxNzEiLz4KPHJlY3QgeD0iNDIwIiB5PSIxNjYiIHdpZHRoPSIzNTAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjQyMCIgeTE9IjE1NiIgeDI9IjQyMCIgeTI9IjE5OCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQgMyIgc3R5bGU9InN0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQyMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZmlsbDojY2JkNWUxIj5ub3cg4oiSIHJldGVudGlvbjwvdGV4dD4KPHRleHQgeD0iMjQwIiB5PSIxODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNmODcxNzEiPnNlbmQgdGltZSBiZWZvcmUgY3V0b2ZmIOKGkiByZW1vdmVkPC90ZXh0Pgo8dGV4dCB4PSI1OTUiIHk9IjE4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+d2l0aGluIHJldGVudGlvbiDihpIga2VwdDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5yZXRlbnRpb24gNjBzLTE0ZCDCtyBiYXRjaGVkIGNsZWFudXAgwrcgb25lIHdvcmtlciBwZXIgZGF0YWJhc2UgwrcgYmFja3Mgb2ZmIGR1cmluZyBtYWludGVuYW5jZTwvdGV4dD4KPC9zdmc+)

Atomic DLQ moves require the same supported SQS-owned database transaction. Cross-store moves are unsupported. Retention cleanup removes aged messages.

#### FIFO ordering & dedup

A FIFO queue stores each message's `MessageGroupId` and orders delivery within each group. A receive returns only the oldest message of each group that has nothing in flight (no message in that group is currently received and still hidden). Because arrival positions only increase, that is always the group's next message, and exactly one message is in flight per group at a time. Groups are independent, so different receivers can process different groups at once, coordinated only by PostgreSQL. When a message's visibility timeout passes, it is first in its group again, so a redelivery stays in sequence.

Each FIFO send requires `MessageGroupId` and returns a `SequenceNumber`: the message's arrival position as a 20-digit, zero-padded number.

Deduplication markers live in a separate PostgreSQL table keyed by queue and deduplication ID. An explicit `MessageDeduplicationId` takes precedence; otherwise, on a queue with content-based deduplication, the key is the SHA-256 of the body, excluding attributes. The message insert and deduplication marker are part of one transaction. A duplicate within 5 minutes saves no new message and returns the original `MessageId` and `SequenceNumber`. Marker retention is independent of message retention, so receiving or deleting the original does not shorten the deduplication window.

While a message is in flight, no other message from its group is delivered until it is deleted or its visibility timeout passes. That does not stop a timed-out worker from finishing a message it already received, so consumers must make repeated processing safe.

![FIFO receives deliver the next message of each group that has nothing in flight. Each send returns a 20-digit, zero-padded sequence number. Explicit or content-based deduplication is recorded in a separate PostgreSQL table with a five-minute window; a repeated send returns the original message ID and sequence number.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJGSUZPIHJlY2VpdmVzIGRlbGl2ZXIgdGhlIG5leHQgbWVzc2FnZSBvZiBlYWNoIGdyb3VwIHRoYXQgaGFzIG5vdGhpbmcgaW4gZmxpZ2h0LiBFYWNoIHNlbmQgcmV0dXJucyBhIDIwLWRpZ2l0LCB6ZXJvLXBhZGRlZCBzZXF1ZW5jZSBudW1iZXIuIEV4cGxpY2l0IG9yIGNvbnRlbnQtYmFzZWQgZGVkdXBsaWNhdGlvbiBpcyByZWNvcmRlZCBpbiBhIHNlcGFyYXRlIFBvc3RncmVTUUwgdGFibGUgd2l0aCBhIGZpdmUtbWludXRlIHdpbmRvdzsgYSByZXBlYXRlZCBzZW5kIHJldHVybnMgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgSUQgYW5kIHNlcXVlbmNlIG51bWJlci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZnMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PUkRFUiBXSVRISU4gQSBHUk9VUDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQwIiB5PSI1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+bWVzc2FnZXMgb3JkZXJlZCB3aXRoaW4gZWFjaCBncm91cDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjcxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMzM0MTU1Ij5lYWNoIGdyb3VwJ3Mgb2xkZXN0IG1lc3NhZ2UsIGlmIG5vdGhpbmcgaW4gZmxpZ2h0ICDihpIgIGRlbGl2ZXJlZDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9Ijg3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U2VxdWVuY2VOdW1iZXI6IDIwIGRpZ2l0cywgemVyby1wYWRkZWQsIGFsd2F5cyBpbmNyZWFzaW5nPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQwIiB5PSIxMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgb3JkZXJzPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMDQ3ODU3Ij5tNDEgKGhlYWQsIGluIGZsaWdodCkgwrcgbTQyIMK3IG00MyDigKY8L3RleHQ+Cjx0ZXh0IHg9IjQwIiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vbmUgaW4gZmxpZ2h0IMK3IG00MiB3YWl0cyB1bnRpbCBtNDEgaXMgZGVsZXRlZCBvciB0aW1lcyBvdXQ8L3RleHQ+CjxyZWN0IHg9IjQzMCIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTIzIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmdyb3VwIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMDQ3ODU3Ij5tNTggKGhlYWQsIGluIGZsaWdodCkgwrcgbTU5IOKApjwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5ncm91cHMgYXJlIGNvbmN1cnJlbnQgwrcgYSBkaWZmZXJlbnQgcmVjZWl2ZXIgZHJhaW5zIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjI2IiB5PSIxOTAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNiNDUzMDkiPkRFRFVQTElDQVRJT04gwrcgNS1NSU5VVEUgV0lORE9XPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTk2IiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTUxIiB5PSIyMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPmV4cGxpY2l0IElEIG9yIFNIQS0yNTYoYm9keSk8L3RleHQ+CjxsaW5lIHgxPSIyNzYiIHkxPSIyMTYiIHgyPSIzMTIiIHkyPSIyMTYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZzKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjMxNCIgeT0iMTk2IiB3aWR0aD0iNDk2IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZiZWI7c3Ryb2tlOiNmZGU2OGEiLz4KPHRleHQgeD0iNTYyIiB5PSIyMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojYjQ1MzA5Ij5yZXBlYXQgcmV0dXJucyBvcmlnaW5hbCBJRHM8L3RleHQ+Cjx0ZXh0IHg9IjU2MiIgeT0iMjI5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojYjQ1MzA5Ij5tZXNzYWdlIGFuZCBkZWR1cCBtYXJrZXIgc2F2ZWQgdG9nZXRoZXI8L3RleHQ+Cjwvc3ZnPg==)

![FIFO receives deliver the next message of each group that has nothing in flight. Each send returns a 20-digit, zero-padded sequence number. Explicit or content-based deduplication is recorded in a separate PostgreSQL table with a five-minute window; a repeated send returns the original message ID and sequence number.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJGSUZPIHJlY2VpdmVzIGRlbGl2ZXIgdGhlIG5leHQgbWVzc2FnZSBvZiBlYWNoIGdyb3VwIHRoYXQgaGFzIG5vdGhpbmcgaW4gZmxpZ2h0LiBFYWNoIHNlbmQgcmV0dXJucyBhIDIwLWRpZ2l0LCB6ZXJvLXBhZGRlZCBzZXF1ZW5jZSBudW1iZXIuIEV4cGxpY2l0IG9yIGNvbnRlbnQtYmFzZWQgZGVkdXBsaWNhdGlvbiBpcyByZWNvcmRlZCBpbiBhIHNlcGFyYXRlIFBvc3RncmVTUUwgdGFibGUgd2l0aCBhIGZpdmUtbWludXRlIHdpbmRvdzsgYSByZXBlYXRlZCBzZW5kIHJldHVybnMgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgSUQgYW5kIHNlcXVlbmNlIG51bWJlci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZnMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PUkRFUiBXSVRISU4gQSBHUk9VUDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQwIiB5PSI1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+bWVzc2FnZXMgb3JkZXJlZCB3aXRoaW4gZWFjaCBncm91cDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjcxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojY2JkNWUxIj5lYWNoIGdyb3VwJ3Mgb2xkZXN0IG1lc3NhZ2UsIGlmIG5vdGhpbmcgaW4gZmxpZ2h0ICDihpIgIGRlbGl2ZXJlZDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9Ijg3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U2VxdWVuY2VOdW1iZXI6IDIwIGRpZ2l0cywgemVyby1wYWRkZWQsIGFsd2F5cyBpbmNyZWFzaW5nPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjQwIiB5PSIxMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgb3JkZXJzPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNmVlN2I3Ij5tNDEgKGhlYWQsIGluIGZsaWdodCkgwrcgbTQyIMK3IG00MyDigKY8L3RleHQ+Cjx0ZXh0IHg9IjQwIiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vbmUgaW4gZmxpZ2h0IMK3IG00MiB3YWl0cyB1bnRpbCBtNDEgaXMgZGVsZXRlZCBvciB0aW1lcyBvdXQ8L3RleHQ+CjxyZWN0IHg9IjQzMCIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTIzIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmdyb3VwIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNmVlN2I3Ij5tNTggKGhlYWQsIGluIGZsaWdodCkgwrcgbTU5IOKApjwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5ncm91cHMgYXJlIGNvbmN1cnJlbnQgwrcgYSBkaWZmZXJlbnQgcmVjZWl2ZXIgZHJhaW5zIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjI2IiB5PSIxOTAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiNmYmJmMjQiPkRFRFVQTElDQVRJT04gwrcgNS1NSU5VVEUgV0lORE9XPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTk2IiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTUxIiB5PSIyMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPmV4cGxpY2l0IElEIG9yIFNIQS0yNTYoYm9keSk8L3RleHQ+CjxsaW5lIHgxPSIyNzYiIHkxPSIyMTYiIHgyPSIzMTIiIHkyPSIyMTYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZzKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjMxNCIgeT0iMTk2IiB3aWR0aD0iNDk2IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiM0MjIwMDY7c3Ryb2tlOiM5MjQwMGUiLz4KPHRleHQgeD0iNTYyIiB5PSIyMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojZmJiZjI0Ij5yZXBlYXQgcmV0dXJucyBvcmlnaW5hbCBJRHM8L3RleHQ+Cjx0ZXh0IHg9IjU2MiIgeT0iMjI5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojZmJiZjI0Ij5tZXNzYWdlIGFuZCBkZWR1cCBtYXJrZXIgc2F2ZWQgdG9nZXRoZXI8L3RleHQ+Cjwvc3ZnPg==)

FIFO receives deliver one message per group at a time. Sends return a SequenceNumber, and repeated sends within 5 minutes are suppressed, matched by an explicit ID or, with content-based deduplication, a body hash.

#### Limitations

Where SQS and the PostgreSQL adapter differ

* **Throughput behaves differently: one PostgreSQL server serves every queue.** All of a Cloud Adapter deployment's queues share one server, so its capacity bounds peak throughput and a heavy queue can affect the others. In Tensor9's round-trip test of a moderate-rate Standard queue, the adapter matched SQS throughput (about 300 vs 286 ops/s) with a lower p99 (140 ms vs 172 ms) but a slower median (p50 24 ms vs 15 ms). That is not a measured ceiling, and it does not cover FIFO queues or every host.
* **Recovery follows the database placement.** The managed database is outside the Cloud Adapter deployment cluster, so replacing that cluster does not replace the queue data. Database availability and recovery still depend on the selected server, HA and backup configuration.
* **Messages are limited to 256 KiB by default.** The adapter's default limit is 262144 bytes, while native SQS now accepts up to 1 MiB. Sends are checked against the queue's declared limit.
* **FIFO send deduplication lasts 5 minutes.** A duplicate send within that window returns the original IDs. Reusing an ID after the window can create a new message. Consumer redelivery remains possible even within the window.
* **Stale receipt handles behave differently: they return an error.** `DeleteMessage` and `ChangeMessageVisibility` return `ReceiptHandleIsInvalid` when no message matches the handle.
* **Retention behaves differently: expired messages are removed periodically.** An expired message can remain until the next cleanup pass. Retention is kept between 60 seconds and 14 days; a too-short value is raised to 60 seconds so that new messages are not deleted.
* **Counts observe queue state, not application completion.** Requested message counts read the message database: eligible messages are visible, future-visible messages with a receipt are in flight, and future-visible messages without a receipt are initially delayed. These categories share one query snapshot and can change immediately afterward. Metadata-only reads do not require a message-table count. An unavailable requested count returns an explicit unsupported result rather than zero. Purge, expiry and dead-letter movement can reduce depth without completing the application's work.
* **Queue creation behaves differently: queues are created when the stack is deployed.** Tensor9 creates the database and each queue's table, and its dead-letter table, at deploy time. `CreateQueue`, `DeleteQueue` and `SetQueueAttributes` act on those tables. Switching a queue between Standard and FIFO is rejected, because it would replace the queue.

#### Other considerations

* **Moving from AWS.** The database and queue tables start empty, and existing SQS messages are not migrated. Drain each group before switching it, to preserve order.
* **Removing queues.** Each queue is created in one step, so a crash never leaves a half-created queue. When a queue is removed from the stack, Tensor9 deletes only queues it created; any other queue is detached and left in place. A queue that still holds messages is not deleted unless deletion is forced.
* **Who operates what.** On the managed hosts, the provider operates the database's durability, backups and high availability, and Tensor9 operates the adapter. On CloudNativePG, Tensor9 operates the database inside your cluster.

#### Google Cloud queue designs

FIFO needs durable group order, deduplication results, user receipts and lifecycle generations. The following designs have different storage owners and bills. Choosing one is an explicit resource/configuration decision; the adapter does not move a running queue between them automatically.

\| Design | Where bodies and queue state live | Workload consequence | | --- | --- | --- | | Cloud SQL PostgreSQL | Transactional bodies, receipts and dedup | Shared/dedicated capacity; zonal/HA placement | | Firestore | Transactional manifests, binary chunks and claims | Idle-heavy/many-group traffic; hot-group contention and operation/index charges | | Regional Spanner | Serializable queue transactions and binary chunks | Aggregate distributed load; capacity floor and hot-group serialization | | Pub/Sub full-body FIFO + PostgreSQL | Recoverable body in SQL; another body copy traverses Pub/Sub | Two-service cost; first delivery waits for broker observation; per-key payload limit | | PostgreSQL FIFO + Pub/Sub wakeups | Bodies/user state in SQL; broker carries ready hints | Scans repair lost hints; compare with LISTEN/NOTIFY |

**Firestore:** a message manifest and its immutable binary chunks commit together. A 1-MiB body uses four 256-KiB chunks, avoiding Firestore's per-document limit without introducing a Cloud Storage bucket. Attributes, transaction overhead and indexes must also fit the complete request. Candidate queries are hints; the transaction checks queue generation and claims the group. Chunk cleanup waits until no valid delivery/replay needs the body.

**Spanner:** distributed group keys spread independent work. A read-write transaction checks lifecycle state, deduplication and group ownership before accepting or claiming a message. A read-only scan never owns a delivery. Unknown commit results are resolved from operation identity and durable state. Regional placement is explicit; this design makes no automatic multi-region recovery or measured throughput claim.

**Full-body Pub/Sub FIFO:** Send commits body, group sequence, dedup result and publication intent in PostgreSQL. A publisher sends the body with stable logical identity and digest. A subscriber verifies the existing authority row and records broker observation before acknowledging the physical copy. Only observed eligible group heads reach SQS consumers. Broker acknowledgement is not SQS DeleteMessage: PostgreSQL retains the body and user claim. An outage before observation blocks first delivery and can consume retention time. Pub/Sub's 1 MB/s ordering-key publish limit applies to bodies, attributes and transport-envelope bytes; more consumers do not remove it.

**Wakeups:** Send commits the same database state but publishes only queue/group readiness. Receive can claim from PostgreSQL without a notification, using bounded repair scans. Duplicate or reordered notifications cannot allocate another message or advance a group. A broker outage can increase discovery latency, while database availability still determines message service. The notification byte limit is not a payload throughput estimate.

The transactional designs retain queue incarnation and purge generation with every message, receipt and pending publication. A late publisher cannot recreate a deleted body or enter a replacement queue. Firestore, Spanner and SQL-assisted FIFO transport designs use the separate ordered-batch protocol, rather than direct PostgreSQL's one-head-per-group mechanism. They return a contiguous group prefix up to the overall ten-message budget, but conservatively wait for all remaining members to settle or expire before redelivery. This is a restriction when individual members have different visibility deadlines. Valid five-minute ReceiveRequestAttemptId replays return the same unchanged set and refresh visibility without another receive-count increment; modified claims return an explicit unsupported result requiring a new attempt. These designs do not establish full AWS batch/replay equivalence.

Atomic dead-letter moves require source and target in the same supported transaction. Cross-store moves/redrive are unsupported. Moving a blocked FIFO head to a dead-letter queue permits later messages to proceed and changes the original business sequence; decide whether that is appropriate for the application.

#### 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.** FIFO request-processing service levels have not been qualified for this mapping. Standard-queue measurements do not establish FIFO latency, throughput or availability. Cost estimates describe the selected service resources; operation coverage remains separate.

##### SQS FIFO · SQS request billing units

Feature: SQS FIFO.

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

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

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/f158bf2cf840855dc0368387034370246b08d95352748ec5e5297564a4633445-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.

| SQS request billing units (per second) | SQS (Simple Queue Service, FIFO queues) | 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.31 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 116.86 |
| 1 | 1.31 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 235.04 |
| 10 | 13.14 | Cloud SQL for PostgreSQL (one copy) | 118.18 | 105.04 |
| 10 | 13.14 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 223.22 |
| 100 | 131.40 | Cloud SQL for PostgreSQL (one copy) | 118.18 | -13.22 |
| 100 | 131.40 | Cloud SQL for PostgreSQL (two copies) | 236.36 | 104.96 |
| 1,000 | 1,314.00 | Cloud SQL for PostgreSQL (one copy) | 421.71 | -892.29 |
| 1,000 | 1,314.00 | Cloud SQL for PostgreSQL (two copies) | 843.42 | -470.58 |
| 10,000 | 13,140.00 | Cloud SQL for PostgreSQL (one copy) | 3,254.70 | -9,885.30 |
| 10,000 | 13,140.00 | Cloud SQL for PostgreSQL (two copies) | 6,509.39 | -6,630.61 |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 64 vCPU, 256 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 · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Cloud SQL for PostgreSQL (one copy) | Representative message size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (one copy) | Origin send batch fill | 1 | messages/request |
| Cloud SQL for PostgreSQL (one copy) | Origin receive batch fill | 1 | messages/request |
| Cloud SQL for PostgreSQL (one copy) | Origin delete batch fill | 1 | messages/request |
| Cloud SQL for PostgreSQL (one copy) | Deliveries per message | 1 | attempts |
| Cloud SQL for PostgreSQL (one copy) | Empty receive calls per message | 0 | requests |
| Cloud SQL for PostgreSQL (one copy) | Queue residence window | 60 | seconds |
| Cloud SQL for PostgreSQL (one copy) | Ordering and dedup work multiplier | 2 | multiplier |
| 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 · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Cloud SQL for PostgreSQL (two copies) | Representative message size | 1,024 | bytes |
| Cloud SQL for PostgreSQL (two copies) | Origin send batch fill | 1 | messages/request |
| Cloud SQL for PostgreSQL (two copies) | Origin receive batch fill | 1 | messages/request |
| Cloud SQL for PostgreSQL (two copies) | Origin delete batch fill | 1 | messages/request |
| Cloud SQL for PostgreSQL (two copies) | Deliveries per message | 1 | attempts |
| Cloud SQL for PostgreSQL (two copies) | Empty receive calls per message | 0 | requests |
| Cloud SQL for PostgreSQL (two copies) | Queue residence window | 60 | seconds |
| Cloud SQL for PostgreSQL (two copies) | Ordering and dedup work multiplier | 2 | multiplier |
| 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 |

* 1-KiB messages, unbatched send/receive/delete; actual batch and delivery assumptions stay visible. 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.
* Native/deployment comparison scope: FIFO request-processing service levels have not been qualified for this mapping. Standard-queue measurements do not establish FIFO latency, throughput or availability.
* 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.
* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.
* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.
* 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, AWSQueueService offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json)
* 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-c35b94f39c83dfc6e65b2063cdc3c7857cb28524` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AWSQueueService offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json), [Cloud SQL pricing](https://cloud.google.com/sql/pricing).

**SQS FIFO → 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: SQS billing units | 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 · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Representative message size | 1,024 | bytes |
| Origin send batch fill | 1 | messages/request |
| Origin receive batch fill | 1 | messages/request |
| Origin delete batch fill | 1 | messages/request |
| Deliveries per message | 1 | attempts |
| Empty receive calls per message | 0 | requests |
| Queue residence window | 60 | seconds |
| Ordering and dedup work multiplier | 2 | multiplier |
| 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 |
| SQS billing units | 0 | 64-KiB request units |

* 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: FIFO request-processing service levels have not been qualified for this mapping. Standard-queue measurements do not establish FIFO latency, throughput or availability.

* 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.

* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.

* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.

* 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-c35b94f39c83dfc6e65b2063cdc3c7857cb28524` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AWSQueueService offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json), [Cloud SQL pricing](https://cloud.google.com/sql/pricing).

## On Scaleway

### Scaleway Managed Database for PostgreSQL

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Dead-letter redrive | Dead-letter | Supported | Most usage | fires automatically once a message passes maxReceiveCount |
| Content/ID deduplication | FIFO | Supported | Most usage | both modes are served: an explicit MessageDeduplicationId takes precedence over the content hash (AWS's own rule), and a content-based queue derives a stable digest of the body. The message insert and deduplication marker share one transaction. A duplicate rolls back its new row and returns the original message identifiers |
| FIFO ordering | FIFO | Supported | Common | per-MessageGroupId strict order with one-in-flight per group (each receive takes the oldest message of each group, the same contract as the portable, Cloud SQL and Flexible Server FIFO tiers). Scaleway's native Queues cannot express this at all: MessageGroupId is unsupported there |
| Message attributes | Messages | Supported | Common | - |
| GetQueueAttributes | Queues | Supported | Most usage | reads queue attributes, including approximate message counts |
| GetQueueUrl | Queues | Supported | Most usage | resolves the queue by name |
| DeleteMessage | Send / receive | Supported | Common | resolves by receipt handle; a stale handle returns ReceiptHandleIsInvalid |
| DeleteMessageBatch | Send / receive | Supported | Common | returns the result for each entry |
| ReceiveMessage | Send / receive | Supported | Common | long-poll (WaitTimeSeconds) honored; one message in flight per MessageGroupId |
| SendMessage | Send / receive | Supported | Common | MessageGroupId required on send (the AWS FIFO rule); MD5 checksums match what your SDK verifies |
| SendMessageBatch | Send / receive | Supported | Common | up to 10 messages per call, each with its MessageGroupId; returns the result for each entry |
| ChangeMessageVisibility | Visibility | Supported | Common | resolves by receipt handle; a stale handle is rejected rather than silently succeeding |

#### PostgreSQL hosting

Scaleway operates the managed PostgreSQL instance outside the customer's Kubernetes cluster. Tensor9 operates the adapter and queue schema. Queue data survives a Kubernetes cluster rebuild; configure the managed database credentials for the adapter. Tensor9 operates the queue schema and adapter. Queues start empty; existing SQS messages are not migrated. Drain each message group before cutover to preserve order.

#### Persistent queue management and total cost

Cloud Adapter retains a persistent PostgreSQL store for the queue catalog, tenancy and lifecycle/control state, normally shared with the Cloud Adapter deployment. Native broker or Cosmos message storage does not remove this resource. Include its allocated compute, storage, backups and selected HA costs alongside adapter and message-backend charges; an idle or serverless message backend does not imply a zero total installation floor. Backend-only curves omit these shared allocations unless their assumptions explicitly include them.

This control store is distinct from the SQS-owned message database. PostgreSQL-authority FIFO composites add recoverable message bodies, receipts, deduplication and outbox state to an explicitly configured SQS message database; they do not store messages in the shared control catalog. A separate logical database and login provide data/permission separation, but still share server CPU, storage, IOPS, WAL and connection limits when hosted on the same instance. Dedicated physical server/instance capacity is a separate allocation and cost decision.

#### Database placement and recovery

Scaleway's managed PostgreSQL database keeps the queues outside the application cluster. Scaleway operates the server; configure the adapter's database credentials and network access. Database capacity, availability and backups follow the selected managed instance configuration, rather than the application cluster's lifecycle.

#### Capacity and queue workload

The default shared message database holds multiple queues, each with its own table. Dedicated physical server/instance capacity isolates compute and I/O from other server workloads; a separate logical database alone does not. HA changes recovery, commit latency and price rather than FIFO semantics. Neither choice creates an unlimited queue service. Size connection pools, storage, IOPS and WAL for accepted sends, receives, deletes, visibility changes, retries and cleanup together. Long polls wait outside database transactions.

The single-message receive mechanism below permits one message in flight per group. If a group takes T seconds from receive to settlement, its useful completion rate is bounded by roughly 1/T, even when other groups are idle. A larger MaxNumberOfMessages can collect heads from multiple groups; it does not create a ten-message pipeline within one group. Adding consumers or database CPU does not remove that serialization. Compare the separate ordered-batch design before selecting a workload that depends on within-group batching.

Requested live counts scan the message population even for a single requested counter. Frequent depth polling over a large backlog competes for database I/O and pool capacity; receipt classification can change index/heap work. Price those queries separately from sends and completed message cycles. A fall in depth can reflect purge, expiry or dead-letter transfer rather than application completion.

The portable Standard-queue benchmark does not establish the capacity of this host, its HA configuration or a FIFO workload. Payload sizes, active-group skew, settlement time, backlog growth and matched native measurements determine whether a proposed size fits. Missing measurements leave capacity unknown.

#### Retries, batches and application changes

The application keeps its SQS SDK and uses the adapter's configured endpoint and authentication. Backend IAM, database schema permissions and TLS identity belong to the deployment; an AWS ARN or policy is not automatically a target-cloud authorization grant. Scope identities to the customer resources and keep rotated credentials out of message bodies and receipt handles.

A batch response reports each entry separately. Retry only failed entries whose outcome is known; a request timeout can follow a committed send or delete. Keep the same effective deduplication ID on uncertain retries. Duplicate enqueue suppression does not make consumer side effects exactly once. SDK retries and adapter retries share one bounded deadline, with backoff for provider throttling. An expired observer deadline does not prove a still-running native operation was cancelled.

Visibility expiration permits another delivery while an earlier worker can still be executing. Consumers use idempotent writes, choose a visibility duration that covers normal processing and handle stale receipt errors. Retention can expire a message in flight. Queues start empty: drain the source before cutover, group by group. Queue recreation and purge must invalidate old claims independently of public names; data cleanup can continue after logical retirement. Database or broker backup is a resource recovery mechanism, not an automatic replay of application side effects.

#### PostgreSQL queue behavior

Your application keeps its SQS SDK and uses the authenticated Cloud Adapter endpoint configured for the install. The adapter performs `SendMessage` and `ReceiveMessage` in the SQS-owned PostgreSQL message database and returns SQS responses, error codes and MD5 checksums. Its message-data login is separate from other services and the shared control catalog.

Each queue is a PostgreSQL table with one row per message. Sending, receiving, deleting, delays, visibility, dead-letter delivery and message counts all work on those rows. FIFO queues add ordering by message group, per-group sequence numbers and duplicate detection. Consumers can still receive a message more than once.

![Before: on AWS the application's SQS SDK calls Amazon SQS. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS API with one PostgreSQL table per queue.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMuIEFmdGVyOiBpbiB0aGUgdGFyZ2V0IGNsb3VkIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggaW1wbGVtZW50cyB0aGUgU1FTIEFQSSB3aXRoIG9uZSBQb3N0Z3JlU1FMIHRhYmxlIHBlciBxdWV1ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6Izk0YTNiOCIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyODgiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gU1FTPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiNjYmQ1ZTEiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI3NzQiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMXB4Ij5Qb3N0Z3JlczwvdGV4dD4KPHRleHQgeD0iNzc0IiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj50YWJsZSBwZXIgcXVldWU8L3RleHQ+Cjwvc3ZnPg==)

![Before: on AWS the application's SQS SDK calls Amazon SQS. After: in the target cloud the same application and SDK call a Tensor9 adapter, which implements the SQS API with one PostgreSQL table per queue.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMTgwIiB2aWV3Qm94PSIwIDAgODM2IDE4MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyB0aGUgYXBwbGljYXRpb24ncyBTUVMgU0RLIGNhbGxzIEFtYXpvbiBTUVMuIEFmdGVyOiBpbiB0aGUgdGFyZ2V0IGNsb3VkIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFuZCBTREsgY2FsbCBhIFRlbnNvcjkgYWRhcHRlciwgd2hpY2ggaW1wbGVtZW50cyB0aGUgU1FTIEFQSSB3aXRoIG9uZSBQb3N0Z3JlU1FMIHRhYmxlIHBlciBxdWV1ZS4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9ImFoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+CjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ2IiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjExOCIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1IiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjMwIiB5PSI2NCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+T04gQVdTIFRPREFZPC90ZXh0Pgo8cmVjdCB4PSIzMCIgeT0iODAiIHdpZHRoPSIxMjAiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iOTAiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI5MCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U1FTIFNESzwvdGV4dD4KPGxpbmUgeDE9IjE1MCIgeTE9IjExMyIgeDI9IjIxMCIgeTI9IjExMyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2FoMSkiIHN0eWxlPSJzdHJva2U6IzY0NzQ4YiIvPgo8dGV4dCB4PSIxODEiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZvbnQtc2l6ZTo4LjVweCI+U1FTIEFQSTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI4MCIgd2lkdGg9IjE0OCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyODgiIHk9IjExMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gU1FTPC90ZXh0Pgo8dGV4dCB4PSIyODgiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkFXUy1tYW5hZ2VkPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNjAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiM0NzU1NjkiLz4KPHJlY3QgeD0iNDYyIiB5PSI0NiIgd2lkdGg9IjM2MiIgaGVpZ2h0PSIxMTgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NzYiIHk9IjY0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PTiBUSEUgVEFSR0VUIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSI0NzQiIHk9IjgwIiB3aWR0aD0iOTIiIGhlaWdodD0iNjYiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNTIwIiB5PSIxMTAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTJweCI+WW91ciBhcHA8L3RleHQ+Cjx0ZXh0IHg9IjUyMCIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTY2IiB5MT0iMTEzIiB4Mj0iNTkwIiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjU5NCIgeT0iNzYiIHdpZHRoPSIxMTAiIGhlaWdodD0iNzQiIHJ4PSIxMSIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNjQ5IiB5PSIxMDIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTJweCI+VGVuc29yOTwvdGV4dD4KPHRleHQgeD0iNjQ5IiB5PSIxMTciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPnNlcnZpY2U8L3RleHQ+Cjx0ZXh0IHg9IjY0OSIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5hZGFwdGVyPC90ZXh0Pgo8bGluZSB4MT0iNzA0IiB5MT0iMTEzIiB4Mj0iNzI4IiB5Mj0iMTEzIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjYWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjczMiIgeT0iODAiIHdpZHRoPSI4NCIgaGVpZ2h0PSI2NiIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI3NzQiIHk9IjEwOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMXB4Ij5Qb3N0Z3JlczwvdGV4dD4KPHRleHQgeD0iNzc0IiB5PSIxMjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij50YWJsZSBwZXIgcXVldWU8L3RleHQ+Cjwvc3ZnPg==)

The application keeps its SQS SDK. The adapter stores each queue in a PostgreSQL table.

#### Architecture

The adapter keeps all queue state in PostgreSQL, including messages and receipt handles, so adapter instances can restart or scale out without losing track of in-flight messages. On Cloud SQL and Azure Flexible Server it signs in with short-lived Cloud SQL IAM or Microsoft Entra tokens used as database passwords, so no static secret is stored.

When the stack is deployed, Tensor9 creates one database per Cloud Adapter deployment and one table per declared queue. Each row holds the message body and attributes, its message group, its visibility time, its receipt handle, its receive count and the time it was sent. A FIFO queue orders messages within each message group; each row's arrival position gives its sequence number. A dead-letter queue is another queue table, and a background task deletes messages older than the queue's retention period.

CloudNativePG, Cloud SQL for PostgreSQL, Azure Flexible Server and Scaleway use the same adapter code and tables. They differ in where the data lives: the managed servers run outside your Kubernetes cluster, while CloudNativePG runs inside it. See the rebuild limitation below.

![The adapter stores messages, receipt handles, receive counts and visibility times in PostgreSQL: one table per queue, and another table for each dead-letter queue. A background task removes messages past their retention. FIFO messages also store their message group and sequence number, and each group has at most one message in flight.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQ0IiB2aWV3Qm94PSIwIDAgODM2IDI0NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciBzdG9yZXMgbWVzc2FnZXMsIHJlY2VpcHQgaGFuZGxlcywgcmVjZWl2ZSBjb3VudHMgYW5kIHZpc2liaWxpdHkgdGltZXMgaW4gUG9zdGdyZVNRTDogb25lIHRhYmxlIHBlciBxdWV1ZSwgYW5kIGFub3RoZXIgdGFibGUgZm9yIGVhY2ggZGVhZC1sZXR0ZXIgcXVldWUuIEEgYmFja2dyb3VuZCB0YXNrIHJlbW92ZXMgbWVzc2FnZXMgcGFzdCB0aGVpciByZXRlbnRpb24uIEZJRk8gbWVzc2FnZXMgYWxzbyBzdG9yZSB0aGVpciBtZXNzYWdlIGdyb3VwIGFuZCBzZXF1ZW5jZSBudW1iZXIsIGFuZCBlYWNoIGdyb3VwIGhhcyBhdCBtb3N0IG9uZSBtZXNzYWdlIGluIGZsaWdodC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InFhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM5NGEzYjgiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIyNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDYiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSIyNiIgeT0iNDQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4Ij5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNCIgeT0iMTA0IiB3aWR0aD0iOTYiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzIiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNzIiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjcyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTIwIiB5MT0iMTQyIiB4Mj0iMTUyIiB5Mj0iMTQyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjcWEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHJlY3QgeD0iMTU0IiB5PSIxMTIiIHdpZHRoPSIxNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjI0IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXNpemU6MTNweCI+VGVuc29yOSBhZGFwdGVyPC90ZXh0Pgo8dGV4dCB4PSIyMjQiIHk9IjE1NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+c3RhdGUgaW4gUG9zdGdyZVNRTDwvdGV4dD4KPGxpbmUgeDE9IjI5NiIgeTE9IjE0MiIgeDI9IjM2MCIgeTI9IjE0MiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3FhKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+Cjx0ZXh0IHg9IjMyOCIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+U1FMPC90ZXh0Pgo8dGV4dCB4PSIzMjgiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGIiPnRva2VuIHNpZ24taW48L3RleHQ+CjxyZWN0IHg9IjM2NCIgeT0iNTgiIHdpZHRoPSI0NTYiIGhlaWdodD0iMTY0IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjU5MSIgeT0iODIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTIuNXB4Ij5Qb3N0Z3JlU1FMPC90ZXh0Pgo8dGV4dCB4PSI1OTEiIHk9Ijk4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNjQ3NDhiIj5vbmUgZGF0YWJhc2UgcGVyIGFwcGxpYW5jZSDCtyBvbmUgdGFibGUgcGVyIHF1ZXVlPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjExMCIgd2lkdGg9IjIwNiIgaGVpZ2h0PSI3NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0ODMiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+bWVzc2FnZSByb3dzPC90ZXh0Pgo8dGV4dCB4PSI0ODMiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPm9uZSByb3cgcGVyIG1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQ4MyIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+Ym9keSDCtyBhdHRyaWJ1dGVzIMK3IHNlbmQgdGltZTwvdGV4dD4KPHJlY3QgeD0iNTk4IiB5PSIxMTAiIHdpZHRoPSIyMDYiIGhlaWdodD0iNzQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iNzAxIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+RklGTyBncm91cHM8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5ncm91cCBpZCDCtyBzZXF1ZW5jZSBudW1iZXI8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjE5MiIgd2lkdGg9IjQzNiIgaGVpZ2h0PSIyMiIgcng9IjYiIHN0cm9rZS13aWR0aD0iMSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1OTgiIHk9IjIwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6OS41cHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiMzMzQxNTUiPnNhbWUgYWRhcHRlciBvbiBldmVyeSBQb3N0Z3JlU1FMIGhvc3Q8L3RleHQ+Cjwvc3ZnPg==)

![The adapter stores messages, receipt handles, receive counts and visibility times in PostgreSQL: one table per queue, and another table for each dead-letter queue. A background task removes messages past their retention. FIFO messages also store their message group and sequence number, and each group has at most one message in flight.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQ0IiB2aWV3Qm94PSIwIDAgODM2IDI0NCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgYWRhcHRlciBzdG9yZXMgbWVzc2FnZXMsIHJlY2VpcHQgaGFuZGxlcywgcmVjZWl2ZSBjb3VudHMgYW5kIHZpc2liaWxpdHkgdGltZXMgaW4gUG9zdGdyZVNRTDogb25lIHRhYmxlIHBlciBxdWV1ZSwgYW5kIGFub3RoZXIgdGFibGUgZm9yIGVhY2ggZGVhZC1sZXR0ZXIgcXVldWUuIEEgYmFja2dyb3VuZCB0YXNrIHJlbW92ZXMgbWVzc2FnZXMgcGFzdCB0aGVpciByZXRlbnRpb24uIEZJRk8gbWVzc2FnZXMgYWxzbyBzdG9yZSB0aGVpciBtZXNzYWdlIGdyb3VwIGFuZCBzZXF1ZW5jZSBudW1iZXIsIGFuZCBlYWNoIGdyb3VwIGhhcyBhdCBtb3N0IG9uZSBtZXNzYWdlIGluIGZsaWdodC4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+CjxtYXJrZXIgaWQ9InFhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2NDc0OGIiLz48L21hcmtlcj4KPC9kZWZzPgo8cmVjdCB4PSI4IiB5PSIyNCIgd2lkdGg9IjgyMCIgaGVpZ2h0PSIyMDYiIHJ4PSIxNiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSIyNiIgeT0iNDQiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiIj5DVVNUT01FUidTIENMT1VEPC90ZXh0Pgo8cmVjdCB4PSIyNCIgeT0iMTA0IiB3aWR0aD0iOTYiIGhlaWdodD0iNzYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzIiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNzIiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPlNRUyBTREs8L3RleHQ+Cjx0ZXh0IHg9IjcyIiB5PSIxNzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+dW5jaGFuZ2VkPC90ZXh0Pgo8bGluZSB4MT0iMTIwIiB5MT0iMTQyIiB4Mj0iMTUyIiB5Mj0iMTQyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjcWEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHJlY3QgeD0iMTU0IiB5PSIxMTIiIHdpZHRoPSIxNDAiIGhlaWdodD0iNjAiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMjI0IiB5PSIxMzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA3MDAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXNpemU6MTNweCI+VGVuc29yOSBhZGFwdGVyPC90ZXh0Pgo8dGV4dCB4PSIyMjQiIHk9IjE1NiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+c3RhdGUgaW4gUG9zdGdyZVNRTDwvdGV4dD4KPGxpbmUgeDE9IjI5NiIgeTE9IjE0MiIgeDI9IjM2MCIgeTI9IjE0MiIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3FhKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+Cjx0ZXh0IHg9IjMyOCIgeT0iMTM0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+U1FMPC90ZXh0Pgo8dGV4dCB4PSIzMjgiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjgiPnRva2VuIHNpZ24taW48L3RleHQ+CjxyZWN0IHg9IjM2NCIgeT0iNTgiIHdpZHRoPSI0NTYiIGhlaWdodD0iMTY0IiByeD0iMTMiIHN0cm9rZS13aWR0aD0iMS42IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjU5MSIgeT0iODIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTIuNXB4Ij5Qb3N0Z3JlU1FMPC90ZXh0Pgo8dGV4dCB4PSI1OTEiIHk9Ijk4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojOTRhM2I4Ij5vbmUgZGF0YWJhc2UgcGVyIGFwcGxpYW5jZSDCtyBvbmUgdGFibGUgcGVyIHF1ZXVlPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjExMCIgd2lkdGg9IjIwNiIgaGVpZ2h0PSI3NCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuMyIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0ODMiIHk9IjEzMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+bWVzc2FnZSByb3dzPC90ZXh0Pgo8dGV4dCB4PSI0ODMiIHk9IjE1NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPm9uZSByb3cgcGVyIG1lc3NhZ2U8L3RleHQ+Cjx0ZXh0IHg9IjQ4MyIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+Ym9keSDCtyBhdHRyaWJ1dGVzIMK3IHNlbmQgdGltZTwvdGV4dD4KPHJlY3QgeD0iNTk4IiB5PSIxMTAiIHdpZHRoPSIyMDYiIGhlaWdodD0iNzQiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iNzAxIiB5PSIxMzIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+RklGTyBncm91cHM8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTU0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5ncm91cCBpZCDCtyBzZXF1ZW5jZSBudW1iZXI8L3RleHQ+Cjx0ZXh0IHg9IjcwMSIgeT0iMTcyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3Ij5vbmUgbWVzc2FnZSBpbiBmbGlnaHQgcGVyIGdyb3VwPC90ZXh0Pgo8cmVjdCB4PSIzODAiIHk9IjE5MiIgd2lkdGg9IjQzNiIgaGVpZ2h0PSIyMiIgcng9IjYiIHN0cm9rZS13aWR0aD0iMSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1OTgiIHk9IjIwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6OS41cHggJ1NGIE1vbm8nLE1lbmxvLG1vbm9zcGFjZTtmaWxsOiNjYmQ1ZTEiPnNhbWUgYWRhcHRlciBvbiBldmVyeSBQb3N0Z3JlU1FMIGhvc3Q8L3RleHQ+Cjwvc3ZnPg==)

Each queue, including each dead-letter queue, is a PostgreSQL table. The same adapter runs on every supported PostgreSQL host.

#### Receiving messages

One database step selects messages whose visibility timeout has passed, oldest first, up to the requested batch size. In the same step it gives each a new receipt handle, hides it for the visibility timeout, adds one to its receive count and returns it. Messages another receiver is taking at that moment are skipped. FIFO queues return the next eligible message in each group, keeping one in flight per group. When the visibility timeout passes, the message can be delivered again; that does not stop a worker still processing the earlier copy.

`ApproximateReceiveCount` is the actual number of receives, not an estimate. The MD5 checksums of the body and attributes are recomputed, so your SDK's checks pass. `DelaySeconds` sets when a message first becomes visible. Long polling waits up to `WaitTimeSeconds` (at most 20 seconds) and returns as soon as a message is available. `SendMessageBatch` inserts all entries at once and reports a result for each entry. Message bodies are stored in the queue table.

![A receive takes the oldest visible messages and, in the same step, gives each a new receipt handle, hides it for the visibility timeout and adds one to its receive count. Two receivers at the same time get different messages. A message can be delivered again once its visibility timeout passes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIHJlY2VpdmUgdGFrZXMgdGhlIG9sZGVzdCB2aXNpYmxlIG1lc3NhZ2VzIGFuZCwgaW4gdGhlIHNhbWUgc3RlcCwgZ2l2ZXMgZWFjaCBhIG5ldyByZWNlaXB0IGhhbmRsZSwgaGlkZXMgaXQgZm9yIHRoZSB2aXNpYmlsaXR5IHRpbWVvdXQgYW5kIGFkZHMgb25lIHRvIGl0cyByZWNlaXZlIGNvdW50LiBUd28gcmVjZWl2ZXJzIGF0IHRoZSBzYW1lIHRpbWUgZ2V0IGRpZmZlcmVudCBtZXNzYWdlcy4gQSBtZXNzYWdlIGNhbiBiZSBkZWxpdmVyZWQgYWdhaW4gb25jZSBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0IHBhc3Nlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0icmEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJyZyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojMDQ3ODU3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPkZpbmQgdmlzaWJsZSBtZXNzYWdlczwvdGV4dD4KPHRleHQgeD0iNzYiIHk9Ijc5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+PHRzcGFuIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPnZpc2libGUgbm93PC90c3Bhbj4gwrcgb2xkZXN0IGZpcnN0PC90ZXh0Pgo8bGluZSB4MT0iMjAwIiB5MT0iOTAiIHgyPSIyMDAiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI3JhKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIzMDAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMi41cHgiPlNraXAgbWVzc2FnZXMgaW4gdXNlPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMTUzIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+dGFrZW4gYnkgYW5vdGhlciByZWNlaXZlcjwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9IjE2NCIgeDI9IjIwMCIgeTI9IjE4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjcmEpIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC1zaXplOjEycHgiPkhhbmQgb3V0IGluIHRoZSBzYW1lIHN0ZXA8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIyMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTciPm5ldyByZWNlaXB0IGhhbmRsZSDCtyBoaWRkZW48dHNwYW4geD0iNzYiIGR5PSIxMiI+cmVjZWl2ZSBjb3VudCArIDE8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iMzg4IiB5PSI0MiIgd2lkdGg9IjQyNCIgaGVpZ2h0PSIxOTYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iNjAwIiB5PSI2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+VFdPIENPTkNVUlJFTlQgUkVDRUlWRVJTPC90ZXh0Pgo8cmVjdCB4PSI0MDQiIHk9Ijc4IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjI0IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz48dGV4dCB4PSI0NzkiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEEgZ2V0cyBtMTwvdGV4dD4KPHJlY3QgeD0iNDA0IiB5PSIxMDgiIHdpZHRoPSIxNTAiIGhlaWdodD0iMjQiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6I2VjZmRmNTtzdHJva2U6IzA0Nzg1NyIvPjx0ZXh0IHg9IjQ3OSIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEIgZ2V0cyBtMjwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSI3OCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz48dGV4dCB4PSI2MTIiIHk9IjkzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5tMSAgaW4gZmxpZ2h0IChBKTwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxMDQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+PHRleHQgeD0iNjEyIiB5PSIxMTkiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPm0yICBpbiBmbGlnaHQgKEIpPC90ZXh0Pgo8cmVjdCB4PSI2MDAiIHk9IjEzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz48dGV4dCB4PSI2MTIiIHk9IjE0NSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzY0NzQ4YiI+bTMgIHZpc2libGUgwrcgbmV4dDwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxNTYiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+PHRleHQgeD0iNjEyIiB5PSIxNzEiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiM2NDc0OGIiPm00ICB2aXNpYmxlIMK3IG5leHQ8L3RleHQ+CjxsaW5lIHgxPSI1NTYiIHkxPSI5MCIgeDI9IjU5NiIgeTI9Ijg4IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8bGluZSB4MT0iNTU2IiB5MT0iMTIwIiB4Mj0iNTk2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8cmVjdCB4PSI0MDQiIHk9IjE5NiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzMCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjYwMCIgeT0iMjE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmVhY2ggcmVjZWl2ZXIgZ2V0cyBkaWZmZXJlbnQgbWVzc2FnZXM8L3RleHQ+Cjwvc3ZnPg==)

![A receive takes the oldest visible messages and, in the same step, gives each a new receipt handle, hides it for the visibility timeout and adds one to its receive count. Two receivers at the same time get different messages. A message can be delivered again once its visibility timeout passes.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJBIHJlY2VpdmUgdGFrZXMgdGhlIG9sZGVzdCB2aXNpYmxlIG1lc3NhZ2VzIGFuZCwgaW4gdGhlIHNhbWUgc3RlcCwgZ2l2ZXMgZWFjaCBhIG5ldyByZWNlaXB0IGhhbmRsZSwgaGlkZXMgaXQgZm9yIHRoZSB2aXNpYmlsaXR5IHRpbWVvdXQgYW5kIGFkZHMgb25lIHRvIGl0cyByZWNlaXZlIGNvdW50LiBUd28gcmVjZWl2ZXJzIGF0IHRoZSBzYW1lIHRpbWUgZ2V0IGRpZmZlcmVudCBtZXNzYWdlcy4gQSBtZXNzYWdlIGNhbiBiZSBkZWxpdmVyZWQgYWdhaW4gb25jZSBpdHMgdmlzaWJpbGl0eSB0aW1lb3V0IHBhc3Nlcy4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0icmEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPgo8bWFya2VyIGlkPSJyZyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNmVlN2I3Ii8+PC9tYXJrZXI+PC9kZWZzPgo8Y2lyY2xlIGN4PSI0MCIgY3k9IjYwIiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MTwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjQyIiB3aWR0aD0iMzAwIiBoZWlnaHQ9IjQ4IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9Ijc2IiB5PSI2MiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPkZpbmQgdmlzaWJsZSBtZXNzYWdlczwvdGV4dD4KPHRleHQgeD0iNzYiIHk9Ijc5IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+PHRzcGFuIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPnZpc2libGUgbm93PC90c3Bhbj4gwrcgb2xkZXN0IGZpcnN0PC90ZXh0Pgo8bGluZSB4MT0iMjAwIiB5MT0iOTAiIHgyPSIyMDAiIHkyPSIxMTIiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI3JhKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxjaXJjbGUgY3g9IjQwIiBjeT0iMTM0IiByPSIxMyIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0MCIgeT0iMTM4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPjI8L3RleHQ+CjxyZWN0IHg9IjYyIiB5PSIxMTYiIHdpZHRoPSIzMDAiIGhlaWdodD0iNDgiIHJ4PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNzYiIHk9IjEzNiIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMi41cHgiPlNraXAgbWVzc2FnZXMgaW4gdXNlPC90ZXh0Pgo8dGV4dCB4PSI3NiIgeT0iMTUzIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+dGFrZW4gYnkgYW5vdGhlciByZWNlaXZlcjwvdGV4dD4KPGxpbmUgeDE9IjIwMCIgeTE9IjE2NCIgeDI9IjIwMCIgeTI9IjE4NiIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjcmEpIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPGNpcmNsZSBjeD0iNDAiIGN5PSIyMDgiIHI9IjEzIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjQwIiB5PSIyMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+MzwvdGV4dD4KPHJlY3QgeD0iNjIiIHk9IjE5MCIgd2lkdGg9IjMwMCIgaGVpZ2h0PSI0OCIgcng9IjEwIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI3NiIgeT0iMjEwIiBzdHlsZT0iZm9udDogNzAwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC1zaXplOjEycHgiPkhhbmQgb3V0IGluIHRoZSBzYW1lIHN0ZXA8L3RleHQ+Cjx0ZXh0IHg9Ijc2IiB5PSIyMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3YjciPm5ldyByZWNlaXB0IGhhbmRsZSDCtyBoaWRkZW48dHNwYW4geD0iNzYiIGR5PSIxMiI+cmVjZWl2ZSBjb3VudCArIDE8L3RzcGFuPjwvdGV4dD4KPHJlY3QgeD0iMzg4IiB5PSI0MiIgd2lkdGg9IjQyNCIgaGVpZ2h0PSIxOTYiIHJ4PSIxMiIgc3Ryb2tlLXdpZHRoPSIxLjMiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iNjAwIiB5PSI2NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+VFdPIENPTkNVUlJFTlQgUkVDRUlWRVJTPC90ZXh0Pgo8cmVjdCB4PSI0MDQiIHk9Ijc4IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjI0IiByeD0iNiIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz48dGV4dCB4PSI0NzkiIHk9Ijk0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEEgZ2V0cyBtMTwvdGV4dD4KPHJlY3QgeD0iNDA0IiB5PSIxMDgiIHdpZHRoPSIxNTAiIGhlaWdodD0iMjQiIHJ4PSI2IiBzdHJva2Utd2lkdGg9IjEuMiIgc3R5bGU9ImZpbGw6IzA2NGUzYjtzdHJva2U6IzZlZTdiNyIvPjx0ZXh0IHg9IjQ3OSIgeT0iMTI0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPlJlY2VpdmVyIEIgZ2V0cyBtMjwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSI3OCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz48dGV4dCB4PSI2MTIiIHk9IjkzIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5tMSAgaW4gZmxpZ2h0IChBKTwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxMDQiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+PHRleHQgeD0iNjEyIiB5PSIxMTkiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPm0yICBpbiBmbGlnaHQgKEIpPC90ZXh0Pgo8cmVjdCB4PSI2MDAiIHk9IjEzMCIgd2lkdGg9IjE5NiIgaGVpZ2h0PSIyMiIgcng9IjUiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz48dGV4dCB4PSI2MTIiIHk9IjE0NSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6Izk0YTNiOCI+bTMgIHZpc2libGUgwrcgbmV4dDwvdGV4dD4KPHJlY3QgeD0iNjAwIiB5PSIxNTYiIHdpZHRoPSIxOTYiIGhlaWdodD0iMjIiIHJ4PSI1IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+PHRleHQgeD0iNjEyIiB5PSIxNzEiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiM5NGEzYjgiPm00ICB2aXNpYmxlIMK3IG5leHQ8L3RleHQ+CjxsaW5lIHgxPSI1NTYiIHkxPSI5MCIgeDI9IjU5NiIgeTI9Ijg4IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8bGluZSB4MT0iNTU2IiB5MT0iMTIwIiB4Mj0iNTk2IiB5Mj0iMTE0IiBzdHJva2Utd2lkdGg9IjEuNiIgbWFya2VyLWVuZD0idXJsKCNyZykiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8cmVjdCB4PSI0MDQiIHk9IjE5NiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzMCIgcng9IjgiIHN0cm9rZS13aWR0aD0iMS4yIiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjYwMCIgeT0iMjE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmVhY2ggcmVjZWl2ZXIgZ2V0cyBkaWZmZXJlbnQgbWVzc2FnZXM8L3RleHQ+Cjwvc3ZnPg==)

Two receivers never get the same message at the same time. ApproximateReceiveCount is the actual receive count.

#### Receipt handles & visibility

Each receive saves a new receipt handle with the message. `DeleteMessage` and `ChangeMessageVisibility` find the message by that handle, including after an adapter restart or through another adapter instance.

A delete or visibility change whose handle matches no message returns `ReceiptHandleIsInvalid`. That includes a message already deleted, or received again under a newer handle. The visibility timeout defaults to 30 seconds. `ChangeMessageVisibility` can extend it with no lock-duration maximum, and zero makes the message available again immediately. Retention can delete a message while it is in flight.

![The receipt handle is saved with the message in PostgreSQL and survives adapter restart. Visibility uses a stored deadline within SQS bounds, without a broker lock ceiling.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgcmVjZWlwdCBoYW5kbGUgaXMgc2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMIGFuZCBzdXJ2aXZlcyBhZGFwdGVyIHJlc3RhcnQuIFZpc2liaWxpdHkgdXNlcyBhIHN0b3JlZCBkZWFkbGluZSB3aXRoaW4gU1FTIGJvdW5kcywgd2l0aG91dCBhIGJyb2tlciBsb2NrIGNlaWxpbmcuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InZhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIyNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzA0Nzg1NyI+UkVDRUlQVCBIQU5ETEVTIFNVUlZJVkUgUkVTVEFSVFM8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSIzOCIgd2lkdGg9IjM2MCIgaGVpZ2h0PSIxNDIiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMzI0IiBoZWlnaHQ9IjM0IiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNhN2YzZDAiLz4KPHRleHQgeD0iMjA2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+cmVjZWlwdCBoYW5kbGUgPSAzZjJh4oCmLTkxYTI8L3RleHQ+Cjx0ZXh0IHg9IjIwNiIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+c2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMPC90ZXh0Pgo8bGluZSB4MT0iMjA2IiB5MT0iMTIwIiB4Mj0iMjA2IiB5Mj0iMTM2IiBzdHJva2Utd2lkdGg9IjEuNiIgc3Ryb2tlLWRhc2hhcnJheT0iMyAzIiBzdHlsZT0ic3Ryb2tlOiM5NGEzYjgiLz4KPHRleHQgeD0iMjA2IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+YWRhcHRlciByZXN0YXJ0czwvdGV4dD4KPHRleHQgeD0iMjA2IiB5PSIxNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NyI+RGVsZXRlTWVzc2FnZSBhbmQgQ2hhbmdlTWVzc2FnZVZpc2liaWxpdHkgc3RpbGwgd29yazwvdGV4dD4KPGxpbmUgeDE9IjM5OCIgeTE9IjM0IiB4Mj0iMzk4IiB5Mj0iMTg0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQyNCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM2NDc0OGIiPk5PIFZJU0lCSUxJVFkgQ0FQPC90ZXh0Pgo8cmVjdCB4PSI0MjQiIHk9IjM4IiB3aWR0aD0iMzg2IiBoZWlnaHQ9IjE0MiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8bGluZSB4MT0iNDQ2IiB5MT0iMTA0IiB4Mj0iODA2IiB5Mj0iMTA0IiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6I2NiZDVlMSIvPgo8cmVjdCB4PSI0NDYiIHk9Ijg4IiB3aWR0aD0iNzgiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNhN2YzZDA7c3Ryb2tlOiMwNDc4NTciLz4KPHJlY3QgeD0iNTI4IiB5PSI4OCIgd2lkdGg9Ijc4IiBoZWlnaHQ9IjE4IiByeD0iNCIgc3Ryb2tlLXdpZHRoPSIxIiBzdHlsZT0iZmlsbDojYTdmM2QwO3N0cm9rZTojMDQ3ODU3Ii8+CjxyZWN0IHg9IjYxMCIgeT0iODgiIHdpZHRoPSIxMjAiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNDc4NTc7c3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjczNCIgeTE9Ijk3IiB4Mj0iODAwIiB5Mj0iOTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCN2YSkiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI0ODQiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YiI+dGltZW91dDwvdGV4dD4KPHRleHQgeD0iNTY2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNjY4IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNzcyIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZWQgdGltZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5DaGFuZ2VNZXNzYWdlVmlzaWJpbGl0eSB1cGRhdGVzIHRoZSBkZWFkbGluZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxNTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM2NDc0OGIiPihubyBtZXNzYWdlLWxvY2sgdGltZSBsaW1pdCk8L3RleHQ+Cjwvc3ZnPg==)

![The receipt handle is saved with the message in PostgreSQL and survives adapter restart. Visibility uses a stored deadline within SQS bounds, without a broker lock ceiling.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJUaGUgcmVjZWlwdCBoYW5kbGUgaXMgc2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMIGFuZCBzdXJ2aXZlcyBhZGFwdGVyIHJlc3RhcnQuIFZpc2liaWxpdHkgdXNlcyBhIHN0b3JlZCBkZWFkbGluZSB3aXRoaW4gU1FTIGJvdW5kcywgd2l0aG91dCBhIGJyb2tlciBsb2NrIGNlaWxpbmcuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InZhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj48L2RlZnM+Cjx0ZXh0IHg9IjI2IiB5PSIyNiIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzZlZTdiNyI+UkVDRUlQVCBIQU5ETEVTIFNVUlZJVkUgUkVTVEFSVFM8L3RleHQ+CjxyZWN0IHg9IjI2IiB5PSIzOCIgd2lkdGg9IjM2MCIgaGVpZ2h0PSIxNDIiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNDQiIHk9IjU4IiB3aWR0aD0iMzI0IiBoZWlnaHQ9IjM0IiByeD0iOCIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMjA2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+cmVjZWlwdCBoYW5kbGUgPSAzZjJh4oCmLTkxYTI8L3RleHQ+Cjx0ZXh0IHg9IjIwNiIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+c2F2ZWQgd2l0aCB0aGUgbWVzc2FnZSBpbiBQb3N0Z3JlU1FMPC90ZXh0Pgo8bGluZSB4MT0iMjA2IiB5MT0iMTIwIiB4Mj0iMjA2IiB5Mj0iMTM2IiBzdHJva2Utd2lkdGg9IjEuNiIgc3Ryb2tlLWRhc2hhcnJheT0iMyAzIiBzdHlsZT0ic3Ryb2tlOiM2NDc0OGIiLz4KPHRleHQgeD0iMjA2IiB5PSIxNDAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+YWRhcHRlciByZXN0YXJ0czwvdGV4dD4KPHRleHQgeD0iMjA2IiB5PSIxNjQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNyI+RGVsZXRlTWVzc2FnZSBhbmQgQ2hhbmdlTWVzc2FnZVZpc2liaWxpdHkgc3RpbGwgd29yazwvdGV4dD4KPGxpbmUgeDE9IjM5OCIgeTE9IjM0IiB4Mj0iMzk4IiB5Mj0iMTg0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9InN0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQyNCIgeT0iMjYiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiM5NGEzYjgiPk5PIFZJU0lCSUxJVFkgQ0FQPC90ZXh0Pgo8cmVjdCB4PSI0MjQiIHk9IjM4IiB3aWR0aD0iMzg2IiBoZWlnaHQ9IjE0MiIgcng9IjE0IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8bGluZSB4MT0iNDQ2IiB5MT0iMTA0IiB4Mj0iODA2IiB5Mj0iMTA0IiBzdHJva2Utd2lkdGg9IjIiIHN0eWxlPSJzdHJva2U6IzQ3NTU2OSIvPgo8cmVjdCB4PSI0NDYiIHk9Ijg4IiB3aWR0aD0iNzgiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNDc4NTc7c3Ryb2tlOiM2ZWU3YjciLz4KPHJlY3QgeD0iNTI4IiB5PSI4OCIgd2lkdGg9Ijc4IiBoZWlnaHQ9IjE4IiByeD0iNCIgc3Ryb2tlLXdpZHRoPSIxIiBzdHlsZT0iZmlsbDojMDQ3ODU3O3N0cm9rZTojNmVlN2I3Ii8+CjxyZWN0IHg9IjYxMCIgeT0iODgiIHdpZHRoPSIxMjAiIGhlaWdodD0iMTgiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiM2ZWU3Yjc7c3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjczNCIgeTE9Ijk3IiB4Mj0iODAwIiB5Mj0iOTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCN2YSkiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI0ODQiIHk9IjgwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiOCI+dGltZW91dDwvdGV4dD4KPHRleHQgeD0iNTY2IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNjY4IiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+K2V4dGVuZDwvdGV4dD4KPHRleHQgeD0iNzcyIiB5PSI4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwIj5zdG9yZWQgdGltZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxMzQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5DaGFuZ2VNZXNzYWdlVmlzaWJpbGl0eSB1cGRhdGVzIHRoZSBkZWFkbGluZTwvdGV4dD4KPHRleHQgeD0iNjE3IiB5PSIxNTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM5NGEzYjgiPihubyBtZXNzYWdlLWxvY2sgdGltZSBsaW1pdCk8L3RleHQ+Cjwvc3ZnPg==)

Receipt handles are saved with messages, so they still work after an adapter restart. Visibility has no lock-duration limit.

#### Dead-letter & retention

When source and DLQ belong to the same supported SQS-owned message database transaction, receive moves messages at `maxReceiveCount` atomically with claiming the rest. Both changes commit or neither does. Cross-database/store transfers are unsupported: sharing a provider, physical server or control log is not a shared message transaction, and no other service's tables are used. The DLQ retains ordinary queue operations and cleanup. A FIFO move creates a new message in the DLQ, with a new `MessageId`, a receive count of zero and a new send time.

A background task deletes messages sent longer ago than the queue's retention period, including messages in flight; receiving does not reset that time. The retention period defaults to four days and is kept between 60 seconds and 14 days, so a missing or too-short value cannot delete new messages straight away. One worker per database removes expired messages in batches, pauses during database maintenance, and continues if one queue fails. Limits on rows per pass and time per batch cap the load.

![Within the same supported SQS-owned message database transaction, receive moves exhausted messages to the DLQ and hands out the rest. Cross-database/store moves are unsupported. Background cleanup enforces retention; consumers still tolerate redelivery.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJXaXRoaW4gdGhlIHNhbWUgc3VwcG9ydGVkIFNRUy1vd25lZCBtZXNzYWdlIGRhdGFiYXNlIHRyYW5zYWN0aW9uLCByZWNlaXZlIG1vdmVzIGV4aGF1c3RlZCBtZXNzYWdlcyB0byB0aGUgRExRIGFuZCBoYW5kcyBvdXQgdGhlIHJlc3QuIENyb3NzLWRhdGFiYXNlL3N0b3JlIG1vdmVzIGFyZSB1bnN1cHBvcnRlZC4gQmFja2dyb3VuZCBjbGVhbnVwIGVuZm9yY2VzIHJldGVudGlvbjsgY29uc3VtZXJzIHN0aWxsIHRvbGVyYXRlIHJlZGVsaXZlcnkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImRhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiMwNDc4NTciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2RjMjYyNiIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5ERUFELUxFVFRFUiBNT1ZFIElOIE9ORSBUUkFOU0FDVElPTjwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjEwMSIgeT0iNTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTFweCI+bWVzc2FnZXMgZHVlPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzMzNDE1NTsgZmlsbDojMzM0MTU1Ij5vbmUgdHJhbnNhY3Rpb248L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI1MCIgeDI9IjIxMiIgeTI9IjUwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNkeCkiIHN0eWxlPSJzdHJva2U6I2RjMjYyNiIvPgo8dGV4dCB4PSIxOTQiIHk9IjQzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZmlsbDojZGMyNjI2Ij7iiaUgbWF4PC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNzQiIHgyPSIyMTIiIHkyPSI3NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZGEpIiBzdHlsZT0ic3Ryb2tlOiMwNDc4NTciLz4KPHRleHQgeD0iMTk0IiB5PSI5MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZpbGw6IzA0Nzg1NyI+Jmx0OyBtYXg8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iMzIiIHdpZHRoPSIyMjIiIGhlaWdodD0iMzIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6I2ZmZmJlYjtzdHJva2U6I2ZkZTY4YSIvPgo8dGV4dCB4PSIzMjUiIHk9IjUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTFweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2I0NTMwOSI+bW92ZSB0byBkZWFkLWxldHRlciBxdWV1ZTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI2NiIgd2lkdGg9IjIyMiIgaGVpZ2h0PSIzMCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjMyNSIgeT0iODUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+cmV0dXJuZWQgdG8gdGhlIHJlY2VpdmVyPC90ZXh0Pgo8cmVjdCB4PSI0NTIiIHk9IjMyIiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjY0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjYzMSIgeT0iNTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTFweCI+b25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI2MzEiIHk9Ijc5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPm1vdmUgYW5kIHJlY2VpdmUgc3VjY2VlZCB0b2dldGhlcjwvdGV4dD4KPHRleHQgeD0iMjYiIHk9IjEyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzY0NzQ4YiI+UkVURU5USU9OIENMRUFOVVAgwrcgT04gU0VORCBUSU1FPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTM4IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+CjxyZWN0IHg9IjYwIiB5PSIxNjYiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNmZWYyZjI7c3Ryb2tlOiNkYzI2MjYiLz4KPHJlY3QgeD0iNDIwIiB5PSIxNjYiIHdpZHRoPSIzNTAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiNlY2ZkZjU7c3Ryb2tlOiMwNDc4NTciLz4KPGxpbmUgeDE9IjQyMCIgeTE9IjE1NiIgeDI9IjQyMCIgeTI9IjE5OCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQgMyIgc3R5bGU9InN0cm9rZTojMzM0MTU1Ii8+Cjx0ZXh0IHg9IjQyMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZmlsbDojMzM0MTU1Ij5ub3cg4oiSIHJldGVudGlvbjwvdGV4dD4KPHRleHQgeD0iMjQwIiB5PSIxODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiNkYzI2MjYiPnNlbmQgdGltZSBiZWZvcmUgY3V0b2ZmIOKGkiByZW1vdmVkPC90ZXh0Pgo8dGV4dCB4PSI1OTUiIHk9IjE4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICMzMzQxNTU7IGZpbGw6IzA0Nzg1NyI+d2l0aGluIHJldGVudGlvbiDihpIga2VwdDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5yZXRlbnRpb24gNjBzLTE0ZCDCtyBiYXRjaGVkIGNsZWFudXAgwrcgb25lIHdvcmtlciBwZXIgZGF0YWJhc2UgwrcgYmFja3Mgb2ZmIGR1cmluZyBtYWludGVuYW5jZTwvdGV4dD4KPC9zdmc+)

![Within the same supported SQS-owned message database transaction, receive moves exhausted messages to the DLQ and hands out the rest. Cross-database/store moves are unsupported. Background cleanup enforces retention; consumers still tolerate redelivery.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJXaXRoaW4gdGhlIHNhbWUgc3VwcG9ydGVkIFNRUy1vd25lZCBtZXNzYWdlIGRhdGFiYXNlIHRyYW5zYWN0aW9uLCByZWNlaXZlIG1vdmVzIGV4aGF1c3RlZCBtZXNzYWdlcyB0byB0aGUgRExRIGFuZCBoYW5kcyBvdXQgdGhlIHJlc3QuIENyb3NzLWRhdGFiYXNlL3N0b3JlIG1vdmVzIGFyZSB1bnN1cHBvcnRlZC4gQmFja2dyb3VuZCBjbGVhbnVwIGVuZm9yY2VzIHJldGVudGlvbjsgY29uc3VtZXJzIHN0aWxsIHRvbGVyYXRlIHJlZGVsaXZlcnkuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImRhIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjgiIHJlZlk9IjUiIG1hcmtlcldpZHRoPSI3IiBtYXJrZXJIZWlnaHQ9IjciIG9yaWVudD0iYXV0by1zdGFydC1yZXZlcnNlIj48cGF0aCBkPSJNMCwwIEwxMCw1IEwwLDEwIHoiIHN0eWxlPSJmaWxsOiM2ZWU3YjciLz48L21hcmtlcj4KPG1hcmtlciBpZD0iZHgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6I2Y4NzE3MSIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5ERUFELUxFVFRFUiBNT1ZFIElOIE9ORSBUUkFOU0FDVElPTjwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjU0IiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjEwMSIgeT0iNTUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTFweCI+bWVzc2FnZXMgZHVlPC90ZXh0Pgo8dGV4dCB4PSIxMDEiIHk9IjczIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2NiZDVlMTsgZmlsbDojY2JkNWUxIj5vbmUgdHJhbnNhY3Rpb248L3RleHQ+CjxsaW5lIHgxPSIxNzYiIHkxPSI1MCIgeDI9IjIxMiIgeTI9IjUwIiBzdHJva2Utd2lkdGg9IjEuOCIgbWFya2VyLWVuZD0idXJsKCNkeCkiIHN0eWxlPSJzdHJva2U6I2Y4NzE3MSIvPgo8dGV4dCB4PSIxOTQiIHk9IjQzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZmlsbDojZjg3MTcxIj7iiaUgbWF4PC90ZXh0Pgo8bGluZSB4MT0iMTc2IiB5MT0iNzQiIHgyPSIyMTIiIHkyPSI3NCIgc3Ryb2tlLXdpZHRoPSIxLjgiIG1hcmtlci1lbmQ9InVybCgjZGEpIiBzdHlsZT0ic3Ryb2tlOiM2ZWU3YjciLz4KPHRleHQgeD0iMTk0IiB5PSI5MiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZpbGw6IzZlZTdiNyI+Jmx0OyBtYXg8L3RleHQ+CjxyZWN0IHg9IjIxNCIgeT0iMzIiIHdpZHRoPSIyMjIiIGhlaWdodD0iMzIiIHJ4PSI5IiBzdHJva2Utd2lkdGg9IjEuNCIgc3R5bGU9ImZpbGw6IzQyMjAwNjtzdHJva2U6IzkyNDAwZSIvPgo8dGV4dCB4PSIzMjUiIHk9IjUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDo2MDAgMTFweCBJbnRlcixzYW5zLXNlcmlmO2ZpbGw6I2ZiYmYyNCI+bW92ZSB0byBkZWFkLWxldHRlciBxdWV1ZTwvdGV4dD4KPHJlY3QgeD0iMjE0IiB5PSI2NiIgd2lkdGg9IjIyMiIgaGVpZ2h0PSIzMCIgcng9IjkiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjMyNSIgeT0iODUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+cmV0dXJuZWQgdG8gdGhlIHJlY2VpdmVyPC90ZXh0Pgo8cmVjdCB4PSI0NTIiIHk9IjMyIiB3aWR0aD0iMzU4IiBoZWlnaHQ9IjY0IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjYzMSIgeT0iNTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjZjFmNWY5OyBmb250LXNpemU6MTFweCI+b25lIHRyYW5zYWN0aW9uPC90ZXh0Pgo8dGV4dCB4PSI2MzEiIHk9Ijc5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPm1vdmUgYW5kIHJlY2VpdmUgc3VjY2VlZCB0b2dldGhlcjwvdGV4dD4KPHRleHQgeD0iMjYiIHk9IjEyOCIgc3R5bGU9ImZvbnQ6IDcwMCAxMHB4IEludGVyLCBzYW5zLXNlcmlmOyBsZXR0ZXItc3BhY2luZzogMS4zcHg7IGZpbGw6ICM2NDc0OGI7IGZpbGw6Izk0YTNiOCI+UkVURU5USU9OIENMRUFOVVAgwrcgT04gU0VORCBUSU1FPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTM4IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjkyIiByeD0iMTIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+CjxyZWN0IHg9IjYwIiB5PSIxNjYiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiM0NTBhMGE7c3Ryb2tlOiNmODcxNzEiLz4KPHJlY3QgeD0iNDIwIiB5PSIxNjYiIHdpZHRoPSIzNTAiIGhlaWdodD0iMjAiIHJ4PSI0IiBzdHJva2Utd2lkdGg9IjEiIHN0eWxlPSJmaWxsOiMwNjRlM2I7c3Ryb2tlOiM2ZWU3YjciLz4KPGxpbmUgeDE9IjQyMCIgeTE9IjE1NiIgeDI9IjQyMCIgeTI9IjE5OCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjQgMyIgc3R5bGU9InN0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQyMCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZmlsbDojY2JkNWUxIj5ub3cg4oiSIHJldGVudGlvbjwvdGV4dD4KPHRleHQgeD0iMjQwIiB5PSIxODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNmODcxNzEiPnNlbmQgdGltZSBiZWZvcmUgY3V0b2ZmIOKGkiByZW1vdmVkPC90ZXh0Pgo8dGV4dCB4PSI1OTUiIHk9IjE4MCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjYmQ1ZTE7IGZpbGw6IzZlZTdiNyI+d2l0aGluIHJldGVudGlvbiDihpIga2VwdDwvdGV4dD4KPHRleHQgeD0iNDE4IiB5PSIyMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5yZXRlbnRpb24gNjBzLTE0ZCDCtyBiYXRjaGVkIGNsZWFudXAgwrcgb25lIHdvcmtlciBwZXIgZGF0YWJhc2UgwrcgYmFja3Mgb2ZmIGR1cmluZyBtYWludGVuYW5jZTwvdGV4dD4KPC9zdmc+)

Atomic DLQ moves require the same supported SQS-owned database transaction. Cross-store moves are unsupported. Retention cleanup removes aged messages.

#### FIFO ordering & dedup

A FIFO queue stores each message's `MessageGroupId` and orders delivery within each group. A receive returns only the oldest message of each group that has nothing in flight (no message in that group is currently received and still hidden). Because arrival positions only increase, that is always the group's next message, and exactly one message is in flight per group at a time. Groups are independent, so different receivers can process different groups at once, coordinated only by PostgreSQL. When a message's visibility timeout passes, it is first in its group again, so a redelivery stays in sequence.

Each FIFO send requires `MessageGroupId` and returns a `SequenceNumber`: the message's arrival position as a 20-digit, zero-padded number.

Deduplication markers live in a separate PostgreSQL table keyed by queue and deduplication ID. An explicit `MessageDeduplicationId` takes precedence; otherwise, on a queue with content-based deduplication, the key is the SHA-256 of the body, excluding attributes. The message insert and deduplication marker are part of one transaction. A duplicate within 5 minutes saves no new message and returns the original `MessageId` and `SequenceNumber`. Marker retention is independent of message retention, so receiving or deleting the original does not shorten the deduplication window.

While a message is in flight, no other message from its group is delivered until it is deleted or its visibility timeout passes. That does not stop a timed-out worker from finishing a message it already received, so consumers must make repeated processing safe.

![FIFO receives deliver the next message of each group that has nothing in flight. Each send returns a 20-digit, zero-padded sequence number. Explicit or content-based deduplication is recorded in a separate PostgreSQL table with a five-minute window; a repeated send returns the original message ID and sequence number.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJGSUZPIHJlY2VpdmVzIGRlbGl2ZXIgdGhlIG5leHQgbWVzc2FnZSBvZiBlYWNoIGdyb3VwIHRoYXQgaGFzIG5vdGhpbmcgaW4gZmxpZ2h0LiBFYWNoIHNlbmQgcmV0dXJucyBhIDIwLWRpZ2l0LCB6ZXJvLXBhZGRlZCBzZXF1ZW5jZSBudW1iZXIuIEV4cGxpY2l0IG9yIGNvbnRlbnQtYmFzZWQgZGVkdXBsaWNhdGlvbiBpcyByZWNvcmRlZCBpbiBhIHNlcGFyYXRlIFBvc3RncmVTUUwgdGFibGUgd2l0aCBhIGZpdmUtbWludXRlIHdpbmRvdzsgYSByZXBlYXRlZCBzZW5kIHJldHVybnMgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgSUQgYW5kIHNlcXVlbmNlIG51bWJlci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiMzMzQxNTV9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZnMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6Izk0YTNiOCIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PUkRFUiBXSVRISU4gQSBHUk9VUDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojZjhmYWZjO3N0cm9rZTojY2JkNWUxIi8+Cjx0ZXh0IHg9IjQwIiB5PSI1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA0Nzg1NzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6IzMzNDE1NSI+bWVzc2FnZXMgb3JkZXJlZCB3aXRoaW4gZWFjaCBncm91cDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjcxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMzM0MTU1Ij5lYWNoIGdyb3VwJ3Mgb2xkZXN0IG1lc3NhZ2UsIGlmIG5vdGhpbmcgaW4gZmxpZ2h0ICDihpIgIGRlbGl2ZXJlZDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9Ijg3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+U2VxdWVuY2VOdW1iZXI6IDIwIGRpZ2l0cywgemVyby1wYWRkZWQsIGFsd2F5cyBpbmNyZWFzaW5nPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQwIiB5PSIxMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNDc4NTc7IGZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgb3JkZXJzPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMDQ3ODU3Ij5tNDEgKGhlYWQsIGluIGZsaWdodCkgwrcgbTQyIMK3IG00MyDigKY8L3RleHQ+Cjx0ZXh0IHg9IjQwIiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5vbmUgaW4gZmxpZ2h0IMK3IG00MiB3YWl0cyB1bnRpbCBtNDEgaXMgZGVsZXRlZCBvciB0aW1lcyBvdXQ8L3RleHQ+CjxyZWN0IHg9IjQzMCIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojZWNmZGY1O3N0cm9rZTojMDQ3ODU3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTIzIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmb250LXdlaWdodDo3MDAiPmdyb3VwIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojMDQ3ODU3Ij5tNTggKGhlYWQsIGluIGZsaWdodCkgwrcgbTU5IOKApjwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5ncm91cHMgYXJlIGNvbmN1cnJlbnQgwrcgYSBkaWZmZXJlbnQgcmVjZWl2ZXIgZHJhaW5zIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjI2IiB5PSIxOTAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiNiNDUzMDkiPkRFRFVQTElDQVRJT04gwrcgNS1NSU5VVEUgV0lORE9XPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTk2IiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMTUxIiB5PSIyMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjMzM0MTU1OyBmaWxsOiMzMzQxNTUiPmV4cGxpY2l0IElEIG9yIFNIQS0yNTYoYm9keSk8L3RleHQ+CjxsaW5lIHgxPSIyNzYiIHkxPSIyMTYiIHgyPSIzMTIiIHkyPSIyMTYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZzKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+CjxyZWN0IHg9IjMxNCIgeT0iMTk2IiB3aWR0aD0iNDk2IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiNmZmZiZWI7c3Ryb2tlOiNmZGU2OGEiLz4KPHRleHQgeD0iNTYyIiB5PSIyMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojYjQ1MzA5Ij5yZXBlYXQgcmV0dXJucyBvcmlnaW5hbCBJRHM8L3RleHQ+Cjx0ZXh0IHg9IjU2MiIgeT0iMjI5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YjsgZmlsbDojYjQ1MzA5Ij5tZXNzYWdlIGFuZCBkZWR1cCBtYXJrZXIgc2F2ZWQgdG9nZXRoZXI8L3RleHQ+Cjwvc3ZnPg==)

![FIFO receives deliver the next message of each group that has nothing in flight. Each send returns a 20-digit, zero-padded sequence number. Explicit or content-based deduplication is recorded in a separate PostgreSQL table with a five-minute window; a repeated send returns the original message ID and sequence number.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjQwIiB2aWV3Qm94PSIwIDAgODM2IDI0MCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJGSUZPIHJlY2VpdmVzIGRlbGl2ZXIgdGhlIG5leHQgbWVzc2FnZSBvZiBlYWNoIGdyb3VwIHRoYXQgaGFzIG5vdGhpbmcgaW4gZmxpZ2h0LiBFYWNoIHNlbmQgcmV0dXJucyBhIDIwLWRpZ2l0LCB6ZXJvLXBhZGRlZCBzZXF1ZW5jZSBudW1iZXIuIEV4cGxpY2l0IG9yIGNvbnRlbnQtYmFzZWQgZGVkdXBsaWNhdGlvbiBpcyByZWNvcmRlZCBpbiBhIHNlcGFyYXRlIFBvc3RncmVTUUwgdGFibGUgd2l0aCBhIGZpdmUtbWludXRlIHdpbmRvdzsgYSByZXBlYXRlZCBzZW5kIHJldHVybnMgdGhlIG9yaWdpbmFsIG1lc3NhZ2UgSUQgYW5kIHNlcXVlbmNlIG51bWJlci4iPjxzdHlsZT50ZXh0e2ZvbnQtZmFtaWx5OkludGVyLC1hcHBsZS1zeXN0ZW0sQmxpbmtNYWNTeXN0ZW1Gb250LCdTZWdvZSBVSScsUm9ib3RvLCdIZWx2ZXRpY2EgTmV1ZScsQXJpYWwsc2Fucy1zZXJpZjtmaWxsOiNjYmQ1ZTF9PC9zdHlsZT4KPGRlZnM+PG1hcmtlciBpZD0iZnMiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgc3R5bGU9ImZpbGw6IzY0NzQ4YiIvPjwvbWFya2VyPjwvZGVmcz4KPHRleHQgeD0iMjYiIHk9IjI0IiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PUkRFUiBXSVRISU4gQSBHUk9VUDwvdGV4dD4KPHJlY3QgeD0iMjYiIHk9IjM0IiB3aWR0aD0iNzg0IiBoZWlnaHQ9IjU4IiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS4zIiBzdHlsZT0iZmlsbDojMGYxNzJhO3N0cm9rZTojNDc1NTY5Ii8+Cjx0ZXh0IHg9IjQwIiB5PSI1MyIgc3R5bGU9ImZvbnQ6IDEwLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzZlZTdiNzsgZm9udC13ZWlnaHQ6NzAwO2ZpbGw6I2NiZDVlMSI+bWVzc2FnZXMgb3JkZXJlZCB3aXRoaW4gZWFjaCBncm91cDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9IjcxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojY2JkNWUxIj5lYWNoIGdyb3VwJ3Mgb2xkZXN0IG1lc3NhZ2UsIGlmIG5vdGhpbmcgaW4gZmxpZ2h0ICDihpIgIGRlbGl2ZXJlZDwvdGV4dD4KPHRleHQgeD0iNDAiIHk9Ijg3IiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+U2VxdWVuY2VOdW1iZXI6IDIwIGRpZ2l0cywgemVyby1wYWRkZWQsIGFsd2F5cyBpbmNyZWFzaW5nPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjQwIiB5PSIxMjMiIHN0eWxlPSJmb250OiAxMC41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2ZWU3Yjc7IGZvbnQtd2VpZ2h0OjcwMCI+Z3JvdXAgb3JkZXJzPC90ZXh0Pgo8dGV4dCB4PSI0MCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNmVlN2I3Ij5tNDEgKGhlYWQsIGluIGZsaWdodCkgwrcgbTQyIMK3IG00MyDigKY8L3RleHQ+Cjx0ZXh0IHg9IjQwIiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5vbmUgaW4gZmxpZ2h0IMK3IG00MiB3YWl0cyB1bnRpbCBtNDEgaXMgZGVsZXRlZCBvciB0aW1lcyBvdXQ8L3RleHQ+CjxyZWN0IHg9IjQzMCIgeT0iMTA0IiB3aWR0aD0iMzgwIiBoZWlnaHQ9IjYyIiByeD0iMTAiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0iZmlsbDojMDY0ZTNiO3N0cm9rZTojNmVlN2I3Ii8+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTIzIiBzdHlsZT0iZm9udDogMTAuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmb250LXdlaWdodDo3MDAiPmdyb3VwIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjQ0NCIgeT0iMTQxIiBzdHlsZT0iZm9udDoxMHB4ICdTRiBNb25vJyxNZW5sbyxtb25vc3BhY2U7ZmlsbDojNmVlN2I3Ij5tNTggKGhlYWQsIGluIGZsaWdodCkgwrcgbTU5IOKApjwvdGV4dD4KPHRleHQgeD0iNDQ0IiB5PSIxNTgiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5ncm91cHMgYXJlIGNvbmN1cnJlbnQgwrcgYSBkaWZmZXJlbnQgcmVjZWl2ZXIgZHJhaW5zIGJpbGxpbmc8L3RleHQ+Cjx0ZXh0IHg9IjI2IiB5PSIxOTAiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjNjQ3NDhiOyBmaWxsOiNmYmJmMjQiPkRFRFVQTElDQVRJT04gwrcgNS1NSU5VVEUgV0lORE9XPC90ZXh0Pgo8cmVjdCB4PSIyNiIgeT0iMTk2IiB3aWR0aD0iMjUwIiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiMxZTI5M2I7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMTUxIiB5PSIyMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjY2JkNWUxOyBmaWxsOiNjYmQ1ZTEiPmV4cGxpY2l0IElEIG9yIFNIQS0yNTYoYm9keSk8L3RleHQ+CjxsaW5lIHgxPSIyNzYiIHkxPSIyMTYiIHgyPSIzMTIiIHkyPSIyMTYiIHN0cm9rZS13aWR0aD0iMS44IiBtYXJrZXItZW5kPSJ1cmwoI2ZzKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+CjxyZWN0IHg9IjMxNCIgeT0iMTk2IiB3aWR0aD0iNDk2IiBoZWlnaHQ9IjQwIiByeD0iOSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0eWxlPSJmaWxsOiM0MjIwMDY7c3Ryb2tlOiM5MjQwMGUiLz4KPHRleHQgeD0iNTYyIiB5PSIyMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OjYwMCAxMXB4IEludGVyLHNhbnMtc2VyaWY7ZmlsbDojZmJiZjI0Ij5yZXBlYXQgcmV0dXJucyBvcmlnaW5hbCBJRHM8L3RleHQ+Cjx0ZXh0IHg9IjU2MiIgeT0iMjI5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiODsgZmlsbDojZmJiZjI0Ij5tZXNzYWdlIGFuZCBkZWR1cCBtYXJrZXIgc2F2ZWQgdG9nZXRoZXI8L3RleHQ+Cjwvc3ZnPg==)

FIFO receives deliver one message per group at a time. Sends return a SequenceNumber, and repeated sends within 5 minutes are suppressed, matched by an explicit ID or, with content-based deduplication, a body hash.

#### Limitations

Where SQS and the PostgreSQL adapter differ

* **Throughput behaves differently: one PostgreSQL server serves every queue.** All of a Cloud Adapter deployment's queues share one server, so its capacity bounds peak throughput and a heavy queue can affect the others. In Tensor9's round-trip test of a moderate-rate Standard queue, the adapter matched SQS throughput (about 300 vs 286 ops/s) with a lower p99 (140 ms vs 172 ms) but a slower median (p50 24 ms vs 15 ms). That is not a measured ceiling, and it does not cover FIFO queues or every host.
* **Recovery follows the database placement.** The managed database is outside the Cloud Adapter deployment cluster, so replacing that cluster does not replace the queue data. Database availability and recovery still depend on the selected server, HA and backup configuration.
* **Messages are limited to 256 KiB by default.** The adapter's default limit is 262144 bytes, while native SQS now accepts up to 1 MiB. Sends are checked against the queue's declared limit.
* **FIFO send deduplication lasts 5 minutes.** A duplicate send within that window returns the original IDs. Reusing an ID after the window can create a new message. Consumer redelivery remains possible even within the window.
* **Stale receipt handles behave differently: they return an error.** `DeleteMessage` and `ChangeMessageVisibility` return `ReceiptHandleIsInvalid` when no message matches the handle.
* **Retention behaves differently: expired messages are removed periodically.** An expired message can remain until the next cleanup pass. Retention is kept between 60 seconds and 14 days; a too-short value is raised to 60 seconds so that new messages are not deleted.
* **Counts observe queue state, not application completion.** Requested message counts read the message database: eligible messages are visible, future-visible messages with a receipt are in flight, and future-visible messages without a receipt are initially delayed. These categories share one query snapshot and can change immediately afterward. Metadata-only reads do not require a message-table count. An unavailable requested count returns an explicit unsupported result rather than zero. Purge, expiry and dead-letter movement can reduce depth without completing the application's work.
* **Queue creation behaves differently: queues are created when the stack is deployed.** Tensor9 creates the database and each queue's table, and its dead-letter table, at deploy time. `CreateQueue`, `DeleteQueue` and `SetQueueAttributes` act on those tables. Switching a queue between Standard and FIFO is rejected, because it would replace the queue.

#### Other considerations

* **Moving from AWS.** The database and queue tables start empty, and existing SQS messages are not migrated. Drain each group before switching it, to preserve order.
* **Removing queues.** Each queue is created in one step, so a crash never leaves a half-created queue. When a queue is removed from the stack, Tensor9 deletes only queues it created; any other queue is detached and left in place. A queue that still holds messages is not deleted unless deletion is forced.
* **Who operates what.** On the managed hosts, the provider operates the database's durability, backups and high availability, and Tensor9 operates the adapter. On CloudNativePG, Tensor9 operates the database inside your cluster.

#### 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.

##### SQS FIFO · SQS request billing units

Feature: SQS FIFO.

Estimated monthly service charges by SQS request billing units. Adapter hosting and Tensor9 fees are excluded. Source: us-east-1; target: fr-par; currency: USD.

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/1d7f89af4360cd07776aa1bb0fda9aced6001c7d797f34dc6e48c828706b230c-light.svg)

![SQS FIFO · SQS request billing units: monthly service charges by SQS request billing units. Exact values are in the following table.](https://docs.tensor9.com/images/cloud-adapter-early-access/diagrams/service-cost/860e4fd7c118510adeba5d90f1458759a79a92865efef2ec238aa72acb006809-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.

| SQS request billing units (per second) | SQS (Simple Queue Service, FIFO queues) | Target scenario | Scaleway Managed Database for PostgreSQL | Difference |
| -: | -: | - | -: | -: |
| 0 | 0.00 | Scaleway Managed Database for PostgreSQL (one copy) | 101.10 | 101.10 |
| 0 | 0.00 | Scaleway Managed Database for PostgreSQL (two copies) | 154.69 | 154.69 |
| 1 | 1.31 | Scaleway Managed Database for PostgreSQL (one copy) | 101.10 | 99.79 |
| 1 | 1.31 | Scaleway Managed Database for PostgreSQL (two copies) | 154.69 | 153.37 |
| 10 | 13.14 | Scaleway Managed Database for PostgreSQL (one copy) | 101.10 | 87.96 |
| 10 | 13.14 | Scaleway Managed Database for PostgreSQL (two copies) | 154.69 | 141.55 |
| 100 | 131.40 | Scaleway Managed Database for PostgreSQL (one copy) | 101.10 | -30.30 |
| 100 | 131.40 | Scaleway Managed Database for PostgreSQL (two copies) | 154.69 | 23.29 |
| 1,000 | 1,314.00 | Scaleway Managed Database for PostgreSQL (one copy) | 371.03 | -942.97 |
| 1,000 | 1,314.00 | Scaleway Managed Database for PostgreSQL (two copies) | 567.68 | -746.32 |
| 10,000 | 13,140.00 | Scaleway Managed Database for PostgreSQL (one copy) | Unpriced | Unavailable |
| 10,000 | 13,140.00 | Scaleway Managed Database for PostgreSQL (two copies) | Unpriced | Unavailable |

Estimated allocation, not benchmark calibrated: sized from 2 vCPU, 8 GiB memory and 100 GiB SSD at 0 per second to 8 vCPU, 32 GiB memory and 100 GiB SSD at 1,000 per second. From 10,000 per second the workload exceeds the planning range and the target is unpriced.

**Curve assumptions**

| Target scenario | Assumption | Value | Unit |
| - | - | -: | - |
| Scaleway Managed Database for PostgreSQL (one copy) | Origin list price · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Scaleway Managed Database for PostgreSQL (one copy) | Representative message size | 1,024 | bytes |
| Scaleway Managed Database for PostgreSQL (one copy) | Origin send batch fill | 1 | messages/request |
| Scaleway Managed Database for PostgreSQL (one copy) | Origin receive batch fill | 1 | messages/request |
| Scaleway Managed Database for PostgreSQL (one copy) | Origin delete batch fill | 1 | messages/request |
| Scaleway Managed Database for PostgreSQL (one copy) | Deliveries per message | 1 | attempts |
| Scaleway Managed Database for PostgreSQL (one copy) | Empty receive calls per message | 0 | requests |
| Scaleway Managed Database for PostgreSQL (one copy) | Queue residence window | 60 | seconds |
| Scaleway Managed Database for PostgreSQL (one copy) | Ordering and dedup work multiplier | 2 | multiplier |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · read | 0 | USD/read |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · write | 0 | USD/write |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · provider operation | 0 | USD/provider operation |
| Scaleway Managed Database for PostgreSQL (one copy) | Target list price · GiB-month | 0.111266 | USD/GiB-month |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · published GiB | 0 | USD/published GiB |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · network GiB | 0 | USD/network GiB |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Scaleway Managed Database for PostgreSQL (one copy) | Target list price · vCPU-hour | 0.0367275 | USD/vCPU-hour |
| Scaleway Managed Database for PostgreSQL (one copy) | Target list price · GiB-hour | 0.006225 | USD/GiB-hour |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · resource-hour | 0 | USD/resource-hour |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · resource-month | 0 | USD/resource-month |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · input token | 0 | USD/input token |
| Scaleway Managed Database for PostgreSQL (one copy) | Target price guess · output token | 0 | USD/output token |
| Scaleway Managed Database for PostgreSQL (one copy) | Target monthly base charge | 0 | USD/month |
| Scaleway Managed Database for PostgreSQL (one copy) | Target service minimum | 89.9762 | USD/month |
| Scaleway Managed Database for PostgreSQL (one copy) | Minimum primary CPU | 2 | vCPU |
| Scaleway Managed Database for PostgreSQL (one copy) | Minimum primary RAM | 8 | GiB |
| Scaleway Managed Database for PostgreSQL (one copy) | Minimum primary disk | 100 | GiB |
| Scaleway Managed Database for PostgreSQL (one copy) | Additional full-price standby copy | 0 | 0 or 1 |
| Scaleway Managed Database for PostgreSQL (one copy) | Allocated share of provisioned cost | 1 | fraction |
| Scaleway Managed Database for PostgreSQL (one copy) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Scaleway Managed Database for PostgreSQL (one copy) | Planning peak / mean work | 2 | multiplier |
| Scaleway Managed Database for PostgreSQL (one copy) | Planning primary CPU utilization | 0.7 | fraction |
| Scaleway Managed Database for PostgreSQL (one copy) | Resident state reserved in RAM | 0.1 | fraction |
| Scaleway Managed Database for PostgreSQL (one copy) | Planning disk utilization | 0.8 | fraction |
| Scaleway Managed Database for PostgreSQL (one copy) | Maintenance and log disk reserve | 20 | GiB |
| Scaleway Managed Database for PostgreSQL (one copy) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Scaleway Managed Database for PostgreSQL (one copy) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Scaleway Managed Database for PostgreSQL (one copy) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Scaleway Managed Database for PostgreSQL (one copy) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Scaleway Managed Database for PostgreSQL (one copy) | Dependent object sink write price guess | 0.000005 | USD/write |
| Scaleway Managed Database for PostgreSQL (two copies) | Origin list price · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Scaleway Managed Database for PostgreSQL (two copies) | Representative message size | 1,024 | bytes |
| Scaleway Managed Database for PostgreSQL (two copies) | Origin send batch fill | 1 | messages/request |
| Scaleway Managed Database for PostgreSQL (two copies) | Origin receive batch fill | 1 | messages/request |
| Scaleway Managed Database for PostgreSQL (two copies) | Origin delete batch fill | 1 | messages/request |
| Scaleway Managed Database for PostgreSQL (two copies) | Deliveries per message | 1 | attempts |
| Scaleway Managed Database for PostgreSQL (two copies) | Empty receive calls per message | 0 | requests |
| Scaleway Managed Database for PostgreSQL (two copies) | Queue residence window | 60 | seconds |
| Scaleway Managed Database for PostgreSQL (two copies) | Ordering and dedup work multiplier | 2 | multiplier |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · read | 0 | USD/read |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · write | 0 | USD/write |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · provider operation | 0 | USD/provider operation |
| Scaleway Managed Database for PostgreSQL (two copies) | Target list price · GiB-month | 0.111266 | USD/GiB-month |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · published GiB | 0 | USD/published GiB |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · network GiB | 0 | USD/network GiB |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Scaleway Managed Database for PostgreSQL (two copies) | Target list price · vCPU-hour | 0.0367275 | USD/vCPU-hour |
| Scaleway Managed Database for PostgreSQL (two copies) | Target list price · GiB-hour | 0.006225 | USD/GiB-hour |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · resource-hour | 0 | USD/resource-hour |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · resource-month | 0 | USD/resource-month |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · input token | 0 | USD/input token |
| Scaleway Managed Database for PostgreSQL (two copies) | Target price guess · output token | 0 | USD/output token |
| Scaleway Managed Database for PostgreSQL (two copies) | Target monthly base charge | 0 | USD/month |
| Scaleway Managed Database for PostgreSQL (two copies) | Target service minimum | 89.9762 | USD/month |
| Scaleway Managed Database for PostgreSQL (two copies) | Minimum primary CPU | 2 | vCPU |
| Scaleway Managed Database for PostgreSQL (two copies) | Minimum primary RAM | 8 | GiB |
| Scaleway Managed Database for PostgreSQL (two copies) | Minimum primary disk | 100 | GiB |
| Scaleway Managed Database for PostgreSQL (two copies) | Additional full-price standby copy | 1 | 0 or 1 |
| Scaleway Managed Database for PostgreSQL (two copies) | Allocated share of provisioned cost | 1 | fraction |
| Scaleway Managed Database for PostgreSQL (two copies) | Read/write work per vCPU-second | 1,500 | operations/vCPU-second |
| Scaleway Managed Database for PostgreSQL (two copies) | Planning peak / mean work | 2 | multiplier |
| Scaleway Managed Database for PostgreSQL (two copies) | Planning primary CPU utilization | 0.7 | fraction |
| Scaleway Managed Database for PostgreSQL (two copies) | Resident state reserved in RAM | 0.1 | fraction |
| Scaleway Managed Database for PostgreSQL (two copies) | Planning disk utilization | 0.8 | fraction |
| Scaleway Managed Database for PostgreSQL (two copies) | Maintenance and log disk reserve | 20 | GiB |
| Scaleway Managed Database for PostgreSQL (two copies) | Staging database CPU unit-price guess | 0.0413 | USD/vCPU-hour |
| Scaleway Managed Database for PostgreSQL (two copies) | Staging database RAM unit-price guess | 0.007 | USD/GiB-hour |
| Scaleway Managed Database for PostgreSQL (two copies) | Staging database disk unit-price guess | 0.17 | USD/GiB-month |
| Scaleway Managed Database for PostgreSQL (two copies) | Dependent object sink storage price guess | 0.023 | USD/GiB-month |
| Scaleway Managed Database for PostgreSQL (two copies) | Dependent object sink write price guess | 0.000005 | USD/write |

* 1-KiB messages, unbatched send/receive/delete; actual batch and delivery assumptions stay visible. 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 → fr-par, 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.
* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.
* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.
* Scaleway Managed Database for PostgreSQL at Production Optimized (PRO2) prices in EUR converted at the ECB reference rate. A high-availability or replica node bills Scaleway's 'Additional nodes' price, EUR 0.0583 per hour for PRO2-XXS, 53% of the main node. Scaleway lists no egress charge for Managed Databases, so selected network is not charged. Cost Optimized ranges (DB-DEV-S from EUR 0.0156 per hour), Block Storage 15K and backups (EUR 0.03 per GB-month) 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: DB-PRO2-L has 32 vCPUs and 128 GB ([https://www.scaleway.com/en/pricing/managed-databases/](https://www.scaleway.com/en/pricing/managed-databases/)); a volume grows up to 15 TB ([https://www.scaleway.com/en/docs/managed-databases-for-postgresql-and-mysql/concepts/](https://www.scaleway.com/en/docs/managed-databases-for-postgresql-and-mysql/concepts/)).
* 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, AWSQueueService offer: [https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json)
* Scaleway Managed Databases pricing: [https://www.scaleway.com/en/pricing/managed-databases/](https://www.scaleway.com/en/pricing/managed-databases/)

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-587f83be80f7d547d383d9abce0fac6d8798d699` / `2026-10-22.planning.2`. Curve: `workload-1`.

Sources: [AWS Price List API, AWSQueueService offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json), [Scaleway Managed Databases pricing](https://www.scaleway.com/en/pricing/managed-databases/).

**SQS FIFO → Scaleway Managed Database 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: fr-par. Currency: USD.

| Monthly component | USD |
| - | -: |
| Origin: SQS billing units | 0.00 |
| Target: Provisioned primary CPU | 53.62 |
| Target: Provisioned primary RAM | 36.35 |
| Target: Provisioned primary disk | 11.13 |
| 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** | **101.10** |

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 · SQS billing units | 0.0000005 | USD/64-KiB request units |
| Representative message size | 1,024 | bytes |
| Origin send batch fill | 1 | messages/request |
| Origin receive batch fill | 1 | messages/request |
| Origin delete batch fill | 1 | messages/request |
| Deliveries per message | 1 | attempts |
| Empty receive calls per message | 0 | requests |
| Queue residence window | 60 | seconds |
| Ordering and dedup work multiplier | 2 | multiplier |
| 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.111266 | USD/GiB-month |
| Target price guess · published GiB | 0 | USD/published GiB |
| Target price guess · delivered GiB | 0 | USD/delivered GiB |
| Target price guess · network GiB | 0 | USD/network GiB |
| Target price guess · replica GiB-month | 0 | USD/replica GiB-month |
| Target list price · vCPU-hour | 0.0367275 | USD/vCPU-hour |
| Target list price · GiB-hour | 0.006225 | 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 | 89.9762 | 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 |
| SQS billing units | 0 | 64-KiB request units |

* 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.

* Storage follows resident original messages, not every monthly message. Broker delivery bytes include redeliveries.

* FIFO estimates do not qualify dedup support, group throughput or single-group latency; backend limitations remain applicable.

* Scaleway Managed Database for PostgreSQL at Production Optimized (PRO2) prices in EUR converted at the ECB reference rate. A high-availability or replica node bills Scaleway's 'Additional nodes' price, EUR 0.0583 per hour for PRO2-XXS, 53% of the main node. Scaleway lists no egress charge for Managed Databases, so selected network is not charged. Cost Optimized ranges (DB-DEV-S from EUR 0.0156 per hour), Block Storage 15K and backups (EUR 0.03 per GB-month) 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: DB-PRO2-L has 32 vCPUs and 128 GB ([https://www.scaleway.com/en/pricing/managed-databases/](https://www.scaleway.com/en/pricing/managed-databases/)); a volume grows up to 15 TB ([https://www.scaleway.com/en/docs/managed-databases-for-postgresql-and-mysql/concepts/](https://www.scaleway.com/en/docs/managed-databases-for-postgresql-and-mysql/concepts/)).

* 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-587f83be80f7d547d383d9abce0fac6d8798d699` / `2026-10-22.planning.2`. Scenario: `planning-example`.

Sources: [AWS Price List API, AWSQueueService offer](https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AWSQueueService/current/us-east-1/index.json), [Scaleway Managed Databases pricing](https://www.scaleway.com/en/pricing/managed-databases/).

## 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.

| Backend | Sampled workload | Price basis | Origin USD/month | Backend USD/month | Difference | Mapping |
| - | - | - | -: | -: | -: | - |
| Azure Cosmos DB (queue) | SQS request billing units: 100 per second | Cited list prices, 2026-10-22 | 131.40 | 140.16 | +8.76 | Service adapter |
| Azure Service Bus | SQS request billing units: 100 per second | Cited list prices, 2026-10-22 | 131.40 | 160.81 | +29.41 | Service adapter |
| Cloud SQL for PostgreSQL | SQS request billing units: 100 per second; one copy | Cited list prices, 2026-10-22 | 131.40 | 118.18 | -13.22 | Native or deployment |
| PostgreSQL | SQS request billing units: 100 per second; one copy | Cited list prices, 2026-10-22 | 131.40 | 80.90 | -50.50 | Native or deployment |
| PostgreSQL Flexible Server | SQS request billing units: 100 per second; one copy | Cited list prices, 2026-10-22 | 131.40 | 141.44 | +10.04 | Service adapter |
| Scaleway Managed Database for PostgreSQL | SQS request billing units: 100 per second; one copy | Cited list prices, 2026-10-22 | 131.40 | 101.10 | -30.30 | 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 SQS costs](https://docs.tensor9.com/cloud-adapter-early-access/costs/sqs.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).

### SQS to 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. Measure each queue type separately. |
| SendMessage, DeleteMessage, ChangeMessageVisibility adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::sqs`: `SendMessage`, `DeleteMessage`, `ChangeMessageVisibility` | Message body ≤1 KiB and attributes ≤1 KiB. Use supported request options. |
| SendMessageBatch adapter-added latency | +200 ms monthly p99 | `aws::1.0.0::sqs`: `SendMessageBatch` | ≤10 entries, each within the body, attribute and API limits. `DeleteMessageBatch` is not covered. |
| ReceiveMessage: ready-message pickup adapter-added latency | +500 ms monthly p99 | `aws::1.0.0::sqs`: `ReceiveMessage` | One available message and one waiting request for a single message; body/attributes ≤1 KiB. No competing backlog, receiver, or earlier FIFO message blocking delivery. |
| ReceiveMessage: delay after the requested wait adapter-added latency | +500 ms monthly p99 | `aws::1.0.0::sqs`: `ReceiveMessage` | Count adapter delay after the requested waiting period ends, not the time spent waiting for a message. |
| Saving messages and completed processing | Save the required data durably before returning success | `aws::1.0.0::sqs`: `SendMessage`, `DeleteMessage`, `ChangeMessageVisibility`, `SendMessageBatch`, `ReceiveMessage` | Safely assign messages to receivers and preserve visibility, expiration, completed processing and dead-letter handling after a failure. The adapter must not lose accepted messages. |
| Delivery, ordering and deduplication | Delivery behavior as documented for this adapter | `aws::1.0.0::sqs`: `SendMessage`, `DeleteMessage`, `ChangeMessageVisibility`, `SendMessageBatch`, `ReceiveMessage` | Standard queues may deliver a message again. FIFO preserves the documented order and duplicate handling within each message group. Your application must still handle retries without repeating business actions. |
| Adapter autoscaling and limits | Automatic scaling within agreed traffic and deployment limits | Adapter behavior across requests | Set separate limits for Standard and FIFO queues. Include completed send/receive/delete cycles, message sizes and attributes, partitions, conditional message claims, FIFO groups, 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.

**How queue timing works.** Time spent waiting for a message in an empty queue does not count as adapter delay. Adapter delays after a message becomes available, or after the requested wait ends, do count. The message-pickup target is not a deadline for clearing a backlog. Measure Standard and FIFO queues separately, and check each batch entry's result. Empty receives and internal retries do not count as successfully delivered messages.

**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

The shared Standard/FIFO point-operation target is 20 ms, with 200 ms for a batch of up to ten sends. Cosmos FIFO uses a per-group sequence counter, a durable deduplication marker and an in-flight ownership slot. Their conditional reads/writes are adapter coordination; the clock cannot exclude them merely because they use Cosmos DB. The shared target preserves room for that work instead of advertising the cost of a simple native queue forwarder.

Ready-message pickup and delay after the requested wait remain at 500 ms. Discovery, candidate inspection, conditional claims and polling can dominate this path even for a tiny message. The target is not an end-to-end promise for clearing a backlog, and Standard and FIFO observations must remain separate.

#### Adapter and scope

| Origin | Backend |
| - | - |
| `aws::1.0.0::sqs::classic` | `azure::1.0.0::cosmosdb::queue` |
| `aws::1.0.0::sqs::fifo` | `azure::1.0.0::cosmosdb::queue` |

This is the queue-specific Cosmos DB profile, using its serverless account and per-queue container arrangement. It is **not** the provisioned Cosmos DB backend used by the DynamoDB service level. Capacity settings and performance results cannot be transferred between those profiles by matching the provider name.

#### Receive timing

Two phases of `ReceiveMessage` have separate measurements:

* **Ready-message pickup:** time from a message becoming available to a waiting receiver until the adapter sends the response. Only separately measured time spent waiting for the backend service is excluded.
* **Delay after the requested wait:** extra adapter time after the requested wait for a message has ended.

The pickup target applies when one message becomes ready for one waiting receiver that requested a single message. No other messages or receivers may compete for that delivery. For FIFO, an earlier message in the same group must not still be waiting for deletion. The message must be visible, unexpired, past any delivery delay, and available to that consumer.

One ready message and 64 waiting receivers require one delivery, not 64. Ten thousand messages and one outstanding receive do not create ten thousand immediate delivery deadlines. This target does not set a deadline for processing an entire backlog.

Waiting on an empty queue for the requested 20 seconds is intentional. If the adapter sleeps between queue checks after a message becomes available or after the wait deadline, that delay counts toward adapter latency. Waiting for a connection from the adapter's pool also counts. The pickup clock does not start while a message is delayed or invisible.

#### Message guarantees

A send can return success only after the message state has been durably saved. A deduplication marker alone must not produce success for a message that was never committed. The adapter must use the same record of accepted messages when returning success, checking for duplicates, and recovering from a crash.

Standard queues can redeliver messages. FIFO preserves the profile's per-group ordering and supported deduplication behavior; it does not promise global order across groups or exactly-once effects in your application. A consumer can perform a business action and fail before deleting the message, so application-side idempotency still matters.

The adapter follows its documented rules for visibility, expiration, message deletion, and movement to a dead-letter queue. Successfully completed changes must survive the process failures covered by the agreement. An expired receipt handle produces the result documented for that adapter; different backends need not return the same error. Approximate queue counts help with troubleshooting but are not guaranteed to show the exact current queue depth.

#### Useful throughput

Count completed API calls separately from message work. A valid empty `ReceiveMessage` completes an API call but delivers no message. One successful send, nonempty receive and delete form a message lifecycle involving at least three API calls. Redelivery and internal retries must not inflate the count of distinct messages processed.

Measure Standard and FIFO separately. FIFO group distribution, time between receive and delete, visibility timeout, delayed messages and dead-letter traffic change the scaling limit. A large number of consumers cannot make a single serialized group behave like many independent groups.

These standard service levels do not reserve a fixed message rate or specify a maximum throughput. Tensor9 and the customer must agree on limits for the actual workload and production deployment, including how quickly traffic can grow and how large a burst can be. Autoscaling is intended to maintain the stated latency and endpoint reachability within those limits. It cannot remove ordering requirements or backend-service limits.

#### Operation terms

The named operations retain their documented behavior with supported request options. The 1 KiB limits apply to the latency targets. `DeleteMessageBatch`, `ChangeMessageVisibilityBatch`, queue management, tagging and approximate-count reads have no numerical SLA under these standard terms. A capability in the service profile does not automatically receive another operation's SLA.

The pickup service level differs from the Cloud SQL service level. These targets apply to their respective receive paths; they are not comparative benchmark results or a recommendation to choose one backend.

#### Scaling on Cosmos DB

Partition distribution, conditional message claims, deduplication and FIFO group serialization affect useful throughput. Native request-unit consumption and throttling need to be considered alongside adapter scheduling, repeated scans and retry amplification.

Additional replicas can process independent work. They do not remove contention around the same message claim or FIFO group, and they do not grant additional native serverless capacity. Track completed message lifecycles, native calls per lifecycle and repeated failed claims separately.

Once a message expires, the queue must treat it as expired even if the cloud provider has not yet removed its stored data. Do not count expired messages as available work merely because they still appear in a storage view. Time the adapter takes to find an available message, including waits between queue checks, also counts toward adapter latency. It is not automatically excluded as cloud-provider time.

#### Example: two receivers see the same candidate

Two receivers discover a message. The adapter must use a conditional update to assign the message to a receiver under the documented queue rules. It must not give both receivers conflicting ownership just to meet a latency target. Record the claim outcomes and native conditional responses, along with local retries and scheduling.

A later redelivery after visibility expires can be legitimate. It is different from simultaneous ownership caused by a broken claim. Inspect receipt timing and the selected queue semantics before calling either event data loss or a duplicate-delivery defect.

#### Example: restart during a dead-letter transition

A message is copied to the dead-letter queue, then the process restarts before removing the source copy. Recovery must preserve the supported message semantics without adapter-induced loss. A valid redelivery is not the same as a missing accepted message.

Preserve source and destination observations and identifiers before changing either queue. Do not delete both copies to make the counts agree, and do not replay a send solely to generate an Explain report.

If Cosmos DB also reports throttling, investigate serverless/partition pressure and the adapter's call/retry pattern. Backend throttling does not excuse an incorrect recovery algorithm or excessive local retries.

#### Evidence for support

Record Standard versus FIFO, group distribution, message and attribute sizes, conditional-claim outcomes, wait/visibility settings, dead-letter configuration and the affected time window. Include native request IDs, request-unit/throttling observations and available adapter timing. Keep sensitive bodies and receipt handles out of shared reports. You can contact support before you know what caused the problem.

### SQS (Simple Queue Service, FIFO queues) to PostgreSQL Flexible Server

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Small message send and settlement adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::sqs`: `ChangeMessageVisibility`, `DeleteMessage`, `SendMessage` | One message at most 4 KiB including attributes; one group for FIFO; no redrive transition or contention retry. Adapter metadata/coordination waits remain included. Higher contention needs an agreed separate class. |
| Bounded short-poll receive adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::sqs`: `ReceiveMessage` | WaitTimeSeconds=0; at most 10 messages, 40 KiB aggregate bodies/attributes, at most 100 inspected candidates or active groups, no dead-letter transfer. Long-poll timeout and message-arrival latency are separate, not silently subtracted from this row. |
| Bounded message batches adapter-added latency | +100 ms monthly p99 | `aws::1.0.0::sqs`: `DeleteMessageBatch`, `SendMessageBatch` | At most 10 entries and 40 KiB aggregate data. Same point-operation limits, applied to each entry; every entry gets its own success/error result. |
| Queue configuration and discovery adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::sqs`: `GetQueueAttributes`, `GetQueueUrl` | One queue, at most 50 tags and 32 KiB configuration, or a page of at most 100 queues. Purge measures request acceptance, not complete physical reclamation or receipt invalidation across every worker. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::sqs`: `ChangeMessageVisibility`, `DeleteMessage`, `SendMessage`, `ReceiveMessage`, `DeleteMessageBatch`, `SendMessageBatch`, `GetQueueAttributes`, `GetQueueUrl` | Acceptance must not be returned before the documented message persistence point. Settlement must apply to the intended message/receipt; FIFO order and deduplication apply only where this directed profile supports them. Duplicate delivery can be legitimate under at-least-once delivery. Dead-letter transitions must not silently discard an accepted message. Durability of the target broker/database remains its own commitment, while broken adapter receipt, marker or coordination logic remains Tensor9's responsibility. |
| 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::postgresql::flexible`, The SQL queue uses row locking and SKIP LOCKED; FIFO adds head-of-group selection and deduplication state. The current long-poll loop can sleep between polls. Queue configuration is cached and durable queue state remains in PostgreSQL. A ReceiveMessage response budget is not a delivery-time promise: messages may not yet exist, may be delayed, or may be blocked by a FIFO group head. The short-poll row deliberately removes that ambiguity. Requested long-poll waits need their own measurement treatment in the agreement.

#### How the latency targets were chosen

**Small message send and settlement: +10 ms monthly p99 (adapter-added).** `ChangeMessageVisibility`, `DeleteMessage`, `SendMessage`. Native forwarding needs bounded translation; SQL adds queue state; Cosmos FIFO requires multiple durable coordination steps and cannot honestly inherit a 1 ms forwarding budget.

**Bounded short-poll receive: +10 ms monthly p99 (adapter-added).** `ReceiveMessage`. Receive scans/selects candidates, claims visibility and creates receipt handles. FIFO head selection and Cosmos slot CAS cost more than a simple send.

**Bounded message batches: +100 ms monthly p99 (adapter-added).** `DeleteMessageBatch`, `SendMessageBatch`. A conservative upper budget for up to ten point paths plus aggregation. It does not assume the implementation parallelizes all target or metadata work.

**Queue configuration and discovery: +20 ms monthly p99 (adapter-added).** `GetQueueAttributes`, `GetQueueUrl`. Queue identity, attributes, tags and counts can use the adapter's durable catalog; this is not excluded as target message work.

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

Scale send, receive and settle capacity together, and track in-flight messages, pollers, candidate scans and FIFO group skew. Adding replicas helps independent groups but cannot parallelize the ordered head of one group. The agreement caps active pollers, groups inspected per receive, message bytes, retry amplification and batch entries. Tensor9 scales the fabric within those limits; the customer supplies sufficient broker capacity, Cosmos RU/s or PostgreSQL connections and I/O.

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

Acceptance must not be returned before the documented message persistence point. Settlement must apply to the intended message/receipt; FIFO order and deduplication apply only where this directed profile supports them. Duplicate delivery can be legitimate under at-least-once delivery. Dead-letter transitions must not silently discard an accepted message. Durability of the target broker/database remains its own commitment, while broken adapter receipt, marker or coordination logic remains Tensor9's responsibility.

#### Example and diagnosis

For `order-events`, send a 2 KiB message, receive up to ten messages with WaitTimeSeconds=0, then settle each receipt. For a FIFO queue, distribute independent customers across groups instead of expecting one group to scale with replicas. If native message writes are fast but Cosmos FIFO sends slow down, inspect counter/dedup contention: those coordination waits still count against Tensor9's fabric budget.

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.

### SQS (Simple Queue Service, FIFO queues) to Azure Service Bus

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Small message send and settlement adapter-added latency | +1 ms monthly p99 | `aws::1.0.0::sqs`: `ChangeMessageVisibility`, `DeleteMessage`, `SendMessage` | One message at most 4 KiB including attributes; one group for FIFO; no redrive transition or contention retry. Adapter metadata/coordination waits remain included. Higher contention needs an agreed separate class. |
| Bounded short-poll receive adapter-added latency | +3 ms monthly p99 | `aws::1.0.0::sqs`: `ReceiveMessage` | WaitTimeSeconds=0; at most 10 messages, 40 KiB aggregate bodies/attributes, at most 100 inspected candidates or active groups, no dead-letter transfer. Long-poll timeout and message-arrival latency are separate, not silently subtracted from this row. |
| Bounded message batches adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::sqs`: `SendMessageBatch` | At most 10 entries and 40 KiB aggregate data. Same point-operation limits, applied to each entry; every entry gets its own success/error result. |
| Queue configuration and discovery adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::sqs`: `DeleteQueue`, `ListQueueTags`, `ListQueues`, `PurgeQueue`, `SetQueueAttributes`, `TagQueue`, `UntagQueue` | One queue, at most 50 tags and 32 KiB configuration, or a page of at most 100 queues. Purge measures request acceptance, not complete physical reclamation or receipt invalidation across every worker. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::sqs`: `ChangeMessageVisibility`, `DeleteMessage`, `SendMessage`, `ReceiveMessage`, `SendMessageBatch`, `DeleteQueue`, `ListQueueTags`, `ListQueues`, `PurgeQueue`, `SetQueueAttributes`, `TagQueue`, `UntagQueue` | Acceptance must not be returned before the documented message persistence point. Settlement must apply to the intended message/receipt; FIFO order and deduplication apply only where this directed profile supports them. Duplicate delivery can be legitimate under at-least-once delivery. Dead-letter transitions must not silently discard an accepted message. Durability of the target broker/database remains its own commitment, while broken adapter receipt, marker or coordination logic remains Tensor9's responsibility. |
| 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::servicebus`, Service Bus messages and locks implement queue delivery; FIFO uses sessions. Lock renewal, receipt mapping and settlement remain adapter responsibilities, while native broker delivery uses the target service. A ReceiveMessage response budget is not a delivery-time promise: messages may not yet exist, may be delayed, or may be blocked by a FIFO group head. The short-poll row deliberately removes that ambiguity. Requested long-poll waits need their own measurement treatment in the agreement.

#### How the latency targets were chosen

**Small message send and settlement: +1 ms monthly p99 (adapter-added).** `ChangeMessageVisibility`, `DeleteMessage`, `SendMessage`. Native forwarding needs bounded translation; SQL adds queue state; Cosmos FIFO requires multiple durable coordination steps and cannot honestly inherit a 1 ms forwarding budget.

**Bounded short-poll receive: +3 ms monthly p99 (adapter-added).** `ReceiveMessage`. Receive scans/selects candidates, claims visibility and creates receipt handles. FIFO head selection and Cosmos slot CAS cost more than a simple send.

**Bounded message batches: +10 ms monthly p99 (adapter-added).** `SendMessageBatch`. A conservative upper budget for up to ten point paths plus aggregation. It does not assume the implementation parallelizes all target or metadata work.

**Queue configuration and discovery: +20 ms monthly p99 (adapter-added).** `DeleteQueue`, `ListQueueTags`, `ListQueues`, `PurgeQueue`, `SetQueueAttributes`, `TagQueue`, `UntagQueue`. Queue identity, attributes, tags and counts can use the adapter's durable catalog; this is not excluded as target message work.

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

Scale send, receive and settle capacity together, and track in-flight messages, pollers, candidate scans and FIFO group skew. Adding replicas helps independent groups but cannot parallelize the ordered head of one group. The agreement caps active pollers, groups inspected per receive, message bytes, retry amplification and batch entries. Tensor9 scales the fabric within those limits; the customer supplies sufficient broker capacity, Cosmos RU/s or PostgreSQL connections and I/O.

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

Acceptance must not be returned before the documented message persistence point. Settlement must apply to the intended message/receipt; FIFO order and deduplication apply only where this directed profile supports them. Duplicate delivery can be legitimate under at-least-once delivery. Dead-letter transitions must not silently discard an accepted message. Durability of the target broker/database remains its own commitment, while broken adapter receipt, marker or coordination logic remains Tensor9's responsibility.

#### Example and diagnosis

For `order-events`, send a 2 KiB message, receive up to ten messages with WaitTimeSeconds=0, then settle each receipt. For a FIFO queue, distribute independent customers across groups instead of expecting one group to scale with replicas. If native message writes are fast but Cosmos FIFO sends slow down, inspect counter/dedup contention: those coordination waits still count against Tensor9's fabric budget.

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.

### SQS (Simple Queue Service, FIFO queues) to Cloud SQL for PostgreSQL

**SLA status:** Not applicable

FIFO request-processing service levels have not been qualified for this mapping. Standard-queue measurements do not establish FIFO latency, throughput or availability.

### SQS (Simple Queue Service, FIFO queues) to PostgreSQL

**SLA status:** Not applicable

FIFO request-processing service levels have not been qualified for this mapping. Standard-queue measurements do not establish FIFO latency, throughput or availability.

### SQS (Simple Queue Service, FIFO queues) to Scaleway Managed Database for PostgreSQL

| SLA | Service level | What is covered | Conditions |
| - | - | - | - |
| Small message send and settlement adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::sqs`: `ChangeMessageVisibility`, `DeleteMessage`, `SendMessage` | One message at most 4 KiB including attributes; one group for FIFO; no redrive transition or contention retry. Adapter metadata/coordination waits remain included. Higher contention needs an agreed separate class. |
| Bounded short-poll receive adapter-added latency | +10 ms monthly p99 | `aws::1.0.0::sqs`: `ReceiveMessage` | WaitTimeSeconds=0; at most 10 messages, 40 KiB aggregate bodies/attributes, at most 100 inspected candidates or active groups, no dead-letter transfer. Long-poll timeout and message-arrival latency are separate, not silently subtracted from this row. |
| Bounded message batches adapter-added latency | +100 ms monthly p99 | `aws::1.0.0::sqs`: `DeleteMessageBatch`, `SendMessageBatch` | At most 10 entries and 40 KiB aggregate data. Same point-operation limits, applied to each entry; every entry gets its own success/error result. |
| Queue configuration and discovery adapter-added latency | +20 ms monthly p99 | `aws::1.0.0::sqs`: `GetQueueAttributes`, `GetQueueUrl` | One queue, at most 50 tags and 32 KiB configuration, or a page of at most 100 queues. Purge measures request acceptance, not complete physical reclamation or receipt invalidation across every worker. |
| Documented adapter behavior | Preserve the supported behavior documented for this adapter | `aws::1.0.0::sqs`: `ChangeMessageVisibility`, `DeleteMessage`, `SendMessage`, `ReceiveMessage`, `DeleteMessageBatch`, `SendMessageBatch`, `GetQueueAttributes`, `GetQueueUrl` | Acceptance must not be returned before the documented message persistence point. Settlement must apply to the intended message/receipt; FIFO order and deduplication apply only where this directed profile supports them. Duplicate delivery can be legitimate under at-least-once delivery. Dead-letter transitions must not silently discard an accepted message. Durability of the target broker/database remains its own commitment, while broken adapter receipt, marker or coordination logic remains Tensor9's responsibility. |
| 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 `scaleway::1.0.0::rdb::postgresql`, The SQL queue uses row locking and SKIP LOCKED; FIFO adds head-of-group selection and deduplication state. The current long-poll loop can sleep between polls. Queue configuration is cached and durable queue state remains in PostgreSQL. A ReceiveMessage response budget is not a delivery-time promise: messages may not yet exist, may be delayed, or may be blocked by a FIFO group head. The short-poll row deliberately removes that ambiguity. Requested long-poll waits need their own measurement treatment in the agreement.

#### How the latency targets were chosen

**Small message send and settlement: +10 ms monthly p99 (adapter-added).** `ChangeMessageVisibility`, `DeleteMessage`, `SendMessage`. Native forwarding needs bounded translation; SQL adds queue state; Cosmos FIFO requires multiple durable coordination steps and cannot honestly inherit a 1 ms forwarding budget.

**Bounded short-poll receive: +10 ms monthly p99 (adapter-added).** `ReceiveMessage`. Receive scans/selects candidates, claims visibility and creates receipt handles. FIFO head selection and Cosmos slot CAS cost more than a simple send.

**Bounded message batches: +100 ms monthly p99 (adapter-added).** `DeleteMessageBatch`, `SendMessageBatch`. A conservative upper budget for up to ten point paths plus aggregation. It does not assume the implementation parallelizes all target or metadata work.

**Queue configuration and discovery: +20 ms monthly p99 (adapter-added).** `GetQueueAttributes`, `GetQueueUrl`. Queue identity, attributes, tags and counts can use the adapter's durable catalog; this is not excluded as target message work.

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

Scale send, receive and settle capacity together, and track in-flight messages, pollers, candidate scans and FIFO group skew. Adding replicas helps independent groups but cannot parallelize the ordered head of one group. The agreement caps active pollers, groups inspected per receive, message bytes, retry amplification and batch entries. Tensor9 scales the fabric within those limits; the customer supplies sufficient broker capacity, Cosmos RU/s or PostgreSQL connections and I/O.

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

Acceptance must not be returned before the documented message persistence point. Settlement must apply to the intended message/receipt; FIFO order and deduplication apply only where this directed profile supports them. Duplicate delivery can be legitimate under at-least-once delivery. Dead-letter transitions must not silently discard an accepted message. Durability of the target broker/database remains its own commitment, while broken adapter receipt, marker or coordination logic remains Tensor9's responsibility.

#### Example and diagnosis

For `order-events`, send a 2 KiB message, receive up to ten messages with WaitTimeSeconds=0, then settle each receipt. For a FIFO queue, distribute independent customers across groups instead of expecting one group to scale with replicas. If native message writes are fast but Cosmos FIFO sends slow down, inspect counter/dedup contention: those coordination waits still count against Tensor9's fabric budget.

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::sqs::fifo
```

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.