Queue Storage Bindings

This document explains how to use Queue Storage bindings with Azure Functions.

Note: Azure Functions supports different versions of bindings. This documentation primarily refers to v4 bindings, the latest recommended version.

Queue Storage bindings enable you to connect your Azure Functions to Azure Queue Storage. You can use these bindings to trigger a function when a new message is added to a queue, or to write messages to a queue from within your function.

Output Bindings

You can configure your function to write messages to a Queue Storage queue. This is useful for queuing up work to be processed by other services or functions.

Configuration

In your function.json file, define an output binding of type queue. You'll need to specify the connection string setting name (connection) and the name of the queue (queueName).

{
  "bindings": [
    {
      "name": "outputQueueItem",
      "type": "queue",
      "direction": "out",
      "queueName": "my-output-queue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Usage in Code

In your function code, you can access the output binding to add messages to the queue. The way you do this depends on the language you are using:

C#

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

public class QueueOutputFunction
{
    [Function("QueueOutputTrigger")]
    public void Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
        [Queue("my-output-queue", Connection = "AzureWebJobsStorage")] out string outputQueueItem,
        FunctionContext context)
    {
        var logger = context.GetLogger<QueueOutputFunction>();
        logger.LogInformation("C# HTTP trigger function processed a request.");

        string message = $"Message from HTTP trigger at: {DateTime.UtcNow}";
        outputQueueItem = message;
        logger.LogInformation($"Sent message to output queue: {message}");
    }
}

JavaScript/TypeScript

const { app } = require("@azure/functions");

app.http("QueueOutputTrigger", {
    methods: ["GET", "POST"],
    authLevel: "Anonymous",
    handler: async (request, context) => {
        context.log("JavaScript HTTP trigger function processed a request.");

        const message = `Message from HTTP trigger at: ${new Date().toISOString()}`;

        context.bindings.outputQueueItem = message; // Assign to output binding

        context.log(`Sent message to output queue: ${message}`);

        return {
            status: 200,
            body: "Message queued successfully!"
        };
    },
    extraInputs: [app.storage.httpTrigger.input()], // Not strictly needed for output binding, but good practice
    extraOutputs: [app.storage.queue("outputQueueItem", {
        queueName: "my-output-queue",
        connection: "AzureWebJobsStorage"
    })]
});

Python

import azure.functions as func
import datetime
import logging

def main(req: func.HttpRequest, outputQueueItem: func.Out[str]) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    message = f"Message from HTTP trigger at: {datetime.datetime.utcnow()}"
    outputQueueItem.set(message)  # Set the message for the output binding

    logging.info(f"Sent message to output queue: {message}")

    return func.HttpResponse(
        "Message queued successfully!",
        status_code=200
    )

Input Bindings

You can configure your function to be triggered by new messages in a Queue Storage queue. This is a common pattern for processing work items.

Configuration

In your function.json file, define an input binding of type queueTrigger. You'll need to specify the connection string setting name (connection) and the name of the queue (queueName).

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "my-input-queue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Usage in Code

In your function code, the message content will be passed to your function based on the binding name.

C#

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

public class QueueInputFunction
{
    [Function("QueueInputTrigger")]
    public void Run(
        [QueueTrigger("my-input-queue", Connection = "AzureWebJobsStorage")] string myQueueItem,
        FunctionContext context)
    {
        var logger = context.GetLogger<QueueInputFunction>();
        logger.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
    }
}

JavaScript/TypeScript

const { app } = require("@azure/functions");

app.storage.queue("QueueInputTrigger", {
    queueName: "my-input-queue",
    connection: "AzureWebJobsStorage",
    handler: (queueItem, context) => {
        context.log("JavaScript queue trigger function processed work item");
        context.log(`Received message: ${queueItem}`);
    },
});

Python

import azure.functions as func
import logging

def main(myQueueItem: func.QueueMessage) -> None:
    logging.info('Python queue trigger function processed a queue item.')
    logging.info(f'Dequeued message: {myQueueItem.get_body().decode("utf-8")}')

Common Properties

The following properties are common for both input and output queue bindings:

Property Description Required
name The name of the variable in your function code that represents the queue message. Yes
type Must be queue for output bindings and queueTrigger for input bindings. Yes
direction in for input bindings (trigger), out for output bindings. Yes
queueName The name of the Azure Queue Storage queue. Yes
connection The name of an app setting or environment variable that contains the Azure Queue Storage connection string. Defaults to AzureWebJobsStorage. No (defaults to AzureWebJobsStorage)

Advanced Features

Poison Queue Handling

If a function triggered by a queue message fails multiple times (as determined by the azure-functions-core-tools configuration or Azure platform), the message may be moved to a "poison" queue to prevent it from blocking the main queue indefinitely. You can configure the retry behavior.

Batching

For higher throughput, you can configure queue bindings to process messages in batches. This requires specific configuration in your function.json and code that handles an array of messages.

See Also