Cloud Tasks

gRPC · port 8089

Configuration

No env var. Cloud Tasks has no official *_EMULATOR_HOST environment variable. You must configure the endpoint manually in your client code.

Go SDK example

Create a queue, create a task with an HTTP target, and list tasks:

package main

import (
    "context"
    "fmt"
    "log"

    cloudtasks "cloud.google.com/go/cloudtasks/apiv2"
    taskspb "cloud.google.com/go/cloudtasks/apiv2/cloudtaskspb"
    "google.golang.org/api/option"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    "google.golang.org/protobuf/types/known/timestamppb"
    "time"
)

func main() {
    ctx := context.Background()

    // Connect to localgcp (no TLS, no auth)
    client, err := cloudtasks.NewClient(ctx,
        option.WithEndpoint("localhost:8089"),
        option.WithoutAuthentication(),
        option.WithGRPCDialOption(grpc.WithTransportCredentials(
            insecure.NewCredentials(),
        )),
    )
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    parent := "projects/my-project/locations/us-central1"

    // Create a queue
    queue, err := client.CreateQueue(ctx, &taskspb.CreateQueueRequest{
        Parent: parent,
        Queue: &taskspb.Queue{
            Name: parent + "/queues/my-queue",
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    // Create a task with an HTTP target
    task, err := client.CreateTask(ctx, &taskspb.CreateTaskRequest{
        Parent: queue.Name,
        Task: &taskspb.Task{
            MessageType: &taskspb.Task_HttpRequest{
                HttpRequest: &taskspb.HttpRequest{
                    Url:        "http://localhost:9000/process",
                    HttpMethod: taskspb.HttpMethod_POST,
                    Body:       []byte(`{"order_id": "12345"}`),
                    Headers:    map[string]string{"Content-Type": "application/json"},
                },
            },
            // Optional: schedule for later
            ScheduleTime: timestamppb.New(time.Now().Add(30 * time.Second)),
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Created task: %s\n", task.Name)
}

Features

HTTP dispatch

When a task's scheduled time arrives, localgcp dispatches an HTTP request to the configured URL. Start a local HTTP server to receive tasks:

// Simple task handler
http.HandleFunc("/process", func(w http.ResponseWriter, r *http.Request) {
    body, _ := io.ReadAll(r.Body)
    fmt.Printf("Task received: %s\n", body)
    w.WriteHeader(http.StatusOK)
})
http.ListenAndServe(":9000", nil)

If the handler returns a non-2xx status, localgcp retries according to the queue's retry configuration.

Retry configuration

Configure retry behavior when creating a queue:

queue, err := client.CreateQueue(ctx, &taskspb.CreateQueueRequest{
    Parent: parent,
    Queue: &taskspb.Queue{
        Name: parent + "/queues/retry-queue",
        RetryConfig: &taskspb.RetryConfig{
            MaxAttempts: 5,
            MinBackoff:  durationpb.New(1 * time.Second),
            MaxBackoff:  durationpb.New(60 * time.Second),
        },
    },
})

Tasks that fail will be retried with exponential backoff between MinBackoff and MaxBackoff, up to MaxAttempts total attempts.

Scheduling

Delay task execution by setting ScheduleTime:

// Execute 5 minutes from now
task, err := client.CreateTask(ctx, &taskspb.CreateTaskRequest{
    Parent: queue.Name,
    Task: &taskspb.Task{
        MessageType: &taskspb.Task_HttpRequest{
            HttpRequest: &taskspb.HttpRequest{
                Url:        "http://localhost:9000/delayed-job",
                HttpMethod: taskspb.HttpMethod_POST,
            },
        },
        ScheduleTime: timestamppb.New(time.Now().Add(5 * time.Minute)),
    },
})

localgcp holds the task until the scheduled time, then dispatches the HTTP request.

Not yet supported