> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xano.com/llms.txt
> Use this file to discover all available pages before exploring further.

# XanoScript for Background Tasks

> Define Background Tasks in XanoScript to run logic on a schedule

export const xanoscriptApiInputsDiagram = `
\`\`\`mermaid
flowchart TB
    A[Declaration] --> B[Input]
    B --> C[Stack]
    C --> D[Response]
    D --> E[Settings]
    style A fill:#cdeaff,stroke:#0077cc,stroke-width:2px
    style B fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    style C fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    style D fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    style E fill:#f5f5f5,stroke:#ccc,stroke-width:1px
\`\`\`
`;

export function SideBySide({diagram, children}) {
  return <div style={{
    display: "flex",
    gap: "1rem",
    alignItems: "flex-start",
    flexWrap: "wrap"
  }}>
      <div style={{
    flex: "0 0 180px",
    minWidth: "150px"
  }}>
        <div>{mdx(diagram)}</div>
      </div>
      <div style={{
    flex: 1
  }}>
        {children}
      </div>
    </div>;
}

export const HoverImageCode = ({src, alt = "", width = "100%", maxWidth = "800px", className = "", defaultOpen = false, openOnHover = true, children}) => {
  const [open, setOpen] = useState(defaultOpen);
  const panelRef = useRef(null);
  const [maxHeight, setMaxHeight] = useState(0);
  useEffect(() => {
    if (panelRef.current) {
      setMaxHeight(open ? panelRef.current.scrollHeight : 0);
    }
  }, [open, children]);
  const handleMouseEnter = () => openOnHover && setOpen(true);
  const handleMouseLeave = () => openOnHover && setOpen(false);
  const handleClick = () => setOpen(s => !s);
  const handleImageClick = e => {
    e.stopPropagation();
    e.preventDefault();
    handleClick();
  };
  const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  const transition = prefersReducedMotion ? "none" : "max-height 300ms ease, opacity 300ms ease, transform 300ms ease";
  return <div className={`border rounded-md overflow-hidden ${className}`} style={{
    width,
    maxWidth
  }} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
      {}
      <div role="button" tabIndex={0} aria-label="Toggle code" aria-expanded={open} style={{
    cursor: "pointer"
  }}>
        <img src={src} alt={alt} onClickCapture={e => {
    e.stopPropagation();
    e.preventDefault();
    handleClick();
  }} style={{
    display: "block",
    width: "100%",
    height: "auto"
  }} />
      </div>

      {}
      <div className="not-prose" ref={panelRef} style={{
    overflow: "hidden",
    maxHeight: `${maxHeight}px`,
    opacity: open ? 1 : 0,
    transform: open ? "translateY(0)" : "translateY(-6px)",
    transition
  }}>
        <div style={{
    padding: "0.75rem"
  }}>{children}</div>
      </div>
    </div>;
};

## Introduction

Background tasks are scheduled workflows that run in the background, independently of any API request or other logic.

They’re ideal for recurring operations like data cleanup, notifications, or re-engagement campaigns.

Unlike APIs and custom functions, background tasks do not accept inputs or return a response. They are only used to run logic on a schedule.

***

## Anatomy

Every XanoScript background task follows a predictable structure.

Here’s a quick visual overview of its main building blocks — from **declaration** at the top to **settings** at the bottom.<br /><br />You can find more detail about each section by continuing below.

```java XanoScript lines icon="code" theme={null}
// Looks at the user table for users that haven't logged in for the last 30 days or more, and sends them an email trying to reengage them with the platform.
task reengage_users {
  stack {
    db.query user {
      search = $db.user.last_login <= ("now"|timestamp_subtract_months:1)
      return = {type: "list"}
    } as $user1
  
    foreach ($user1) {
      each as $item {
        util.send_email {
          api_key = "abc123"
          service_provider = "resend"
          subject = "Hey, where'd you go?"
          message = "We noticed you haven't logged in for a while. Come back and give us another shot?"
          to = $item.email
          bcc = []
          cc = []
          from = "admin@myapp.com"
          reply_to = ""
          scheduled_at = ""
        } as $x1
      }
    }
  }

  schedule = [{starts_on: 2025-10-01 06:00:00+0000, freq: 604800}]
  tags = ["user actions", "retention"]
}
```

### Declaration

Every Background Task starts with a **declarative header** that specifies its type, name, and HTTP verb.

<div style={{ display: "flex", gap: "1rem", alignItems: "flex-start", flexWrap: "wrap" }}>
  <div style={{ flex: "0 0 180px", minWidth: "150px" }}>
    <div>
      ```mermaid theme={null}
      flowchart TB
      A[Declaration] --> B[Logic] --> C[Schedule] --> D[Settings]
      style A fill:#cdeaff,stroke:#0077cc,stroke-width:2px
      style B fill:#f5f5f5,stroke:#ccc,stroke-width:1px
      style C fill:#f5f5f5,stroke:#ccc,stroke-width:1px
      style D fill:#f5f5f5,stroke:#ccc,stroke-width:1px
      ```
    </div>
  </div>

  <div style={{ flex: 1 }}>
    ```java XanoScript lines icon="code" theme={null}
    // Looks at the user table for users that haven't logged in for the last 30 days or more, and sends them an email trying to reengage them with the platform.
    task reengage_users {
      active = false
      datasource = "test"
    }
    ```

    | Element       | Required | Description                                                                     |
    | ------------- | -------- | ------------------------------------------------------------------------------- |
    | `task`        | ✅        | Declares an Background Task primitive.                                          |
    | `task_name`   | ✅        | The unique name for the task (e.g., `reengage_users`).                          |
    | `description` | no       | A short summary of the task. May also appear as a “//” comment above the block. |
    | `active`      | no       | Whether the task is active.                                                     |
    | `datasource`  | no       | Specifies the datasource to use for this Background Task.                       |
  </div>
</div>

***

### Section 1: Stack

The `stack` block contains the actual logic that will be executed when the Background Task is running.

<div style={{ display: "flex", gap: "1rem", alignItems: "flex-start", flexWrap: "wrap" }}>
  <div className="stickyDiagram">
    ```mermaid theme={null}
    flowchart TB
    A[Declaration] --> B[Logic] --> C[Schedule] --> D[Settings]
    style B fill:#cdeaff,stroke:#0077cc,stroke-width:2px
    style A fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    style C fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    style D fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    ```
  </div>

  <div style={{ flex: 1 }}>
    <Frame caption="Hover over this image to see the XanoScript version">
      <HoverImageCode src="/images/background-tasks-20251003-152455.png" alt="An image of the inputs section">
        ```java XanoScript lines icon="code" theme={null}
          stack {
            db.query user {
              search = $db.user.last_login <= ("now"|timestamp_subtract_months:1)
              return = {type: "list"}
            } as $user1
          
            foreach ($user1) {
              each as $item {
                util.send_email {
                  api_key = "abc123"
                  service_provider = "resend"
                  subject = "Hey, where'd you go?"
                  message = "We noticed you haven't logged in for a while. Come back and give us another shot?"
                  to = $item.email
                  bcc = []
                  cc = []
                  from = "admin@myapp.com"
                  reply_to = ""
                  scheduled_at = ""
                } as $x1
              }
            }
          }
        ```
      </HoverImageCode>
    </Frame>

    The syntax mirrors how you'd configure these functions visually, but expressed textually. The actual behavior is the same — refer to the function's existing docs for complete details.<br /><br /><Card title="Review all available functions and their XanoScript in the function reference" icon="function" horizontal href="/xanoscript/function-reference" />
  </div>
</div>

***

### Section 2: Schedule

The `schedule` block contains the schedule in which the Background Task will run on.

<Tip>You may know this as the 'Timing' section in the visual builder.</Tip>

<div style={{ display: "flex", gap: "1rem", alignItems: "flex-start", flexWrap: "wrap" }}>
  <div className="stickyDiagram">
    ```mermaid theme={null}
    flowchart TB
    A[Declaration] --> B[Logic] --> C[Schedule] --> D[Settings]
    style C fill:#cdeaff,stroke:#0077cc,stroke-width:2px
    style A fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    style B fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    style D fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    ```
  </div>

  <div style={{ flex: 1 }}>
    <Frame caption="Hover over this image to see the XanoScript version">
      <HoverImageCode src="/images/background-tasks-20251003-152534.png" alt="Image of a function stack">
        ```java XanoScript lines icon="code" theme={null}
        schedule = [{
          starts_on: 2025-10-01 06:00:00+0000
          freq     : 604800
          ends_on  : 2025-10-26 19:51:05+0000
        }]
        ```
      </HoverImageCode>
    </Frame>

    <br />

    The schedule begins with an `events` array, which contains one or more objects to represent a schedule entry. Each schedule entry contains a `starts_on` date/time in YYYY-MM-DD HH:MM:SS+TZ format, a `freq` in seconds which defines the interval between runs, and can also contain an `ends_on` date/time in YYYY-MM-DD HH:MM:SS+TZ format. If `ends_on` is not provided, the task will run indefinitely.

    If you're not familiar with background tasks in Xano, you can learn more about them [here](/the-function-stack/building-with-visual-development/background-tasks).
  </div>
</div>

***

### Section 3: Settings

There are several optional settings that can be configured for a Background Task. These settings are defined at the root level of the Background Task block, after the definition, stack, and schedule blocks. They affect how the task behaves.

<div style={{ display: "flex", gap: "1rem", alignItems: "flex-start", flexWrap: "wrap" }}>
  <div className="stickyDiagram">
    ```mermaid theme={null}
    flowchart TB
    A[Declaration] --> B[Logic] --> C[Schedule] --> D[Settings]
    style D fill:#cdeaff,stroke:#0077cc,stroke-width:2px
    style A fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    style B fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    style C fill:#f5f5f5,stroke:#ccc,stroke-width:1px
    ```
  </div>

  <div style={{ flex: 1 }}>
    | Setting       | Type           | Required | Description                                                                                                                                        |
    | ------------- | -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `description` | string         | no       | A short summary of the task. May also appear as a “//” comment above the block.                                                                    |
    | `tags`        | array\[string] | no       | A list of tags used to categorize and organize the Background Task in your workspace.                                                              |
    | `history`     | object         | no       | Configures version inheritance and history behavior. `{inherit: true}` allows this Background Task to inherit history settings from the workspace. |
  </div>
</div>

***

## Detailed Example

Below, you'll see a complete example of a typical signup Background Task endpoint.

```java XanoScript lines icon="code" theme={null}
// Looks at the user table for users that haven't logged in for the last 30 days or more, and sends them an email trying to reengage them with the platform.
task reengage_users {
  active = false
  datasource = "test"

  stack {
    db.query user {
      search = $db.user.last_login <= ("now"|timestamp_subtract_months:1)
      return = {type: "list"}
    } as $user1
  
    foreach ($user1) {
      each as $item {
        util.send_email {
          api_key = "abc123"
          service_provider = "resend"
          subject = "Hey, where'd you go?"
          message = "We noticed you haven't logged in for a while. Come back and give us another shot?"
          to = $item.email
          bcc = []
          cc = []
          from = "admin@myapp.com"
          reply_to = ""
          scheduled_at = ""
        } as $x1
      }
    }
  }

  schedule = [{
    starts_on: 2025-10-01 06:00:00+0000
    freq     : 604800
    ends_on  : 2025-10-26 19:51:05+0000
  }]

  tags = ["user actions", "retention"]
}
```

***

## What's Next

Now that you understand how to define Background Tasks in XanoScript, here are a few great next steps:

<Card title="Explore the function reference" icon="function" horizontal href="/xanoscript/function-reference">
  Learn about the built-in functions available in the stack to start writing more complex logic.
</Card>

<Card title="Try it out in VS Code" icon="https://mintcdn.com/xano-997cb9ee/aZQYcxhIvSDTNEim/images/icons/vscode.svg?fit=max&auto=format&n=aZQYcxhIvSDTNEim&q=85&s=bb6c91058fcbe6ee28fcda04e03de2e6" horizontal href="/xanoscript/vs-code" width="100" height="100" data-path="images/icons/vscode.svg">
  Use the XanoScript VS Code extension with Copilot to write XanoScript in your favorite IDE.
</Card>

<Card title="Learn about Triggers" icon="cube" horizontal href="/xanoscript/triggers">
  They work just like your APIs and custom functions, but they run only when certain other events happen, such as new records in a table.
</Card>
