Edit

Multitenancy and Azure Queue Storage

Azure Queue Storage stores messages for asynchronous processing. This article describes partitioning strategies, isolation models, and Queue Storage features for multitenant solutions. It provides guidance that can help you distribute message load, isolate tenants' messages, and manage access, encryption, and usage.

Partitioning strategies

Queue Storage doesn't expose a partition key or subqueue within a queue. The queue is the smallest boundary that you can use to distribute message load, and the storage account is the next boundary. A shared queue doesn't provide tenant-specific throughput or performance isolation.

For messages that are 1 KiB, a single queue has a target throughput of up to 2,000 messages per second, and a storage account has a maximum request rate of 20,000 messages per second. Message size and access patterns affect the throughput that your workload achieves. Queue messages can be up to 64 KiB. For larger messages or advanced broker features, consider using Azure Service Bus.

If your workload can exceed the per-queue target, distribute messages across multiple queues. Depending on your routing and operational requirements, you can partition queues by tenant, tenant group or service tier, functional workload, deployment stamp, or region. A high-volume tenant that shares a queue with other tenants can consume a disproportionate share of the queue's throughput and cause throttling for other tenants.

Multiple queues in the same storage account still share the account's capacity and account-level configuration. If the aggregate workload can exceed the storage account target, or if a tenant needs independent scale or regional configuration, distribute queues across multiple storage accounts. Monitor for throttling, use exponential-backoff retries, and test your workload against the documented Queue Storage scalability targets. For tenant access and data isolation options, see Isolation models.

Isolation models

After you determine how to distribute message load, determine the level of tenant isolation to apply. Queue Storage supports shared queues, queues for each tenant, and storage accounts for each tenant. The following table summarizes the differences between the main tenancy isolation models for Queue Storage.

Consideration Shared queues Queues for each tenant Storage accounts for each tenant
Data isolation Low. The application enforces isolation. Low-medium High
Performance isolation Low Low. Most quotas and limits apply to the entire storage account. High
Deployment complexity Low Medium High
Operational complexity Low Medium High
Example scenario A large multitenant solution has a shared application tier. Tenant-scoped shared access signature (SAS) URLs are issued. Each tenant has its own deployment stamp.

Note

Consider quotas and limits when you select an isolation model. These limits include Azure service limits, Queue Storage scalability targets, and scalability targets for the Storage resource provider.

Shared queues

If you share a queue, all tenants share its throughput target. A busy tenant can cause throttling for other tenants. For strategies to distribute message load, see Partitioning strategies.

Queues don't provide partitioning or subqueues, so all tenants' data might become intermingled. Your application must identify the tenant for each message and enforce isolation during processing. Don't grant tenants direct access to a shared queue if they must not access other tenants' messages.

Queues for each tenant

You can create individual queues for each tenant within a single storage account. There's no limit to the number of queues that you can create within a storage account.

Queues for each tenant provide a routing and access-control boundary, but they don't provide performance isolation. All queues in the account share the storage account's capacity and performance targets.

For this scenario, you can use Queue Storage access control, including SAS, to manage access for each tenant's data.

When you dynamically create queues for each tenant, consider how your application tier consumes the messages from each tenant's queue. For advanced scenarios, consider using Azure Service Bus, which supports features such as sessions, message autoforwarding, and topics and subscriptions.

Storage accounts for each tenant

The strongest level of isolation uses a dedicated storage account for each tenant. This model ensures full isolation of storage account keys, which you can rotate independently. It also allows you to scale your solution beyond the limits and quotas for each storage account. Consider this model for tenants that have sustained high message volumes or require independent regional configuration or performance targets. But you must also consider the maximum number of storage accounts allowed within a single Azure subscription.

Features of Queue Storage that support multitenancy

The following Queue Storage features can help you implement and operate your chosen isolation model.

Shared access signatures

When you use Queue Storage from a client application, consider whether to route requests through your application tier or allow clients to connect directly to a queue. Direct client access can reduce the load on your back-end applications and the number of network hops.

A shared access signature (SAS) enables you to provide client applications with limited access to a queue. You can restrict the operations that a client can perform and the time period when access is allowed. For example, you can issue a SAS that lets a tenant add messages to its own queue without permitting it to read or delete messages.

Use the Valet Key pattern to issue constrained and scoped SAS tokens from your application tier. Authenticate the client by using your application's authentication system, determine which tenant's queue they can access, and issue a token for only the required operations.

Stored access policies enable you to define a single policy to use when you issue multiple service SAS tokens. Stored access policies don't apply to user delegation SAS tokens or account SAS tokens.

User delegation SAS

A service SAS or account SAS is signed with one of your storage account keys. A user delegation SAS is secured with Microsoft Entra credentials instead. Your application tier requests a user delegation key by using its own managed identity, then signs scoped, time-limited tokens for each tenant. You don't distribute or store account keys. Microsoft recommends using a user delegation SAS instead of an account-key SAS when your design supports it.

Use short token lifetimes and plan how to revoke access if a token is compromised. To correlate your application logs with Queue Storage logs, set a client request ID (x-ms-client-request-id) on storage requests and log it alongside the tenant ID.

Identity-based access control

Queue Storage provides identity-based access control through Microsoft Entra ID. Use managed identities and Azure role-based access control to authorize your application to access queues without storing account keys. Scope access to each tenant's queue when tenants require direct access. Queue-level authorization doesn't isolate individual tenants' messages within a shared queue.

Encryption

Queue Storage encrypts data at rest with Microsoft-managed keys by default. To use customer-managed keys, configure the storage account to use an account-scoped encryption key for queues when you create the account. You can't change this encryption key scope after account creation.

If tenants require separate customer-managed keys, use separate storage accounts. Blob Storage encryption scopes and customer-provided keys on individual requests don't apply to Queue Storage. Plan key rotation and revocation alongside your tenant life cycle.

Monitoring

In a multitenant solution, consider whether you need to measure the consumption for each tenant. Define the specific metrics to track, such as the number of messages or operations for each tenant. You can also use cost allocation to track the cost of each tenant's usage and enable chargeback across multiple subscriptions.

Queue Storage provides built-in monitoring capabilities. When tenants share a queue, include tenant identifiers in your application telemetry so that you can attribute message processing and usage to the correct tenant.

Monitor request rates and HTTP 500 and 503 responses to detect queues or accounts that approach scalability targets. Correlate this telemetry with tenant identifiers so that you can identify tenants whose usage affects shared capacity.

You can collect request logs, then aggregate and analyze them alongside your application telemetry. In solutions that create high volumes of requests, consider whether the benefit justifies the cost to capture and process those logs.

Contributors

Microsoft maintains this article. The following contributors wrote this article.

Principal author:

  • John Downs | Principal Software Engineer, Azure Patterns & Practices

Other contributors:

To see nonpublic LinkedIn profiles, sign in to LinkedIn.