Every journey begins with a Flow. A flow is your workflow's container — it holds all the tasks you want to execute and defines how they work together. Think of it as a recipe: it lists the ingredients (tasks) and the steps to follow (orchestration logic).

Before we dive in, there's one important concept: Namespaces. Every flow lives inside a namespace — think of it as a folder for organizing your workflows. Like folders on your computer, namespaces group related flows and can be nested (e.g. company.team.project).

Every flow needs three essential components:

  1. ID — a unique identifier for your flow

  2. Namespace — an organizational grouping

  3. Tasks — the actual work to be performed

One important note: once you save a flow, its ID and namespace are permanent and cannot be changed. This ensures consistency and prevents breaking dependencies.

When you create a new flow in Kestra, you'll see a starter template that looks like this:

The Flow Code is written in YAML:

id: myflow
namespace: company.team

tasks:
  - id: hello
    type: io.kestra.plugin.core.log.Log
    message: Hello World! 🚀

We can execute this flow and see the result:

This simple example shows the basic structure: an ID, a namespace, and a single task that logs a message. But a flow with just one logging task doesn't do much. Let's add more capability.