Azure Functions Queue Triggers
Queue triggers allow your Azure Functions to execute in response to messages being added to an Azure Queue Storage queue or a Service Bus queue.
Introduction
When a new message arrives in a configured queue, the Azure Functions runtime automatically triggers your function. This is a powerful pattern for building event-driven applications, decoupling services, and processing background tasks.
How It Works
The Functions runtime monitors the specified queue. Upon detecting a new message, it deserializes the message content and passes it as input to your function. After successful execution, the message is typically dequeued. If the function fails, the message may be retried or handled as a poison message.
Supported Queue Services
Azure Functions supports triggers for the following queueing services:
- Azure Queue Storage: A simple, cost-effective queueing service for decoupling application components.
- Azure Service Bus Queues: A fully managed message broker offering advanced features like transactions, duplicate detection, and ordering.
- Azure Service Bus Topics: While primarily a pub/sub pattern, Service Bus Topics can be used with subscriptions that act like queues to trigger functions.
Creating a Queue Trigger
You can create a queue-triggered function using the Azure portal, Azure CLI, Azure Functions Core Tools, or by defining it in your application's code.
Example: Function.json (for older runtime versions or specific configurations)
{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "msg",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "my-queue-name",
      "connection": "AzureWebJobsStorage"
    }
  ]
}
            Example: Python Code (using decorators)
import logging
import azure.functions as func
def main(msg: func.QueueMessage) -> None:
    logging.info('Python queue trigger function processed a body: %s',
                 msg.get_body().decode('utf-8'))
    # You can access message properties like this:
    logging.info(f"Message ID: {msg.id}")
    logging.info(f"Dequeue count: {msg.dequeue_count}")
            connection setting refers to an application setting that contains the connection string for the queue service. The default is usually AzureWebJobsStorage, which points to your Azure Storage account. For Service Bus, it might be a different name like ServiceBusConnectionString.
            Trigger Configuration
Queue triggers have several configuration options:
| Property | Description | Required | Default | 
|---|---|---|---|
| name | The name of the parameter in your function code that will receive the message. | Yes | N/A | 
| type | Must be queueTrigger. | Yes | N/A | 
| direction | Must be infor triggers. | Yes | N/A | 
| queueName | The name of the queue to monitor. | Yes | N/A | 
| connection | The name of the application setting containing the queue service connection string. | No | AzureWebJobsStorage(for Azure Queue Storage) | 
| accessRights | For Service Bus, specifies if the trigger needs read, listen, or manage rights. | No | listen | 
| isSessionsEnabled | For Service Bus, set to trueif the queue/topic subscription uses sessions. | No | false | 
Code Examples
C# Example
using Azure.Storage.Queues.Models;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace Company.Function
{
    public class QueueTriggerCSharp
    {
        [Function("QueueTriggerCSharp")]
        public void Run(
            [QueueTrigger("my-queue-name", Connection = "AzureWebJobsStorage")] QueueMessage message,
            FunctionContext context)
        {
            var logger = context.GetLogger("QueueTriggerCSharp");
            logger.LogInformation($"C# Queue trigger function processed: {message.MessageText}");
            logger.LogInformation($"Dequeue count: {message.DequeueCount}");
        }
    }
}
            JavaScript Example
module.exports = async function (context, myQueueItem) {
    context.log('JavaScript queue trigger function processed work item', myQueueItem);
    context.log('Message ID:', context.bindingData.messageId);
    context.log('Dequeue count:', context.bindingData.dequeueCount);
};
            Handling Poison Messages
A "poison message" is a message that causes a function to fail repeatedly. Azure Functions provides built-in mechanisms to handle these:
- Dequeue Count: The runtime tracks how many times a message has been dequeued.
- MaximumDequeueCount: You can configure a threshold (e.g., 5) after which a message is considered "poison."
- Poison Message Handling: When a message exceeds the maximum dequeue count, it's typically moved to a special "poison queue" (or logged extensively) to prevent infinite loops and allow for manual inspection or reprocessing.
Configuration
The maxDequeueCount setting is typically configured in your host.json file:
{
  "version": "2.0",
  "extensions": {
    "queues": {
      "maxDequeueCount": 5,
      "visibilityTimeout": "00:00:30",
      "batchSize": 16,
      "newBatchThreshold": 4
    }
  }
}
            Best Practices
- Idempotency: Design your functions to be idempotent, meaning that processing the same message multiple times has the same effect as processing it once. This is crucial for handling retries.
- Error Handling: Implement robust error handling within your function to catch exceptions gracefully.
- Logging: Log sufficient information about the message content and processing steps to aid in debugging.
- Connection Strings: Store connection strings securely in application settings, not directly in your code.
- Message Size: Be mindful of message size limits for the queue service you are using.
- Service Bus Sessions: If dealing with ordered processing, leverage Service Bus sessions.