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

# Background jobs

> Run scheduled and event-driven code in your app, and check it in the editor's Workflows tab

Background jobs are parts of your app's code that run on their own: on a schedule, such as every weekday at 8am, or when your app sends an event, such as when a new order is saved. You create them by asking the AI. The app editor lists them in a tab labelled **Workflows**.

> [!NOTE]
>
> Background jobs belong to an app and run its code. To have an AI coworker do something on a schedule, use [scheduled tasks](https://docs.vybe.build/automations/scheduled-tasks.md) instead.

## Create a background job

Ask the AI in the app chat. Say what should happen, when, and in which timezone.

> Every weekday at 8am New York time, pull yesterday's closed deals from HubSpot and save them to the deals table.

> Once an hour, check the inventory table and post in #ops on Slack when a product drops below 10 units.

> When someone submits a new expense, email a summary to [finance@acme.com](mailto:finance@acme.com).

> On the first day of every month, delete tasks that were completed more than 90 days ago.

The AI writes the job and connects it to your app. Then publish: a new or changed job only starts running on its own once you [publish](https://docs.vybe.build/apps/publishing.md) the app.

### Two kinds of jobs

| Kind | Runs when | Shown in the Workflows tab as |
| - | - | - |
| Scheduled | On a repeating schedule | The schedule in words, followed by "(UTC)" |
| Event-driven | Your app sends a named event, for example after it saves a record | The event name, for example `expense/submitted` |

> [!TIP]
>
> Schedules are in UTC. Tell the AI which timezone you mean, then check the time shown in the **Workflows** tab. If a job must run at the same local time all year, say so: a fixed UTC time moves by an hour against your local time when daylight saving time starts or ends.

## The Workflows tab

Add the **Workflows** tab from the **+** menu in the editor's tab bar. Some older apps don't have this tab. The top of the tab counts your jobs, for example "3 deployed, 1 not deployed". Each job has a card with:

* its name and ID
* status badges (see below)
* **Triggers**: the schedule or the event that starts it
* **Concurrency** and **Rate Limit**, when the job sets them
* a **Test Run** button, except on jobs that will be removed on the next publish

If the app has no jobs yet, the tab reads "No workflows deployed yet".

### Status badges

| Badge | Meaning | What to do |
| - | - | - |
| **Deployed** | The job is live in your published app. | Nothing. |
| **Not Deployed** | The job is in your code but not live yet. The card says "Publish your app or it won't run." | Publish the app. |
| **Unregistered** | The job is in your code but isn't connected to the app, so it won't run. The card says "This workflow needs attention." | Ask the AI to register the job, or to delete it if you don't need it. |
| **Will be removed on next publish** | The job still runs in the published app, but it's no longer in your code. | Publish to stop it. |

### Test a job

Click **Test Run** to run a job once, right away, without waiting for its schedule or event. It runs in your app's preview environment. A notice confirms that the run started, or shows the error if it couldn't start.

> [!WARNING]
>
> A test run does real work. It uses the same database as your live app, so any data it writes shows up in the live app, and it can send real messages through your integrations.

The tab doesn't show what happened during a run. Check the data the job was meant to change, or ask the AI to look at the logs.

### What the tab doesn't have

* No run history or step-by-step logs.
* No way to see runs of the published app.
* No switch to pause or disable a job.

## Change, pause or remove a job

Ask the AI, then publish:

> Change the inventory check to run every 4 hours instead of every hour.

> Stop the daily HubSpot sync and remove that job.

Until you publish, the published app keeps running the old version. A job you removed shows **Will be removed on next publish** until then.

## Tips

* **Use shared connections.** A background job can only use integration accounts shared with the whole organization. Private accounts work only when a signed-in person is using the app, so a job can't use them. See [Integrations](https://docs.vybe.build/connections/integrations.md).
* **Event names must match exactly.** If an event-driven job never runs, ask the AI to check that the app sends exactly the event name shown under **Triggers**.

## For developers

Background jobs are Inngest functions. They live in `src/inngest/functions`. Each one must be exported from `src/inngest/index.ts` and listed in the serve route, `src/app/api/inngest/route.ts`. A function that isn't exported from `src/inngest/index.ts` shows as **Unregistered**. A scheduled job looks like this:

```typescript theme={null}
import { inngest } from "../client";

export const weeklyDigest = inngest.createFunction(
  { id: "weekly-digest" },
  { cron: "0 9 * * 1" },
  async ({ step }) => {
    await step.run("send-digest", async () => {
      // ...
    });
  },
);
```

An event-driven job uses `{ event: "expense/submitted" }` as its trigger, and your app starts it with `inngest.send({ name: "expense/submitted", data: { ... } })`. You can read and edit these files in the **Code** tab. See [Working with code](https://docs.vybe.build/apps/working-with-code.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.