diff --git a/templates/intro-jobs/README.ipynb b/templates/intro-jobs/README.ipynb
new file mode 100644
index 000000000..c539c2d6f
--- /dev/null
+++ b/templates/intro-jobs/README.ipynb
@@ -0,0 +1,123 @@
+
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Introduction to Jobs\n",
+ "\n",
+ "This tutorial shows you how to:\n",
+ "1. Run a Ray app non-interactively in Anyscale as an \"Anyscale Job\".\n",
+ "2. Configure and debug Anyscale Jobs.\n",
+ "\n",
+ "**Note**: This tutorial is run within a workspace. Please overview the `Introduction to Workspaces` template first before this tutorial.\n",
+ "\n",
+ "## Key features of Anyscale Jobs\n",
+ "\n",
+ "Typically, we recommend running batch Ray apps as Anyscale Jobs when moving to production. Like workspaces, Anyscale Jobs run with their own Ray cluster, so you can run the exact same Ray program in a workspace as a Job too.\n",
+ "\n",
+ "Key features of Anyscale Jobs:\n",
+ "- Programmatic submission API\n",
+ "- Automated failure handling\n",
+ "- Automated email alerting\n",
+ "- Record and persist outputs such as logs\n",
+ "\n",
+ "\n",
+ "**Note**: Ray also has an internal concept of a \"Ray job\", which is created when running a Ray app. Anyscale Jobs, Workspaces, and Services all launch Ray jobs internally."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Walkthrough\n",
+ "\n",
+ "First, let's run the following app first interactively in the current workspace.\n",
+ "\n",
+ "This template includes a simple processing job in **./main.py** that runs a few Ray tasks. Run the cell below in the workspace, you should see it print the result after a few seconds."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# First install the necessary `emoji` dependency.\n",
+ "!pip install emoji"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Then run the Ray app script.\n",
+ "!python main.py"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Next, let's try submitting the app to Anyscale Jobs. Within a workspace, you can use the \"ray job submit\" (job runs will be managed by Anyscale Jobs) functionality for this.\n",
+ "\n",
+ "The following cell should also run to completion within a few minutes and print the same result. Note however that the Ray app was not run within the workspace cluster (you can check the ``Ray Dashboard`` to verify). It was submitted to Anyscale for execution on a new Ray cluster."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Second, submit the Ray app for execution on a new Ray cluster.\n",
+ "# The execution will be managed by Anyscale Jobs.\n",
+ "!ray job submit --wait -- python main.py\n",
+ "\n",
+ "# Tip: You can run any Ray app as a job by prefixing its entrypoint with \"ray job submit --\"."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Job UI Overview\n",
+ "\n",
+ "You can view active and historical job runs at (`Home > Jobs`). Click into the job run created by the above cell to inspect its results.\n",
+ "\n",
+ "You should see the job state and its output on the overview page.\n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This concludes the Anyscale Jobs tutorial. To learn more about how to configure Anyscale Jobs, see the [Anyscale documentation](https://docs.endpoints.anyscale.com/preview/)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Summary\n",
+ "\n",
+ "This notebook:\n",
+ "- Ran a simple Ray app in the local workspace.\n",
+ "- Submitted the same Ray app as an Anyscale Job."
+ ]
+ }
+ ],
+ "metadata": {
+ "language_info": {
+ "name": "python"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/templates/intro-jobs/README.md b/templates/intro-jobs/README.md
new file mode 100644
index 000000000..72d0b16ef
--- /dev/null
+++ b/templates/intro-jobs/README.md
@@ -0,0 +1,67 @@
+# Introduction to Jobs
+
+This tutorial shows you how to:
+1. Run a Ray app non-interactively in Anyscale as an "Anyscale Job".
+2. Configure and debug Anyscale Jobs.
+
+**Note**: This tutorial is run within a workspace. Please overview the `Introduction to Workspaces` template first before this tutorial.
+
+## Key features of Anyscale Jobs
+
+Typically, we recommend running batch Ray apps as Anyscale Jobs when moving to production. Like workspaces, Anyscale Jobs run with their own Ray cluster, so you can run the exact same Ray program in a workspace as a Job too.
+
+Key features of Anyscale Jobs:
+- Programmatic submission API
+- Automated failure handling
+- Automated email alerting
+- Record and persist outputs such as logs
+
+
+**Note**: Ray also has an internal concept of a "Ray job", which is created when running a Ray app. Anyscale Jobs, Workspaces, and Services all launch Ray jobs internally.
+
+## Walkthrough
+
+First, let's run the following app first interactively in the current workspace.
+
+This template includes a simple processing job in **./main.py** that runs a few Ray tasks. Run the cell below in the workspace, you should see it print the result after a few seconds.
+
+
+```python
+# First install the necessary `emoji` dependency.
+!pip install emoji
+```
+
+
+```python
+# Then run the Ray app script.
+!python main.py
+```
+
+Next, let's try submitting the app to Anyscale Jobs. Within a workspace, you can use the "ray job submit" (job runs will be managed by Anyscale Jobs) functionality for this.
+
+The following cell should also run to completion within a few minutes and print the same result. Note however that the Ray app was not run within the workspace cluster (you can check the ``Ray Dashboard`` to verify). It was submitted to Anyscale for execution on a new Ray cluster.
+
+
+```python
+# Second, submit the Ray app for execution on a new Ray cluster.
+# The execution will be managed by Anyscale Jobs.
+!ray job submit --wait -- python main.py
+
+# Tip: You can run any Ray app as a job by prefixing its entrypoint with "ray job submit --".
+```
+
+### Job UI Overview
+
+You can view active and historical job runs at (`Home > Jobs`). Click into the job run created by the above cell to inspect its results.
+
+You should see the job state and its output on the overview page.
+
+
+
+This concludes the Anyscale Jobs tutorial. To learn more about how to configure Anyscale Jobs, see the [Anyscale documentation](https://docs.endpoints.anyscale.com/preview/).
+
+## Summary
+
+This notebook:
+- Ran a simple Ray app in the local workspace.
+- Submitted the same Ray app as an Anyscale Job.
diff --git a/templates/intro-jobs/assets/anyscale-job.png b/templates/intro-jobs/assets/anyscale-job.png
new file mode 100644
index 000000000..9eb296f5b
Binary files /dev/null and b/templates/intro-jobs/assets/anyscale-job.png differ
diff --git a/templates/intro-jobs/main.py b/templates/intro-jobs/main.py
new file mode 100644
index 000000000..2d8f3f710
--- /dev/null
+++ b/templates/intro-jobs/main.py
@@ -0,0 +1,12 @@
+import ray
+import emoji
+import time
+
+@ray.remote
+def process(x):
+ print(emoji.emojize("Processing :thumbs_up:"), x)
+ time.sleep(1)
+ return x * 2
+
+result = ray.get([process.remote(x) for x in range(10)])
+print("The job result is", result)