# Steps & Workflows
Source: https://www.inngest.com/docs/features/inngest-functions/steps-workflows

import {
  RiGuideFill,
  RiCalendarLine,
  RiGitForkFill,
} from "@remixicon/react";

Steps are fundamental building blocks of Inngest, turning your Inngest Functions into reliable workflows that can runs for months and recover from failures.

<CardGroup cols={1}>
  <Card title="Thinking in Steps" icon={<RiGuideFill className="text-basis h-4 w-4" />} href={'/docs/guides/multi-step-functions'}>
    Discover by example how steps enable more reliable and flexible functions with step-level error handling, conditional steps and waits.
  </Card>
</CardGroup>

Once you are familiar with Steps, start adding new capabilities to your Inngest Functions: 

<CardGroup cols={2}>
  <Card title="Add sleeps" icon={<RiCalendarLine className="text-basis h-4 w-4" />} href={'/docs/features/inngest-functions/steps-workflows/sleeps'}>
    Enable your Inngest Functions to pause by waiting from minutes to months.
  </Card>
  <Card title="Wait for events" icon={<EventIcon className="text-basis h-4 w-4"/>} href={'/docs/features/inngest-functions/steps-workflows/wait-for-event'}>
    Write functions that react to incoming events.
  </Card>
  <Card title="Loop over steps" icon={<RiGuideFill className="text-basis h-4 w-4" />} href={'/docs/guides/working-with-loops'}>
    Iterate over large datasets by looping with steps.
  </Card>
  <Card title="Parallelize steps" icon={<RiGitForkFill className="rotate-90 text-basis h-4 w-4" />} href={'/docs/guides/step-parallelism'}>
    Discover how to apply the map-reduce pattern with Steps.
  </Card>
</CardGroup>

## How steps work

You might wonder: how do Steps work? Why doesn't an Inngest Function get timed out when running on a Serverless environment?

You can think of steps as an API for expressing checkpoints in your workflow, such as waits or work that might benefit from retries or parallelism:

<CodeGroup>
```ts {{ title: "TypeScript" }}
inngest.createFunction(
  { id: "sync-systems" },
  { event: "auto/sync.request" },
  async ({ step }) => {
    // By wrapping code in step.run, the code will be retried if it throws an error and when successfuly.
    // It's result is saved to prevent unnecessary re-execution
    await step.run("get-data", async () => {
      return getDataFromExternalSource();
    });

    // Can also be retried up to 4 times
    await step.run("save-data", async () => {
      return db.syncs.insertOne(data);
    });
  },
);
```
```py {{ title: "Python" }}
@inngest_client.create_function(
    fn_id="sync-systems",
    trigger=inngest.TriggerEvent(event="auto/sync.request"),
)
def sync_systems(ctx: inngest.ContextSync) -> None:
    # By wrapping code in step.run, the code will be retried if it throws an error and when successfuly.
    # It's result is saved to prevent unnecessary re-execution
    data = ctx.step.run("Get data", get_data_from_external_source)

    # Can also be retried up to 4 times
    ctx.step.run("Save data", db.syncs.insert_one, data)
```
```go {{ title: "Go" }}
!snippet:path=snippets/go/docs/functions/sync_systems_function.go
```
</CodeGroup>

Each step execution relies on a communication with Inngest's [Durable Execution Engine](/docs/learn/how-functions-are-executed) which is responsible to:

- Invoking Functions with the correct steps state (current step + previous steps data)
- Gather each step result and schedule the next step to perform

<ImageTheme
  dark={'/assets/docs/features/inngest-functions/steps-workflows/Durable-Execution-Engine-steps-dark.jpg'}
  light={'/assets/docs/features/inngest-functions/steps-workflows/Durable-Execution-Engine-steps-light.jpg'}
  className="my-0"
  alt={'Each Inngest Functions\'s step invocation implies a communication between your application and the Inngest Platform. The illustration shows how each step results in two requests to the deployed application.'}
/>

This architecture powers the durability of Inngest Functions with retriable steps and waits from hours to months. Also, when used in a serverless environment, steps benefit from an extended max duration, enabling workflows that both span over months and run for more than 5 minutes!

Explore the following guide for a step-by-step overview of a complete workflow run:

<CardGroup cols={1}>
  <Card title="How Functions are executed" icon={<RiGuideFill className="text-basis h-4 w-4" />} href={'/docs/learn/how-functions-are-executed'}>
    A deep dive into Inngest's Durable Execution Engine with a step-by-step workflow run example.
  </Card>
</CardGroup>

## SDK References

<CardGroup cols={3}>

  <Card 
    href={"/docs/reference/functions/step-run"}
    title={"TypeScript SDK"}
    icon={<TypeScriptIcon className="text-basis" />}
  >
  Steps API reference
  </Card>

  <Card 
    href={"/docs/reference/python/steps/invoke"}
    title={"Python SDK"}
    icon={<PythonIcon className="text-basis" />}
  >
    Steps API reference
  </Card>

  <Card 
    href={"https://pkg.go.dev/github.com/inngest/inngestgo@v0.9.0/step"}
    title={"Go SDK"}
    icon={<GoIcon className="text-basis" />}
  >
    Steps API reference
  </Card>

</CardGroup>