Before running a
tensor9 command, install the CLI, set T9_API_KEY, and verify your customer account. Online commands are authenticated and their adapter detail is limited to mappings your account is entitled to use.Decide what you are changing
There are three places to tune a queue workload:VisibilityTimeout is already an SQS attribute. Supply it through the SQS API. A queue’s PostgreSQL server size is a different kind of choice: several queues can share that server, so changing one queue’s tags must not resize all of its neighbors.
The t9:tuning:<path> mechanism is for documented target-native fields. A target cloud’s API field is not automatically an accepted queue tuning path. Use the exact paths published for the selected mapping; do not turn a native console setting into a guessed tag. See Tuning Your Adapters.
Choose a backend
Choose Classic for independent at-least-once messages or FIFO for per-group order and the selected deduplication contract. Extra capacity cannot turn a Classic broker mapping into FIFO, remove group serialization or supply a missing receipt authority.
The presence of a native queue service in a cloud does not make it an available backend. Choose a current catalog direction returned for your account by
tensor9 adapt svc list.
Backend selection is made when the queue is created. For example:
tags property is the AWS CLI’s CreateQueue input shape. t9:backend selects where this queue is placed. It is not a setting that moves an existing queue when updated with TagQueue.
Try SQS on Pub/Sub
This experiment requires an already-running, owned test install that is licensed and configured to serve Classic SQS on native Pub/Sub. It does not install or start Cloud Adapter, select a FIFO composite or establish another release/backend’s availability. Use its actual authenticated SQS endpoint, signing Region and existing origin workload credentials. This example creates a disposable Standard queue with two minutes of visibility, twenty-second long polling and four-day retention. Use a test project and a fresh queue name.1
Confirm the existing install and permissions
Obtain the test install’s SQS endpoint, signing Region, existing origin workload profile, selected runtime/backend and native resource owner. Confirm permission to create a fresh disposable queue and no other consumers on that queue. Read the mapping’s visibility, delay and dead-letter contract before the experiment.The install owner supplies its valid license, persistent control state, actual backend configuration and target credentials. Google lifecycle permissions differ from publish/consume permissions. Merely installing the Tensor9 CLI and configuring Application Default Credentials does not establish a serving adapter. Use installation and authentication and configuration for setup outside this experiment.
2
Point the AWS CLI at the adapter
In a shell with the existing AWS workload profile, configure the actual endpoint and signing Region:
AWS_ENDPOINT_URL_SQS applies to SQS commands in this shell. You can instead put --endpoint-url "$T9_CLOUD_ADAPTER_ENDPOINT" on each command. The existing profile supplies the origin-facing identity; Google Cloud credentials and target configuration belong to the running install. A Tensor9 account API key does not replace these SQS workload credentials.3
Create and inspect the queue
Save the preceding JSON as Confirm the three declared attributes and the selected backend. Also inspect the native Pub/Sub subscription’s acknowledgement deadline and retention. A successful queue create is not a measurement of workload performance.
notifications-tuning.json, then run:4
Send, receive and settle one message
Send a small representative payload:Copy the returned receipt handle. After processing the message, settle that exact receive:Record the successful delete acknowledgement and the processed job ID. Observe native subscription backlog and redelivery over an appropriate interval. Neither an empty receive nor an immediate metric alone proves settlement: metrics can lag, and a message can still be hidden by its visibility timeout.
5
Finish the trial
Confirm all test messages are settled. Remove only the disposable queue and resources created for this trial, using the lifecycle owner that created them. Deleting a logical queue does not always delete its pre-provisioned native infrastructure.Leave the existing install running under its owner. Clear the endpoint override if you are returning to native AWS work:
Pub/Sub: tune visibility, batching and retries
Pub/Sub is a good starting point for independent, short-running jobs. Its acknowledgement deadline constrains the SQS visibility lease.Example: workers taking 45–90 seconds
Start with a 120-second queue visibility timeout:Example: receive ten messages without hiding unstarted work
Example: tolerate several attempts before dead-letter delivery
Pub/Sub accepts a dead-letter threshold of 5–100 delivery attempts. For a threshold of ten, the SQS policy has this shape:ApproximateReceiveCount is meaningful on this backend only when the dead-letter policy and its permissions are configured. A queue without that policy reports 1; that value must not drive an application poison-message cutoff.
Example: delayed jobs
A nonzeroDelaySeconds does not map to Pub/Sub. If the job must become available five minutes after publication, choose the PostgreSQL backend and use a per-message delay. A longer visibility timeout is not a substitute: visibility begins when a consumer receives a message, while delivery delay applies before its first receive.
PostgreSQL for delayed or long-running work
Direct PostgreSQL serves Classic and FIFO using the SQS-owned message database on the selected host, including Cloud SQL, Azure Flexible Server and CloudNativePG. Host placement changes recovery and operation: a managed database outside the cluster survives replacement of that cluster; cluster-hosted volumes need explicit recovery. Performance depends on physical capacity, storage, network placement and workload. The direct FIFO engine permits one message in flight per group; ordered-batch alternatives are separate designs.Prepare the shared database
Prepare the SQS-owned message database and its authenticated runtime connection through the installation’s resource owner. It is distinct from the persistent shared PostgreSQL control catalog. A separate logical database/login provides data and permission isolation, but shares CPU, IOPS, WAL and server connection limits when it uses the same instance. Dedicated physical server capacity is an additional allocation. See Configuration Files for the existing binding contract; do not invent a native tuning tag for credentials or infrastructure. For the following Cloud SQL experiment, obtain an already-running owned test endpoint licensed and configured for Classic SQS on Cloud SQL. Its owner must have prepared the actual SQS message binding, target database credentials and persistent control state. Use the endpoint/profile/Region steps above with this install’s values. Do not assume a previous endpoint or queue URL selects the new backend. This experiment supplies no first-install launcher command or configuration document.Example: export jobs with a fifteen-minute processing budget
Example: defer a job for five minutes
After creating the export queue, save its returned URL asSQS_EXPORT_QUEUE_URL:
Example: size a server for two queues
Supposeemail-jobs receives small messages all day and export-jobs produces a large evening burst. Both queues share one PostgreSQL server. Measure them together: a test of email-jobs alone cannot show whether the export burst will delay it.
Make these changes through the infrastructure that owns the database. A
CreateQueue tag does not resize the shared server. Likewise, adding more adapter processes does not add database capacity; it can increase the number of competing database connections.
For direct FIFO, measure the busiest group’s receive-to-settlement time. A group taking T seconds per settled head is bounded by roughly 1/T useful completions, regardless of idle capacity elsewhere. More independent ready groups can improve aggregate concurrency. A larger receive collects multiple group heads rather than a pipeline within one group. Test stalled groups and bounded scheduler/receiver slots; do not infer fairness from average throughput.
Tune Azure and transactional alternatives by their actual authority
Native Service Bus
ReceiveRequestAttemptId replay is unsupported; broker duplicate detection is not a durable receive-attempt record. Group-partitioned Cosmos also rejects explicit attempt IDs. Queue-scope Cosmos and the transactional ordered-batch designs replay unchanged five-minute attempts, with explicit restrictions after claims are modified. Do not assume those behaviors from direct PostgreSQL’s simpler one-head engine.
Cosmos queue-wide deduplication keeps the entire queue in one authoritative partition. MessageGroup scope distributes groups only when explicitly selected and changes which duplicate IDs are suppressed. The selected profile’s 256-KB message admission is separate from larger native document/transaction limits; those limits do not automatically raise accepted SQS message size. Include payload, attributes/index overhead, dedup markers, attempts, terminal records and cleanup lag in retained bytes. The 20-GB logical-partition ceiling applies to the whole queue or busiest group respectively. A capacity upgrade does not change the scope or raise that storage limit. Serverless-to-provisioned conversion is account-wide and irreversible; it needs an explicit resource decision.
Queue Storage’s unchanged current native receipt permits Receive→Delete across adapter restart. Successful native visibility changes rotate that token without returning a replacement SQS handle. The native design does not specify the retained alias authority needed to preserve post-update SQS operations over arbitrary replicas/restarts. Treat visibility updates and subsequent settlement as conditional; without qualified mapping, the supported contract requires refusal before effects. No Table or SQL alias resource is implicitly selected.
Atomic dead-letter moves require source and destination in the same supported SQS-owned message transaction. Separate databases on one server, different stores or the shared control catalog do not provide that atomicity. Cosmos cross-partition/store transfers are unsupported in the transactional FIFO design. Classic copy/delete paths and application poison routing have different guarantees.
Respect backend limits
For Pub/Sub, nonzero queue- or message-level delay, retention below ten minutes, visibility outside the documented range and a dead-letter threshold outside 5–100 are rejected. They are not adjusted into equivalent behavior. Native subscription/delivery receipt effectiveness follows acknowledgement deadlines and redelivery, with no qualified restart-continuity guarantee. Google Cloud backlog metrics are operational observations with their own timing and definitions; they are not SQS visible/in-flight/delayed availability counts. Pure Pub/Sub has no authoritative source for those SQS attributes in this design. For PostgreSQL, use the configured profile’s message and retention limits. Cleanup can remove messages in flight; stale receipts cannot settle a newer claim. Requested counts read one message-state snapshot: eligible rows are visible, future-visible rows with receipts are in flight, and future-visible rows without receipts are initially delayed. They can change immediately afterward. Unavailable requested counts return an explicit unsupported result, not a fabricated zero. Read the Cloud SQL PostgreSQL profile before designing alerts around these responses. For CloudNativePG, a full cluster rebuild loses queue data unless a separate recovery procedure restores it. Test with the exact PostgreSQL image/version, adapter version, queue schema and topology you will run. The available Standard-queue benchmark does not establish another host’s capacity or verify message and claim recovery after a database outage. Test those recovery paths separately before production.Measure the workload before changing capacity
Use a bounded workload with known message count, payload size and processing duration. Keep those inputs the same when comparing two settings.
Record send success, receive-to-delete latency, end-to-end completion latency, retries, failed batch entries and duplicate processing. Observe native backend metrics as well as origin-shaped responses. A successful batch HTTP response can still contain failed entries.
Measure body, attributes and transport-envelope bytes; busiest-group fraction; active ready groups; settlement duration; retained backlog; conflicts; retries and cleanup. Missing sizes, observation windows or distributions remain unknown, rather than taking a benchmark’s assumed payload. The historical Classic offered-load benchmark does not establish another host, FIFO, HA, capacity mode or composite’s ceiling.
Count polling is a separate cost: PostgreSQL scans the message population even when one counter is requested, competing for pool and I/O capacity as backlog grows. Metadata-only reads avoid count work. Track count-query frequency separately from successful sends, attempts and completed cycles. Queue depth can fall after purge, expiry or dead-letter transfer without an application completion.
Include the adapter and allocated persistent shared control PostgreSQL compute/storage/backup/HA in total cost, even for native/serverless message storage. Add any separate SQL message authority, selected capacity floors, broker traffic, repair/outbox retries, retained state and cleanup. Use generated SQS costs only within the displayed scenario’s scope; see total cost trade-offs.
Change one setting and verify its effect
1
Capture the baseline
Save the queue attributes, tags, backend selection, native resource settings and workload results. Include the adapter version and the shared database capacity or Pub/Sub resource settings.
2
Choose the owner of the change
Use SQS attributes for queue behavior, the documented target tuning contract for a resource-specific override, or installation infrastructure for shared capacity. A backend move requires a new queue and a cutover procedure.
3
Apply a bounded change
Use a disposable queue or controlled test workload first. Changing visibility affects how long another worker waits after a failure; changing retention affects how long work remains recoverable. Keep those consequences in the experiment.
4
Read back both sides
Read the declared SQS attribute and the relevant native setting. Run the behavior that setting controls: delay a message, let a claim expire, retry a send or exercise the dead-letter path. Use tensor9 explain and diagnostic headers when the observed behavior differs from the mapping.
5
Keep or reverse the change
Restore the previous mutable setting through the same owner if results are worse. A larger capacity allocation does not necessarily roll back without operational effects, and restoring retention cannot recover messages that have already expired.For a backend change, drain or otherwise account for the old queue’s messages before redirecting producers and consumers. Changing
t9:backend on an existing queue is not a message migration.x-t9-explain-* response headers, queue attributes and the message’s attempt history. See Debugging Your Adapters.