TL;DR

Running a batch of jobs across a few machines can be a pain. You have to manage several SSH sessions, keep track of the logs, and synchronize the results. nextask is built to handle it for you. It is a lightweight distributed task queue written in Go. nextask lets you locally run commands as you would on your machine, while under the hood delegating each run to the next available worker. It can also snapshot your code, upload run artifacts, and store the logs, for maximum reproducibility.

Background

During the first year of my PhD, I collaborated on a research project that required us to run many experiments within a short rebuttal period. We used whatever compute we had, including local machines and a shared SLURM cluster. During that period, we managed to obtain the results we desperately needed, but only after many messy runs.

That review process ended in rejection. We later submitted the paper again and waited almost a year for a decision. Apparently, it had been lost midway through the process. After about eight months, the paper was assigned to a new area chair, and the entire review process started over.

Once the reviews finally arrived, the reviewers asked for more experiments, as expected. I dug into the nearly 18-month-old codebase and tried to recover the code and results from the original runs. The whole setup was a mess. We had to rerun the experiments and could not fully reproduce the results we had reported in the paper. Fortunately, after I spent far more time than I should have, we produced the additional results and the paper was accepted.

nextask was born out of this experience. It provides reproducible, automated runtime management by keeping logs, results, and the code used to generate them in a single persistent location. The following sections explain how it works and describe some common use cases.

How it works

nextask has three main components. The CLI runs on the local machine, the queue ideally runs on a persistent, network-accessible host, and the workers execute tasks. The diagram below shows how these components fit together.

nextask architecture you@local — nextask ❯ nextask enqueue “python train.py” \     --with git --with s3 --attach [a3f9c2] pending [worker-1] claimed a3f9c2 [a3f9c2] epoch 1/3  loss 0.482 [a3f9c2] epoch 2/3  loss 0.211 [a3f9c2] epoch 3/3  loss 0.094 ✓ a3f9c2 completed | exit 0 2 SNAPSHOT remote branch a3f9c2 5 PUSH ARTIFACT S3 branch a3f9c2 1 ENQUEUE 3 CLAIM 4 STREAM LOGS queue postgres a3f9c2 pending running completed c4a811 running b7d2e1 completed atomic claim + heartbeats worker-1 a3f9c2 gpu=a100 idle › python train.py worker-2 c4a811 image=pytorch › python eval.py

A task through its lifecycle: (1) the CLI enqueues it into the Postgres-backed queue, (2) --with git pushes the working tree to the remote Git repository, (3) a matching worker claims it atomically, and (4) logs stream live to the attached client. Green dots indicate worker heartbeats, and the status chip moves from pending to running to completed.

The CLI lets us enqueue, list, monitor, and inspect logs for tasks. Before looking at individual commands, let’s walk through an example of how it works once everything is set up.

Let’s begin with a project. To send its code to the worker with --with git, it must be a Git repository with at least one commit and a configured remote. Suppose we want to delegate a task to an available worker running on a powerful GPU server, a remote workstation, or a production server to which we have secure access. To run the task on a worker, enqueue it from the project directory:

~/project
nextask enqueue "python script.py" --with git

This adds the task to the queue. When a matching worker becomes available, it runs the task and streams the logs back to the database. To follow the task as if it were running locally, add the --attach flag:

~/project
nextask enqueue "python script.py" --with git --attach

This streams the logs to your terminal in real time while also storing them in the database.

Commands

Here, we cover some of the basic commands in nextask. Each command touches only the part of the system it needs.

Workers

You can view registered workers from the CLI or register one on the current machine with:

Terminal window
nextask worker

To start a worker that accepts only tasks matching image=pytorch gpu=a100 and exits after one hour of idleness, run:

Terminal window
nextask worker --tag image=pytorch,gpu=a100 --exit-if-idle 1h

Use the following commands to manage registered workers:

Terminal window
nextask worker list # list workers
nextask worker stop <workerId> # stop worker

Tasks

The remaining commands cover task management and monitoring.

Terminal window
nextask list --status running --tag sweep=exp3 # list & filter tasks
nextask log <taskId> --attach # stream live output
nextask show <taskId> # task details
nextask cancel <taskId> # cancel task

Agent-ready

nextask is agent-ready by design. Its skills guide agents through setting up services such as Postgres, deploying workers, and managing tasks. They prompt you for preferences with multiple-choice questions.

To install the skills, run this command in your agent directory:

Terminal window
npx skills add https://github.com/TolgaOk/nextask/skills

Use cases

In agentic workflows, especially those involving sub-agents, several tasks often run in parallel. This can lead to resource contention and even freeze the system. nextask handles this by queuing tasks and dispatching them as matching workers become available, even when the local machine is the only worker. Agents can monitor tasks, be awakened when a task finishes, and easily access the results.

A common use case for nextask is running a batch of tasks, such as a hyperparameter sweep, and waiting for them to finish. Agents can wait for all tasks to finish or just the first one. The following example runs a hyperparameter sweep:

Terminal window
for lr in 0.1 0.01 0.001; do
nextask enqueue "python train.py --lr $lr" --with git --tag exp=sweep,lr=$lr
done
nextask wait --tag exp=sweep # block until all `exp=sweep` tasks are finished

The final command wakes the agent only after all tasks have finished. When an agent enqueues long-running tasks, you and other agents can independently monitor their progress, stream their logs, check their status, and track their results without interrupting the submitting agent.

Install

To install nextask, run:

Terminal window
curl -fsSL https://raw.githubusercontent.com/TolgaOk/nextask/main/install | bash

Before submitting tasks, configure the PostgreSQL connection, run nextask init db, and start a worker. See the configuration guide for setup instructions.