| name | azure-storage-queue-ts |
| description | Azure Queue Storage JavaScript/TypeScript SDK (@azure/storage-queue) for message queue operations. Use for sending, receiving, peeking, and deleting messages in queues. |
| risk | unknown |
| source | community |
| date_added | 2026-02-27 |
@azure/storage-queue (TypeScript/JavaScript)
SDK for Azure Queue Storage operations ā send, receive, peek, and manage messages in queues.
Installation
npm install @azure/storage-queue @azure/identity
Current Version: 12.x
Node.js: >= 18.0.0
Environment Variables
AZURE_STORAGE_ACCOUNT_NAME=<account-name>
AZURE_STORAGE_ACCOUNT_KEY=<account-key>
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
Authentication
DefaultAzureCredential (Recommended)
import { QueueServiceClient } from "@azure/storage-queue";
import { DefaultAzureCredential } from "@azure/identity";
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const client = new QueueServiceClient(
`https://${accountName}.queue.core.windows.net`,
new DefaultAzureCredential()
);
Connection String
import { QueueServiceClient } from "@azure/storage-queue";
const client = QueueServiceClient.fromConnectionString(
process.env.AZURE_STORAGE_CONNECTION_STRING!
);
StorageSharedKeyCredential (Node.js only)
import { QueueServiceClient, StorageSharedKeyCredential } from "@azure/storage-queue";
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY!;
const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
const client = new QueueServiceClient(
`https://${accountName}.queue.core.windows.net`,
sharedKeyCredential
);
SAS Token
import { QueueServiceClient } from "@azure/storage-queue";
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const sasToken = process.env.AZURE_STORAGE_SAS_TOKEN!;
const client = new QueueServiceClient(
`https://${accountName}.queue.core.windows.net${sasToken}`
);
Client Hierarchy
QueueServiceClient (account level)
āāā QueueClient (queue level)
āāā Messages (send, receive, peek, delete)
Queue Operations
Create Queue
const queueClient = client.getQueueClient("my-queue");
await queueClient.create();
await queueClient.createIfNotExists();
List Queues
for await (const queue of client.listQueues()) {
console.log(queue.name);
}
for await (const queue of client.listQueues({ prefix: "task-" })) {
console.log(queue.name);
}
Delete Queue
await queueClient.delete();
await queueClient.deleteIfExists();
Get Queue Properties
const properties = await queueClient.getProperties();
console.log("Approximate message count:", properties.approximateMessagesCount);
console.log("Metadata:", properties.metadata);
Set Queue Metadata
await queueClient.setMetadata({
department: "engineering",
priority: "high",
});
Message Operations
Send Message
const queueClient = client.getQueueClient("my-queue");
await queueClient.sendMessage("Hello, World!");
await queueClient.sendMessage("Delayed message", {
visibilityTimeout: 60,
messageTimeToLive: 3600,
});
const task = { type: "process", data: { id: 123 } };
await queueClient.sendMessage(JSON.stringify(task));
Receive Messages
const response = await queueClient.receiveMessages({
numberOfMessages: 10,
visibilityTimeout: 30,
});
for (const message of response.receivedMessageItems) {
console.log("Message ID:", message.messageId);
console.log("Content:", message.messageText);
console.log("Dequeue Count:", message.dequeueCount);
console.log("Pop Receipt:", message.popReceipt);
await queueClient.deleteMessage(message.messageId, message.popReceipt);
}
Peek Messages
Peek without removing from queue (no visibility timeout).
const response = await queueClient.peekMessages({
numberOfMessages: 5,
});
for (const message of response.peekedMessageItems) {
console.log("Message ID:", message.messageId);
console.log("Content:", message.messageText);
}
Update Message
Extend visibility timeout or update content.
const response = await queueClient.receiveMessages();
const message = response.receivedMessageItems[0];
if (message) {
const updateResponse = await queueClient.updateMessage(
message.messageId,
message.popReceipt,
"Updated content",
60
);
console.log("New pop receipt:", updateResponse.popReceipt);
}
Delete Message
const response = await queueClient.receiveMessages();
const message = response.receivedMessageItems[0];
if (message) {
await queueClient.deleteMessage(message.messageId, message.popReceipt);
}
Clear All Messages
await queueClient.clearMessages();
Message Processing Patterns
Basic Worker Pattern
async function processQueue(queueClient: QueueClient): Promise<void> {
while (true) {
const response = await queueClient.receiveMessages({
numberOfMessages: 10,
visibilityTimeout: 30,
});
if (response.receivedMessageItems.length === 0) {
await sleep(5000);
continue;
}
for (const message of response.receivedMessageItems) {
try {
await processMessage(message.messageText);
await queueClient.deleteMessage(message.messageId, message.popReceipt);
} catch (error) {
console.error(`Failed to process message ${message.messageId}:`, error);
}
}
}
}
async function processMessage(content: string): Promise<void> {
const task = JSON.parse(content);
}
function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
Poison Message Handling
const MAX_DEQUEUE_COUNT = 5;
async function processWithPoisonHandling(
queueClient: QueueClient,
poisonQueueClient: QueueClient
): Promise<void> {
const response = await queueClient.receiveMessages({
numberOfMessages: 10,
visibilityTimeout: 30,
});
for (const message of response.receivedMessageItems) {
if (message.dequeueCount > MAX_DEQUEUE_COUNT) {
await poisonQueueClient.sendMessage(message.messageText);
await queueClient.deleteMessage(message.messageId, message.popReceipt);
console.log(`Moved message ${message.messageId} to poison queue`);
continue;
}
try {
await processMessage(message.messageText);
await queueClient.deleteMessage(message.messageId, message.popReceipt);
} catch (error) {
console.error(`Processing failed (attempt ${message.dequeueCount}):`, error);
}
}
}
Batch Processing with Visibility Extension
async function processBatchWithExtension(queueClient: QueueClient): Promise<void> {
const response = await queueClient.receiveMessages({
numberOfMessages: 1,
visibilityTimeout: 60,
});
const message = response.receivedMessageItems[0];
if (!message) return;
let popReceipt = message.popReceipt;
const extensionInterval = setInterval(async () => {
try {
const updateResponse = await queueClient.updateMessage(
message.messageId,
popReceipt,
message.messageText,
60
);
popReceipt = updateResponse.popReceipt;
} catch (error) {
console.error("Failed to extend visibility:", error);
}
}, 45000);
try {
await longRunningProcess(message.messageText);
await queueClient.deleteMessage(message.messageId, popReceipt);
} finally {
clearInterval(extensionInterval);
}
}
Message Encoding
By default, messages are Base64 encoded. You can customize this:
import { QueueClient } from "@azure/storage-queue";
const queueClient = new QueueClient(
`https://${accountName}.queue.core.windows.net/my-queue`,
credential,
{
messageEncoding: "text",
}
);
const customQueueClient = new QueueClient(
`https://${accountName}.queue.core.windows.net/my-queue`,
credential,
{
messageEncoding: {
encode: (message: string) => Buffer.from(message).toString("base64"),
decode: (message: string) => Buffer.from(message, "base64").toString(),
},
}
);
SAS Token Generation (Node.js only)
Generate Queue SAS
import {
QueueSASPermissions,
generateQueueSASQueryParameters,
StorageSharedKeyCredential,
} from "@azure/storage-queue";
const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
const sasToken = generateQueueSASQueryParameters(
{
queueName: "my-queue",
permissions: QueueSASPermissions.parse("raup"),
startsOn: new Date(),
expiresOn: new Date(Date.now() + 3600 * 1000),
},
sharedKeyCredential
).toString();
const sasUrl = `https://${accountName}.queue.core.windows.net/my-queue?${sasToken}`;
Generate Account SAS
import {
AccountSASPermissions,
AccountSASResourceTypes,
AccountSASServices,
generateAccountSASQueryParameters,
} from "@azure/storage-queue";
const sasToken = generateAccountSASQueryParameters(
{
services: AccountSASServices.parse("q").toString(),
resourceTypes: AccountSASResourceTypes.parse("sco").toString(),
permissions: AccountSASPermissions.parse("rwdlacupi"),
expiresOn: new Date(Date.now() + 24 * 3600 * 1000),
},
sharedKeyCredential
).toString();
Error Handling
import { RestError } from "@azure/storage-queue";
try {
await queueClient.sendMessage("test");
} catch (error) {
if (error instanceof RestError) {
switch (error.statusCode) {
case 404:
console.log("Queue not found");
break;
case 400:
console.log("Bad request - message too large or invalid");
break;
case 403:
console.log("Access denied");
break;
case 409:
console.log("Queue already exists or being deleted");
break;
default:
console.error(`Storage error ${error.statusCode}: ${error.message}`);
}
}
throw error;
}
TypeScript Types Reference
import {
QueueServiceClient,
QueueClient,
StorageSharedKeyCredential,
AnonymousCredential,
QueueSASPermissions,
AccountSASPermissions,
AccountSASServices,
AccountSASResourceTypes,
generateQueueSASQueryParameters,
generateAccountSASQueryParameters,
DequeuedMessageItem,
PeekedMessageItem,
QueueSendMessageResponse,
QueueReceiveMessageResponse,
QueueUpdateMessageResponse,
QueueItem,
QueueGetPropertiesResponse,
RestError,
} from "@azure/storage-queue";
Message Limits
| Limit | Value |
|---|
| Max message size | 64 KB |
| Max visibility timeout | 7 days |
| Max time-to-live | 7 days (or -1 for infinite) |
| Max messages per receive | 32 |
| Default visibility timeout | 30 seconds |
Best Practices
- Use DefaultAzureCredential ā Prefer AAD over connection strings/keys
- Always delete after processing ā Prevent duplicate processing
- Handle poison messages ā Move failed messages to a dead-letter queue
- Use appropriate visibility timeout ā Set based on expected processing time
- Extend visibility for long tasks ā Update message to prevent timeout
- Use JSON for structured data ā Serialize objects to JSON strings
- Check dequeueCount ā Detect repeatedly failing messages
- Use batch receive ā Receive multiple messages for efficiency
Platform Differences
| Feature | Node.js | Browser |
|---|
StorageSharedKeyCredential | ā
| ā |
| SAS generation | ā
| ā |
| DefaultAzureCredential | ā
| ā |
| Anonymous/SAS access | ā
| ā
|
| All message operations | ā
| ā
|
When to Use
This skill is applicable to execute the workflow or actions described in the overview.
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.