Developer documentation

How to point each protocol's official SDK at the public service, what works, what differs from the real service, and what every refusal means.

Protocol guides

Endpoints

ProtocolEndpointIdentifier goes inOther credentials
AMQP 0-9-1amqps://amqp.powerqueue.link:5673/<identifier>virtual hostany user name and password
Amazon SQShttps://sqs.powerqueue.linkaccess key idany secret key; any region
Google Pub/Subpubsub.powerqueue.link:443 (gRPC, TLS)project idnone (AnonymousCredentials)
Azure Queue Storagehttps://azure.powerqueue.link/<identifier>account name (URL path)any base64 account key, or none
Azure Service BusEndpoint=sb://amqp.powerqueue.link/ (AMQP on 5671, administration on 443)SharedAccessKeyNameany SharedAccessKey

Every endpoint uses TLS with a publicly trusted certificate; there are no plain-text endpoints. Your firewall must allow outgoing connections to port 443, and to 5671 for Service Bus or 5673 for AMQP 0-9-1.

Tenant identifiers

To generate one from a shell:

python3 -c 'import secrets, string; a = string.ascii_lowercase; print(secrets.choice(a) + "".join(secrets.choice(a + string.digits) for _ in range(23)))'

Entities need not be created

Using a queue or topic name creates it, in every protocol, and entities created that way are deleted after an hour empty and unused. Pub/Sub's rule: publishing to topic X creates subscription X, and pulling X~name creates a further subscription to X. How it works has the details for each protocol.

Limits and their errors

Each limit is refused with the protocol's own error, which the SDK raises as it would against the real service. Values above a limit are refused, never silently reduced.

LimitValue
Message size, body plus attributes256 KiB (Azure Queue Storage: 64 KiB)
Queues, topics and subscriptions per tenant (Pub/Sub schemas and snapshots count too)100
Messages per queue or subscription1,000
Message bytes per tenant, across its queues, including messages received but not yet acknowledged16 MiB
Message lifetime: retention, time to live, delay, visibility1 hour
Idle time before an implicitly created entity is deleted1 hour
Idle time before a tenant is deleted with all its data7 days
Requests per client address100 a second, bursts of 200
Connections per client address (AMQP ports)50
New connections per client address (AMQP ports)5 a second, bursts of 20
Refusals for exceeding these limits before an address is banned100 within a minute
Ban length1 minute, then 10 minutes, 1 hour, 1 day
New tenants per client address20 an hour
Tenants in the service10,000
AMQP 0-9-1 channels per connection64
Service Bus sessions / links per connection16 / 128
Pub/Sub calls in progress per client address (open streaming pulls included)100

The error for each limit

What each protocol answers when a limit is reached
RefusalAMQP 0-9-1SQSPub/SubAzure Queue StorageService Bus
Malformed identifierconnection.close 530 NOT_ALLOWED403 InvalidClientTokenIdINVALID_ARGUMENT403 AuthenticationFailed401 on the token (ServiceBusAuthenticationError); administration API 401
Too many new tenantsconnection.close 530 NOT_ALLOWED403 RequestThrottledRESOURCE_EXHAUSTED503 ServerBusycom.microsoft:server-busy; administration API 503
Message too largeconnection closed, 311 CONTENT_TOO_LARGE400 InvalidParameterValueINVALID_ARGUMENT400 MessageTooLargeamqp:link:message-size-exceeded (MessageSizeExceededError)
Entity limitchannel error 406 PRECONDITION_FAILED403 OverLimitRESOURCE_EXHAUSTED403 InsufficientAccountPermissionsadministration API 403; implicit creation amqp:resource-limit-exceeded (ServiceBusQuotaExceededError)
Queue full, or tenant holding 16 MiBpublish nacked under publisher confirms; dropped without them403 OverLimit (in a batch, the entry fails with OverLimit)RESOURCE_EXHAUSTED403 InsufficientAccountPermissionsamqp:resource-limit-exceeded (ServiceBusQuotaExceededError)
Lifetime too longqueue argument: channel error 406 PRECONDITION_FAILED; message expiration: nackedqueue attribute: 400 InvalidAttributeValue; DelaySeconds on a send: 400 InvalidParameterValueINVALID_ARGUMENT400 OutOfRangeQueryParameterValuecom.microsoft:argument-out-of-range (ServiceBusError); administration API 400
Request budget spentnot applied (bounded by connections and channels)403 RequestThrottledRESOURCE_EXHAUSTED503 ServerBusycom.microsoft:server-busy (ServiceBusServerBusyError); administration API 503
Too many connectionssocket closed before the handshakenot applied: these endpoints are behind the HTTPS proxy and bounded by the request budgetconnection closed (ServiceBusError)
Too many channels, sessions or linkschannel_max negotiated down to 64-HTTP/2 stream limit 100 (the client waits)-amqp:resource-limit-exceeded

Status codes are the HTTP status each SDK sees. Names in brackets are the Python SDK's exception classes.

Troubleshooting

"this public service needs a tenant identifier…"

The full message is:

this public service needs a tenant identifier in your SDK's credential field: a lowercase letter followed by 23 lowercase letters or digits (24 characters), chosen at random; the service's web page generates one

The field that names the tenant does not hold a valid identifier. Check, for your protocol:

Uppercase letters, hyphens, a leading digit or the wrong length are all refused.

"too many new tenants; try again later or reuse your identifier"

Your address created 20 tenants within the last hour, or the service holds its maximum of 10,000. Reuse one identifier for all your work: one tenant can hold 100 entities in every protocol.

Throttling

More than 100 requests a second from one address (after a burst of 200) are answered with the protocol's throttling error: SQS RequestThrottled, Pub/Sub RESOURCE_EXHAUSTED, Azure ServerBusy, Service Bus server-busy. The SDKs treat these as retryable and back off on their own, so you usually see slower calls rather than errors. If you turned retries off, retry with back-off yourself. Batch operations (SQS SendMessageBatch, Pub/Sub's batching publisher, Azure's 32-message gets) do more per request.

An address that keeps exceeding the limits, refused 100 times within a minute, is banned for a while: a minute the first time, then 10 minutes, an hour, and a day each time after, until it has gone a day without a ban. While banned, its HTTP requests are answered 429 Too Many Requests with Retry-After (Pub/Sub RESOURCE_EXHAUSTED), and its AMQP connections are closed at once. Client libraries that back off after a throttling error never get near this.

Long-lived streams count each request on them: a Pub/Sub streaming pull counts each acknowledgement request, and a Service Bus connection counts each message sent and each link attached.

Size errors

The size limit counts the body plus attributes, headers or properties. At 256 KiB of body you are already over if you add any attributes. Azure Queue Storage measures the message text after any encoding your SDK applies (base64 grows it by a third) against 64 KiB. AMQP 0-9-1 is strictest: an oversized message closes the whole connection with 311 CONTENT_TOO_LARGE. The broker advertises its limit as max_message_size in its connection properties.

Queue full

A queue or subscription holding 1,000 messages, or a tenant holding 16 MiB of messages across its queues (counting messages received but not yet acknowledged), refuses further sends until something is consumed. Pub/Sub's publisher retries RESOURCE_EXHAUSTED, so a publish to a full subscription can wait until its deadline. AMQP 0-9-1 publishers only learn of the refusal with publisher confirms on (confirm.select).

My queue or messages disappeared

Pub/Sub pull answers NOT_FOUND

A pull names only a subscription, so an unknown name cannot be created. Pull subscription X after publishing to topic X, pull X~something, or create the subscription with CreateSubscription.

Connection or TLS errors