Skip to content

Workflows in Go.
Built to keep going.

Durable workflows and background jobs for Go. Runs in your process. Built on Postgres.

Postgres 14+Go 1.26.3+

triage.goGo
retrieve := cyclone.NewStep("retrieve",
    func(ctx cyclone.Context, ticket Ticket) (Facts, error) {
        return loadFacts(ctx, ticket.ID)
    })

triage := cyclone.Define("triage",
    func(b *cyclone.Builder, ticket Ticket) error {
        // answer waits on retrieve.
        // send waits on the draft.
        facts := cyclone.Do(b, retrieve, cyclone.Lit(ticket))
        draft := cyclone.Do(b, answer, cyclone.From(facts))
        cyclone.Run(b, send, cyclone.From(draft))
        return nil
    })

// Records the run. Each step is claimed
// when its input is ready.
runID, err := cyclone.Submit(ctx, client, triage, ticket)
if err != nil {
    return "", err
}

Core features

Typed workflow graphs

Go types connect steps through fan-out and fan-in.

Transactional enqueue

A job commits with the application data that created it.

Durable waits

Pause for a signal or timer without holding a worker.

Atomic step writes

Postgres writes commit with step completion.

CYCLONE UI

See what is running.

Inspect runs and steps, retry or cancel work, and check queues and schedules from the browser. No SQL or CLI needed.

Cyclone UI dashboard showing run counts and an outcomes chart