Blog Post

Apps on Azure Blog
5 MIN READ

Announcing Go support in Azure Functions (Preview)

AnthonyChu's avatar
AnthonyChu
Icon for Microsoft rankMicrosoft
Jun 02, 2026

Write Azure Functions in Go using a first-class serverless programming model

We're excited to announce that Azure Functions now supports Go as a first-class language, available today in public preview on the Flex Consumption plan. Go developers can now build event-driven, serverless applications using idiomatic Go, the standard toolchain they already love, and the full breadth of Azure Functions triggers, bindings, and operational capabilities.

TL;DR: Write Functions in Go using a new code-first programming model and SDK (azure-functions-golang-worker). Use triggers across HTTP, Timer, Service Bus, Event Hubs, Event Grid, Cosmos DB, and Blob Storage.

Why Go on Azure Functions

Go has become a default choice for cloud-native APIs, platform services, networking tools, and high-throughput integration workloads. Until now, teams that standardized on Go on Azure had to either:

  • Use Azure Functions through the custom handlers protocol, missing out on a first-class developer experience, or
  • Build and operate their own serving, scaling, and eventing infrastructure on containers or VMs.

With first-class Go support, those teams get the productivity of Go plus the operational leverage of serverless: automatic scaling, pay-per-use billing, integrated triggers across the Azure ecosystem, and built-in observability, without leaving the Go ecosystem.

What's in the preview

  • A new Go programming model and SDK: a code-first, idiomatic way to register Functions and declare triggers using functional options.
  • Support for popular triggers: HTTP, Timer, Service Bus (queues and topics), Event Hubs, Event Grid, Cosmos DB, and Blob Storage. More to come.
  • Native Go build pipeline: go build produces a single static binary that the Functions host invokes directly. No function.json, no interop shims at request time.
  • Integrated observability: Application Insights logging, metrics, and distributed tracing.
  • End-to-end tooling: local development with a preview build of Azure Functions Core Tools. Deployment via Core Tools, zip deploy, or GitHub Actions.
  • Flex Consumption: fast elastic scale, scale-to-zero, per-second billing, VNet integration, and always-ready instances.

A quick look at the programming model

The Go model is code-first: you register functions and declare triggers in Go, with compile-time checks and full IDE support. No separate JSON metadata to keep in sync.

Here's a minimal HTTP-triggered Function:

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)
}

Notice the HTTP handler is a plain http.HandlerFunc, the same signature you'd use with net/http or any Go web framework. There's nothing Functions-specific to learn at the handler level.

Registering other triggers

The same pattern works across triggers. Non-HTTP handlers take a context.Context plus a typed payload:

import (
    "context"
    "log"

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

// Timer: runs every 10 seconds
func onTimer(ctx context.Context, t bindings.TimerInfo) error {
    log.Printf("timer fired; past due=%v", t.IsPastDue)
    return nil
}
app.Timer("cleanup", onTimer,
    sdk.WithSchedule("*/10 * * * * *"),
)

// Service Bus queue
func onOrder(ctx context.Context, msg bindings.ServiceBusMessage) error {
    log.Printf("order %s: %s", msg.MessageId, string(msg.Body))
    return nil
}
app.ServiceBusQueue("processOrder", onOrder,
    sdk.WithQueueName("orders"),
    sdk.WithConnection("ServiceBusConnection"),
)

// Event Hubs
func onEvent(ctx context.Context, e bindings.EventHubMessage) error {
    log.Printf("event seq=%d body=%s", e.SequenceNumber, string(e.Body))
    return nil
}
app.EventHub("ingest", onEvent,
    sdk.WithEventHubName("telemetry"),
    sdk.WithConnection("EventHubConnection"),
)

// Cosmos DB change feed
func onChange(ctx context.Context, docs []bindings.CosmosDocument) error {
    for _, d := range docs {
        log.Printf("doc %s: %s", d.ID, string(d.Data))
    }
    return nil
}
app.CosmosDB("onChange", onChange,
    sdk.WithDatabase("ToDoList"),
    sdk.WithContainer("Items"),
    sdk.WithConnection("CosmosDBConnection"),
)

// Event Grid
func onGridEvent(ctx context.Context, e bindings.EventGridEvent) error {
    log.Printf("%s: %s", e.EventType, e.Subject)
    return nil
}
app.EventGrid("onEvent", onGridEvent)

Extension triggers: real Azure SDK clients

For triggers like Blob Storage, the Go SDK injects a fully-typed Azure SDK client directly into your handler. You opt in with a blank import, so your binary only includes the extensions you actually use:

import (
    "context"
    "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" // registers blob trigger client factory
    "github.com/azure/azure-functions-golang-worker/worker"
)

func onUpload(ctx context.Context, client *blob.Client) error {
    log.Printf("blob: %s", client.URL())
    resp, err := client.DownloadStream(ctx, nil)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    data, err := io.ReadAll(resp.Body)
    if err != nil {
        return err
    }
    log.Printf("size=%d", len(data))
    return nil
}

app.Blob("onUpload", onUpload,
    sdk.WithPath("uploads/{name}"),
    sdk.WithConnection("AzureWebJobsStorage"),
    sdk.WithSource("EventGrid"),
)

The handler receives a *blob.Client from github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob, the same client you'd use in any other Go app. Because it's a real SDK client, you can DownloadStream blobs of any size without buffering the whole payload through the worker. Dependencies stay isolated per extension, so apps that don't use Blob never pull in azblob or azidentity.

Project layout

A Go function app is just a regular Go module plus the standard Functions config files:

my-function-app/
├── host.json
├── local.settings.json
├── go.mod
├── go.sum
└── main.go

No function.json and no generated metadata. Triggers are declared in main.go. go build, go test, and go mod tidy all just work.

Get started

  • Quickstart Install the preview tooling, scaffold your first Go function app, run it locally, and deploy to Flex Consumption.

We can't wait to see what you build. Welcome to Functions, Gophers.

Updated Jun 02, 2026
Version 1.0
No CommentsBe the first to comment