Edit

Azure Functions Go developer reference

Azure Functions is a serverless compute service that you can use to run event-driven code without provisioning or managing infrastructure. The Go worker enables you to write Azure Functions natively in Go, with deep integration into the Azure Functions trigger ecosystem.

This guide helps you:

  • Understand the Go programming model
  • Create and structure your project code
  • Work with triggers
  • Deploy and run your app locally and in Azure

To learn more Azure Functions development in general, see the Azure Functions developer reference.

Getting started

Choose the environment that fits your workflow and get started with Azure Functions for Go:

Prerequisites

  • Go 1.24 or later
  • Azure Functions Core Tools version 4.12 or later. Run func --version to verify your installed version.
  • Azure CLI version 2.87.0 or later, when you create Azure resources or deploy packages to Azure. Run az version to verify your installed version.

Programming model

The Go worker uses a code-first programming model. You define serverless functions and their triggers by using idiomatic Go handlers.

Entry point

Every Go code project starts with a main() function that creates a FunctionApp, registers functions, and starts the worker:

package main

import (
    "fmt"
    "net/http"

    "github.com/azure/azure-functions-golang-worker/sdk"
    "github.com/azure/azure-functions-golang-worker/worker"
)

func main() {
    app := sdk.FunctionApp()

    app.HTTP("hello", hello,
        sdk.WithMethods("GET", "POST"),
        sdk.WithAuth("anonymous"),
    )

    worker.Start(app)
}

func hello(w http.ResponseWriter, r *http.Request) {
    name := r.URL.Query().Get("name")
    if name == "" {
        name = "world"
    }
    fmt.Fprintf(w, "Hello, %s!", name)
}

Function registration

Register functions by using the fluent builder API with the functional options pattern. Each trigger type has a registration method on the App object:

// HTTP trigger
app.HTTP("myHttpFunc", handler,
    sdk.WithMethods("GET", "POST"),
    sdk.WithAuth("anonymous"),
)

// Timer trigger
app.Timer("myTimerFunc", handler,
    sdk.WithSchedule("0 */5 * * * *"),
)

// Azure Cosmos DB trigger
app.CosmosDB("myCosmosFunc", handler,
    sdk.WithDatabase("mydb"),
    sdk.WithContainer("mycontainer"),
    sdk.WithConnection("CosmosDBConnection"),
)

// Azure Queue Storage trigger
app.Queue("myQueueFunc", handler,
    sdk.WithQueueName("myqueue"),
    sdk.WithConnection("AzureWebJobsStorage"),
)

// Azure Service Bus trigger
app.ServiceBusQueue("myServiceBusFunc", handler,
    sdk.WithQueueName("myqueue"),
    sdk.WithConnection("ServiceBusConnection"),
)

// Azure SQL trigger
app.SQL("mySqlFunc", handler,
    sdk.WithTable("dbo.Products"),
    sdk.WithConnection("SqlConnectionString"),
)

// Event Hubs trigger
app.EventHub("myEventHubFunc", handler,
    sdk.WithEventHubName("myeventhub"),
    sdk.WithConnection("EventHubConnection"),
)

// Event Grid trigger
app.EventGrid("myEventGridFunc", handler)

// Blob trigger (extension model)
app.Blob("myBlobFunc", handler,
    sdk.WithPath("mycontainer/{name}"),
    sdk.WithConnection("AzureWebJobsStorage"),
)

Project structure

A Go code project for Azure Functions is a standard Go module. When you run func init --worker-runtime go, the following files are generated:

my-function-app/
├── host.json              # Host configuration
├── local.settings.json    # Local settings (connection strings, app settings)
├── go.mod                 # Go module file
├── go.sum                 # Go module checksums
└── main.go                # Entry point with function registrations

host.json

The host.json file contains host-level configuration options. For more information, see the host.json reference.

local.settings.json

The local.settings.json file stores app settings and connection strings used during local development. This file isn't published to Azure. For more information, see Local settings file.

Triggers

The Go worker provides dedicated registration methods for supported triggers.

Typed trigger payloads

Most supported triggers receive their payload inline through gRPC. The Azure Functions host serializes the trigger data into the gRPC message, and the worker deserializes it into typed Go values. These triggers have:

  • Typed handler signatures with compile-time safety
  • No external Azure SDK dependencies: only encoding/json is needed
  • Bounded payloads: change-feed documents, messages, and events are discrete, size-limited objects

Supported triggers:

Trigger Handler signature Registration method
HTTP func(http.ResponseWriter, *http.Request) app.HTTP()
Timer TimerHandler app.Timer()
Azure Queue Storage QueueHandler app.Queue()
Azure Cosmos DB func(context.Context, []bindings.CosmosDocument) error app.CosmosDB()
Azure Service Bus (Queue) ServiceBusHandler app.ServiceBusQueue()
Azure Service Bus (Topic) ServiceBusHandler app.ServiceBusTopic()
Event Hubs EventHubHandler app.EventHub()
Event Grid EventGridHandler app.EventGrid()
Azure SQL func(context.Context, []bindings.SQLChange) error app.SQL()

Event Hubs and Service Bus also support strongly typed batch handlers through app.EventHubBatch(), app.ServiceBusQueueBatch(), and app.ServiceBusTopicBatch().

SDK type bindings

SDK type bindings provide an authenticated Azure SDK client instead of serialized trigger data. For Go, Blob Storage triggers support SDK type bindings. The host sends metadata, such as the container name and blob path, and the worker constructs a client scoped to the specific resource. SDK type bindings provide:

  • SDK client injection: the handler receives a ready-to-use client
  • Isolated dependencies: Azure SDK packages live in triggers/<name>/
  • Streaming support: enables reading large payloads without buffering through gRPC

To use the Blob Storage SDK type binding, add a blank import for the Blob trigger package:

import _ "github.com/azure/azure-functions-golang-worker/triggers/blob"
Trigger Handler receives Registration method
Blob Storage *blob.Client app.Blob()

Blob trigger example

package main

import (
    "context"
    "fmt"
    "io"
    "log"

    "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
    "github.com/azure/azure-functions-golang-worker/sdk"
    _ "github.com/azure/azure-functions-golang-worker/triggers/blob"
    "github.com/azure/azure-functions-golang-worker/worker"
)

func main() {
    app := sdk.FunctionApp()
    app.Blob("processBlobTrigger", processBlob,
        sdk.WithPath("samples-workitems/{name}"),
        sdk.WithConnection("AzureWebJobsStorage"),
    )
    worker.Start(app)
}

func processBlob(ctx context.Context, client *blob.Client) error {
    get, err := client.DownloadStream(ctx, nil)
    if err != nil {
        return fmt.Errorf("download error: %w", err)
    }
    data, _ := io.ReadAll(get.Body)
    get.Body.Close()
    log.Printf("Blob size: %d bytes", len(data))
    return nil
}

Generic host triggers

Use app.GenericTrigger() when a compatible host extension provides a trigger that doesn't have a dedicated Go registration method. Generic triggers support raw text, byte slices, and JSON-compatible Go types:

app.GenericTrigger("echoTool", echoTool, &bindings.GenericTrigger{
    Type:     "mcpToolTrigger",
    Name:     "call",
    DataType: "string",
    Properties: map[string]any{
        "toolName":       "echo",
        "description":    "Echo text using a generic Go trigger",
        "toolProperties": `[{"propertyName":"text","propertyType":"string","description":"Text to echo","isRequired":true}]`,
    },
})

The compatible host extension must be installed. Generic trigger registration doesn't provide HTTP handling, SDK client injection, Durable Functions replay, or service-specific message settlement. For complete examples, see the generic triggers sample.

HTTP triggers

HTTP trigger handlers use standard Go net/http types, making them immediately familiar to Go developers:

func myHandler(w http.ResponseWriter, r *http.Request) {
    name := r.URL.Query().Get("name")
    if name == "" {
        name = "world"
    }
    w.Header().Set("Content-Type", "application/json")
    fmt.Fprintf(w, `{"message": "Hello, %s!"}`, name)
}

Register HTTP functions with methods and authorization level:

app.HTTP("myApi", myHandler,
    sdk.WithMethods("GET", "POST"),
    sdk.WithAuth("anonymous"),
)

HTTP streaming

The Go worker supports HTTP streaming for scenarios like server-sent events or sending large response data:

func streamHandler(w http.ResponseWriter, r *http.Request) {
    flusher, ok := w.(http.Flusher)
    if !ok {
        http.Error(w, "streaming not supported", http.StatusInternalServerError)
        return
    }

    w.Header().Set("Content-Type", "text/event-stream")
    for i := 0; i < 10; i++ {
        fmt.Fprintf(w, "data: message %d\n\n", i)
        flusher.Flush()
    }
}

Timer trigger

Timer triggers run on a schedule defined by a cron expression:

app.Timer("myScheduledFunc", timerHandler,
    sdk.WithSchedule("0 */5 * * * *"),
)

func timerHandler(ctx context.Context, timer bindings.TimerInfo) error {
    log.Printf("Timer trigger executed at: %s", timer.ScheduleStatus.Next)
    return nil
}

Durable Functions

Go supports Durable Functions orchestrations and activities through the middleware/durabletask package. Register your orchestrators and activities with the Durable middleware before adding the middleware to the function app:

durable := durabletask.Middleware()
durable.Orchestrator("HelloCities", helloCities)
durable.Activity("SayHello", sayHello)
app.Use(durable)

Durable Functions for Go requires the Durable Task extension version 3.15.0 or later. Entities aren't currently supported. For a complete application, see the Durable Functions sample.

Dependency management

Go code projects use standard Go modules for dependency management.

  1. Initialize a new module:

    go mod init myapp
    
  2. Add the Azure Functions Go worker SDK:

    go get github.com/azure/azure-functions-golang-worker
    

    For blob trigger support, the dependency is included automatically via the blank import of triggers/blob.

  3. Tidy dependencies:

    go mod tidy
    

Run local

Use Azure Functions Core Tools to run your project locally:

func start

Core Tools automatically:

  1. Detects FUNCTIONS_WORKER_RUNTIME = "native" from local.settings.json.
  2. Resolves the native worker runtime to Go when a go.mod file is present.
  3. Runs go build -o bin/app . to compile your project for your local operating system.
  4. Starts the Azure Functions host, which communicates with the compiled binary over gRPC.
  5. Displays your function endpoints (for example, http://localhost:7071/api/hello).

Use local.settings.json to configure environment variables for local development:

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "",
        "FUNCTIONS_WORKER_RUNTIME": "native"
    }
}

The generated AzureWebJobsStorage value is empty for Go projects. Set it to a storage account connection string or UseDevelopmentStorage=true when you use triggers that require host storage during local development.

Deployment

Compilation and packaging

Azure Functions Core Tools version 4.12 or later handles Go builds for the common local and Azure deployment flows:

  • func start builds your project as bin/app for your local operating system before starting the local Functions host.
  • func azure functionapp publish builds, packages, and deploys your project to an existing function app in Azure.
  • func pack builds your project as bin/app for Linux x64 and creates a deployable .zip package.

When packaging for Azure, the generated .zip file contains the files needed by the Linux Functions host. The compiled binary is stored as bin/app in your local project, but Core Tools places it at the root of the deployment package as app.

If you use func pack --no-build, you must build the Linux x64 binary before packaging:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/app .

Deploy with Core Tools

Use func azure functionapp publish to deploy your Go project to an existing function app in Azure:

func azure functionapp publish <APP_NAME>

Replace <APP_NAME> with the name of your function app.

Deploy a zip package

Use func pack when you need to create a deployment package separately from publishing:

  1. Create a deployable zip artifact:

    func pack
    
  2. Deploy the package by using the Azure CLI:

    az functionapp deployment source config-zip --resource-group <RESOURCE_GROUP> --name <APP_NAME> --src <ZIP_FILE_PATH>
    

The package produced by func pack is ready to run in Azure, so don't request a remote build when you deploy it.

Docker support

You can run Go code projects in containers. Initialize a project with Docker support:

func init --worker-runtime go --docker

The command generates a Dockerfile along with the standard project files.

Telemetry and observability

The Azure Functions Go worker supports structured logging and OpenTelemetry-based observability. Use context-aware methods from the standard log/slog package, such as slog.InfoContext, to correlate logs with the current function invocation. To enable OpenTelemetry, configure the Functions host and register the Go worker OpenTelemetry middleware in your app. For setup instructions, see Use OpenTelemetry with Azure Functions.

Known limitations

  • func new isn't supported. Add functions by editing main.go directly.
  • Go function apps run on Linux in the Flex Consumption plan only.
  • Only the dedicated triggers listed in Triggers and compatible generic host triggers are supported.
  • Additional input bindings and non-HTTP output bindings aren't currently supported.
  • Go packaging in Core Tools currently targets Linux x64 apps.

Next steps