# Delayed Functions
Source: https://www.inngest.com/docs/guides/delayed-functions

You can easily enqueue jobs in the future with Inngest. Inngest offers two ways to run jobs in the future: delaying jobs for a specific amount of time (up to a year, and for free plan up to seven days), or running code at a specific date and time. There are some benefits to enqueuing jobs using Inngest:

- It works across any provider or platform
- Delaying jobs is durable, and works across server restarts, serverless functions, and redeploys
- You can enqueue jobs into the far future
- Serverless functions are fully supported on all platforms
- Our SDK bypasses serverless function timeouts on all platforms
- You never need to manage queues or backlogs

### Platform support

**This works across all providers and platforms**, whether you run serverless functions or use servers like express.  **It also bypasses serverless function timeouts** on all platforms, so you can sleep for a longer time than your provider supports.

## Delaying jobs

<GuideSelector
  options={[
    { key: "typescript", title: "TypeScript" },
    { key: "go", title: "Go" },
    { key: "python", title: "Python" },
  ]}>

<GuideSection show="typescript">

You can delay jobs using the [`step.sleep()`](/docs/reference/functions/step-sleep) method:

```ts
new Inngest({ id: "signup-flow" });

fn = inngest.createFunction(
  { id: "send-signup-email" },
  { event: "app/user.created" },
  async ({ event, step }) => {
    await step.sleep("wait-a-moment", "1 hour");
    await step.run("do-some-work-in-the-future", async () => {
      // This runs after 1 hour
    });
  }
);
```

For more information on `step.sleep()` read [the reference](/docs/reference/functions/step-sleep).

## Running at specific times

You can run jobs at a specific time using the [`step.sleepUntil()`](/docs/reference/functions/step-sleep-until) method:

```ts
new Inngest({ id: "signup-flow" });

fn = inngest.createFunction(
  { id: "send-signup-email" },
  { event: "app/user.created" },
  async ({ event, step }) => {
    await step.sleepUntil("wait-for-iso-string", "2023-04-01T12:30:00");

    // You can also sleep until a timestamp within the event data.  This lets you
    // pass in a time for you to run the job:
    await step.sleepUntil("wait-for-timestamp", event.data.run_at); // Assuming event.data.run_at is a timestamp.

    await step.run("do-some-work-in-the-future", async () => {
      // This runs at the specified time.
    });
  }
);
```

For more information on `step.sleepUntil()` [read the reference](/docs/reference/functions/step-sleep-until).

</GuideSection>
<GuideSection show="go">

You can delay jobs using the [`step.Sleep()`](https://pkg.go.dev/github.com/inngest/inngestgo@v0.7.4/step#Sleep) method:

```go
!snippet:path=snippets/go/docs/functions/delayed_function.go
```

For more information on `step.sleep()` read [the reference](https://pkg.go.dev/github.com/inngest/inngestgo@v0.7.4/step#Sleep).

</GuideSection>
<GuideSection show="python">

You can delay jobs using the [`step.sleep()`](http://localhost:3001/docs/reference/python/steps/sleep) method:

```python
import inngest
from src.inngest.client import inngest_client
from datetime import timedelta

@inngest_client.create_function(
    fn_id="send-signup-email", 
    trigger=inngest.TriggerEvent(event="app/user.created")
)
async def send_signup_email(ctx: inngest.Context):
    
    await ctx.step.sleep("wait-for-the-future", timedelta(hours=4))

    async def future_work():
        # Code here runs in the future automatically
        pass

    await ctx.step.run("do-some-work-in-the-future", future_work)
```

For more information on `step.sleep()` read [the reference](/docs/reference/functions/step-sleep).

## Running at specific times

You can run jobs at a specific time using the [`step.sleep_until()`](/docs/reference/python/steps/sleep-until) method:

```python
import inngest
from src.inngest.client import inngest_client

inngest_client = inngest.Inngest(
    app_id="my-app",
)

@inngest_client.create_function(
    fn_id="send-signup-email", 
    trigger=inngest.TriggerEvent(event="app/user.created")
)
async def send_signup_email(ctx: inngest.Context):
    async def send_email():
        await sesclient.send_email(
            to=ctx.event.data["user_email"],
            subject="Welcome to Inngest!",
            message="..."
        )
    
    await ctx.step.run("send-the-user-a-signup-email", send_email)
    
    await ctx.step.sleep_until("wait-for-the-future", "2023-02-01T16:30:00")

    async def future_work():
        # Code here runs in the future automatically
        pass

    await ctx.step.run("do-some-work-in-the-future", future_work)
```

For more information on `step.sleep_until()` [read the reference](/docs/reference/python/steps/sleep-until).

</GuideSection>

</GuideSelector>

## How it works

{/* TODO - Revisit this section after we write a How Inngest Works explainer */}

In both methods, **the function controls when it runs**.  You control the flow of your code by calling `sleep` or `sleepUntil` within your function directly,
instead of using the queue to manage your code's timing.  This keeps your logic together and makes your code easier to modify.

Inngest *stops the function from running* for whatever time is specified.  When you call `step.sleep` or `step.sleepUntil` the function automatically stops running any future work. The function then tells the Inngest executor that it should be re-invoked at a future time.  We re-call the function at the next step, skipping any previous work.  This is how we bypass serverless function time limits and work across server restarts or redeploys.