diff --git a/composer.json b/composer.json
index de0c9bc..e1c0ca1 100644
--- a/composer.json
+++ b/composer.json
@@ -20,7 +20,8 @@
     "require": {
         "php": "^8.1",
         "ext-json": "*",
-        "codeigniter4/settings": "^2.0"
+        "codeigniter4/settings": "^2.0",
+        "codeigniter4/queue": "dev-develop"
     },
     "require-dev": {
         "codeigniter4/devkit": "^1.3",
diff --git a/docs/basic-usage.md b/docs/basic-usage.md
index 5bf7843..e844045 100644
--- a/docs/basic-usage.md
+++ b/docs/basic-usage.md
@@ -81,6 +81,48 @@ a simple URL string, you can use a closure or command instead.
 $schedule->url('https://my-status-cloud.com?site=foo.com')->everyFiveMinutes();
 ```
 
+### Scheduling Queue Jobs
+
+If you want to schedule a Queue Job, you can use the `queue()` method and specify the queue name, job name and data your job needs:
+
+```php
+$schedule->queue('queue-name', 'jobName', ['data' => 'array'])->hourly();
+```
+
+!!! note
+
+    To learn more about the [Queue package](https://github.com/codeigniter4/queue) you can visit a project page.
+
+
+The `singleInstance()` option, described in the next section, works a bit differently than with other scheduling methods.
+Since queue jobs are added quickly and processed later in the background, the lock is applied as soon as the job is queued - not when it actually runs.
+
+```php
+$schedule->queue('queue-name', 'jobName', ['data' => 'array'])
+    ->hourly()
+    ->singleInstance();
+```
+
+This means:
+
+- The lock is created immediately when the job is queued.
+- The lock is released only after the job is processed (whether it succeeds or fails).
+
+We can optionally pass a TTL to `singleInstance()` to limit how long the job lock should last:
+
+```php
+$schedule->queue('queue-name', 'jobName', ['data' => 'array'])
+    ->hourly()
+    ->singleInstance(30 * MINUTE);
+```
+
+How it works:
+
+- The lock is set immediately when the job is queued.
+- The job must start processing before the TTL expires (in this case, within 30 minutes).
+- Once the job starts, the lock is renewed for the same TTL.
+- So, effectively, you have 30 minutes to start, and another 30 minutes to complete the job.
+
 ## Single Instance Tasks
 
 Some tasks can run longer than their scheduled interval. To prevent multiple instances of the same task running simultaneously, you can use the `singleInstance()` method:
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index f275e39..45e53a9 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -39,7 +39,7 @@ parameters:
 		-
 			message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''CodeIgniter\\\\Tasks\\\\Task'' and CodeIgniter\\Tasks\\Task will always evaluate to true\.$#'
 			identifier: method.alreadyNarrowedType
-			count: 3
+			count: 4
 			path: tests/unit/SchedulerTest.php
 
 		-
diff --git a/src/Scheduler.php b/src/Scheduler.php
index b7d2b5e..a430813 100644
--- a/src/Scheduler.php
+++ b/src/Scheduler.php
@@ -14,6 +14,8 @@
 namespace CodeIgniter\Tasks;
 
 use Closure;
+use CodeIgniter\Queue\Queue;
+use CodeIgniter\Tasks\Exceptions\TasksException;
 
 class Scheduler
 {
@@ -73,6 +75,16 @@ public function url(string $url): Task
         return $this->createTask('url', $url);
     }
 
+    /**
+     * Schedule a queue job.
+     *
+     * @throws TasksException
+     */
+    public function queue(string $queue, string $job, array $data): Task
+    {
+        return $this->createTask('queue', [$queue, $job, $data]);
+    }
+
     // --------------------------------------------------------------------
 
     /**
diff --git a/src/Task.php b/src/Task.php
index a5659c6..e121fb1 100644
--- a/src/Task.php
+++ b/src/Task.php
@@ -15,6 +15,7 @@
 
 use CodeIgniter\Events\Events;
 use CodeIgniter\I18n\Time;
+use CodeIgniter\Queue\Payloads\PayloadMetadata;
 use CodeIgniter\Tasks\Exceptions\TasksException;
 use InvalidArgumentException;
 use ReflectionException;
@@ -48,6 +49,7 @@ class Task
         'closure',
         'event',
         'url',
+        'queue',
     ];
 
     /**
@@ -142,7 +144,7 @@ public function run()
 
             return $this->{$method}();
         } finally {
-            if ($this->singleInstance) {
+            if ($this->singleInstance && $this->getType() !== 'queue') {
                 cache()->delete($lockKey);
             }
         }
@@ -297,6 +299,25 @@ protected function runUrl()
         return $response->getBody();
     }
 
+    /**
+     * Sends a job to the queue.
+     */
+    protected function runQueue()
+    {
+        $queueAction = $this->getAction();
+
+        if ($this->singleInstance) {
+            // Create PayloadMetadata instance with the task lock key
+            $queueAction[] = new PayloadMetadata([
+                'queue'       => $queueAction[0],
+                'taskLockTTL' => $this->singleInstanceTTL,
+                'taskLockKey' => $this->getLockKey(),
+            ]);
+        }
+
+        return service('queue')->push(...$queueAction);
+    }
+
     /**
      * Builds a unique name for the task.
      * Used when an existing name doesn't exist.
diff --git a/src/Test/MockTask.php b/src/Test/MockTask.php
index fe1d54a..0a685b9 100644
--- a/src/Test/MockTask.php
+++ b/src/Test/MockTask.php
@@ -46,6 +46,7 @@ public function run()
             'closure' => 42,
             'event'   => true,
             'url'     => 'body',
+            'queue'   => true,
         ][$this->type];
     }
 }
diff --git a/tests/_support/Config/Registrar.php b/tests/_support/Config/Registrar.php
new file mode 100644
index 0000000..dd7e7e4
--- /dev/null
+++ b/tests/_support/Config/Registrar.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of CodeIgniter Tasks.
+ *
+ * (c) CodeIgniter Foundation <admin@codeigniter.com>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Tests\Support\Config;
+
+class Registrar
+{
+    public static function Queue(): array
+    {
+        return [
+            'jobHandlers' => [
+                'job-example' => 'Tests\Jobs\Example',
+            ],
+        ];
+    }
+}
diff --git a/tests/_support/Jobs/Example.php b/tests/_support/Jobs/Example.php
new file mode 100644
index 0000000..d8115bd
--- /dev/null
+++ b/tests/_support/Jobs/Example.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of CodeIgniter Tasks.
+ *
+ * (c) CodeIgniter Foundation <admin@codeigniter.com>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Tests\Support\Jobs;
+
+use CodeIgniter\Queue\BaseJob;
+use CodeIgniter\Queue\Interfaces\JobInterface;
+
+class Example extends BaseJob implements JobInterface
+{
+    public function process(): bool
+    {
+        return true;
+    }
+}
diff --git a/tests/unit/SchedulerTest.php b/tests/unit/SchedulerTest.php
index ed1c5cd..a332886 100644
--- a/tests/unit/SchedulerTest.php
+++ b/tests/unit/SchedulerTest.php
@@ -56,4 +56,12 @@ public function testShellSavesTask()
         $this->assertInstanceOf(Task::class, $task);
         $this->assertSame('foo:bar', $task->getAction());
     }
+
+    public function testQueueSavesTask()
+    {
+        $task = $this->scheduler->queue('example', 'job-example', ['data' => 'array']);
+
+        $this->assertInstanceOf(Task::class, $task);
+        $this->assertSame(['example', 'job-example', ['data' => 'array']], $task->getAction());
+    }
 }
diff --git a/tests/unit/TaskTest.php b/tests/unit/TaskTest.php
index 55862fe..e61b3f5 100644
--- a/tests/unit/TaskTest.php
+++ b/tests/unit/TaskTest.php
@@ -297,4 +297,31 @@ public function testSingleInstanceWithCustomTTL()
 
         $this->assertNull($this->getPrivateProperty($task2, 'singleInstanceTTL'));
     }
+
+    public function testRunQueue()
+    {
+        $task = new Task('queue', ['example', 'job-example', []]);
+        $task->named('test_run_queue');
+
+        $result = $task->run();
+        $this->assertTrue($result);
+
+        // No lock
+        $lockKey = $this->getPrivateMethodInvoker($task, 'getLockKey')();
+        $this->assertNull(cache()->get($lockKey));
+    }
+
+    public function testRunQueueWithSingleInstance()
+    {
+        $task = new Task('queue', ['example', 'job-example', []]);
+        $task->named('test_run_queue_single');
+        $task->singleInstance();
+
+        $result = $task->run();
+        $this->assertTrue($result);
+
+        // Lock is still present
+        $lockKey = $this->getPrivateMethodInvoker($task, 'getLockKey')();
+        $this->assertNotNull(cache()->get($lockKey));
+    }
 }