# Background Jobs

Gravity supports background jobs with [Bull.js](https://github.com/OptimalBits/bull). These are used for offloading longer tasks to a separate process. There is a working example included that manages an [automated onboarding flow](/gravity-server/user-onboarding.md).

{% hint style="info" %}
For more information, [please read the Bull docs](https://github.com/OptimalBits/bull).
{% endhint %}

## 1. Add Your Redis URL

You will need to set up a Redis database for tracking the job queue and then add the URL to the following environment variable:

<pre class="language-javascript"><code class="lang-javascript"><strong>REDIS_JOB_URL=
</strong></code></pre>

## 2. Start The Worker

Run the following command to start the background worker:

```
node worker
```

The worker will process jobs added to the queue.

{% hint style="warning" %}
If you're using Mongo, the setup wizard will inject mongo.connect() into the worker. If you bypassed the setup wizard, you need to add this manually.
{% endhint %}

There's also a `Procfile` included to start a separate worker dynos on [Heroku](https://heroku.com) automatically. Other platforms will vary in how you set this up.

The default worker has a `setTimeout` function in `worker/index.js` – you should replace this with your own job function.&#x20;

## 3. Add a Job To The Queue

There are two ways to add a job to the queue in Gravity:

1. Internally
2. Using the API

To add a job on the server, use the following code:

```javascript
const Queue = require('bull');
const jobQueue = new Queue('jobs', process.env.REDIS_JOB_URL);

async function addJob(){

 const job = await jobQueue.add({ /* your custom metadata here */ });
 
}
```

To add a job via the API, make a POST request to:

```javascript
POST /api/job
```

## Updating the Job Progress

It's helpful to set different statuses during the lifecycle of the job:

```javascript
const job = await jobQueue.getJob(id);
job.progress('started');
```

## Updating The Job Data

If you want to update the job metadata, make a PATCH request to:

```javascript
PATCH /api/job/:id
```

The request body will be merged with the existing job data.

## Getting a Job's Status

Once a job has begun, you'll want to check it's status and perform an action when it has completed. To do this, make a GET request to:

```
GET /api/job/:id
```

You can determine if a job has finished using the `finishedOn` key.

You can also fetch a job internally without using the API with:

```javascript
const job = await jobQueue.getJob(id);
```

## Delete a Job

{% hint style="danger" %}
If a job has already started, you can't delete it from the queue.&#x20;
{% endhint %}

You can delete a job that hasn't been executed yet using the the API:

```javascript
DELETE /api/job/:id
```

or anywhere in your internal app:

```javascript
const job = await jobQueue.getJob(req.params.id);
await job.remove();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.usegravity.app/gravity-server/background-jobs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
