# gotick docs — how the replay engine works, and how to use it

> Complete gotick documentation: the replay model, every primitive with a working snippet, driving flows from outside, runnable examples, operations and known limits.

Documentation

- [01Install and run](/en/docs.md)
- [02How it works](/en/docs/model.md)
- [03What's underneath](/en/docs/internals.md)
- [04Primitives](/en/docs/primitives.md)
- [05Driving from outside](/en/docs/control.md)
- [06Examples](/en/docs/examples.md)
- [07Running it](/en/docs/operations.md)
- [08Limits](/en/docs/limits.md)

# Install and run

Start here: install it and get a flow running. Then read How it works — the replay model is the one thing you genuinely have to understand. Everything after that is reference you can come back to.

On this page

- [Install](#install)
- [Register a flow, start the scheduler](#write)
- [A process that only starts flows](#client)
- [In tests, without Redis](#test)

gotick is a library, not a service. Nothing to deploy, no schema to migrate, no daemon that has to stay alive. It needs a Redis, and the one you already run will do.

## Install

Go 1.25 or newer. Several projects can share one Redis — give each of them its own queue namespace and they won't see each other.

Copy

```
go get github.com/zbysir/gotick
```

## Register a flow, start the scheduler

NewServerFromConfig gives you a server, Flow registers a definition under an id, and StartServer blocks while driving the scheduler — usually the last line of main, or a goroutine next to your HTTP server. Registering a flow doesn't run it; Trigger does.

Copy

```
tick, err := gotick.NewServerFromConfig(gotick.Config{    RedisURL: "redis://localhost:6379/0",})if err != nil {    log.Fatal(err)} tick.Flow("order/close", func(ctx *gotick.Context) {    gotick.Task(ctx, "create-order", createOrder)    gotick.Sleep(ctx, "wait-payment", 30*time.Minute)    gotick.Task(ctx, "close-order", closeOrder)}) callId, err := tick.Trigger(ctx, "order/close", gotick.MetaData{    "order_id": "ORD-1",}) log.Fatal(tick.StartServer(ctx))
```

## A process that only starts flows

An HTTP handler that kicks off a flow doesn't need to execute one. NewClient gives you Trigger and nothing else. It reaches the workers through Redis — the two processes never connect directly, and they deploy independently.

Copy

```
client, err := gotick.NewClient(gotick.NewClientConfig{    RedisURL: "redis://localhost:6379/0",})if err != nil {    log.Fatal(err)} // 0 = start nowcallId, err := client.Trigger(ctx, "order/close", meta, 0)
```

## In tests, without Redis

There are in-memory implementations of both the queue and the store, so a unit test runs a real flow — real scheduling, real replay, real retries — inside the test process. Every test in the repo works this way.

Copy

```
tick := gotick.NewServer(gotick.NewServerParams{    DelayedQueue: store.NewMockRedisDelayedQueue(),    KVStore:      store.NewMockKvStore(),})
```

[Next →\
\
How it works](/en/docs/model.md)

On this page

- [Install](#install)
- [Register a flow, start the scheduler](#write)
- [A process that only starts flows](#client)
- [In tests, without Redis](#test)

> Full page index: [/llms.txt](/llms.txt)
