The modern way to build jobs

Runly is a .NET and Node.js based open source framework for creating multi-threaded background jobs. Offload long-running work out of your app's critical path to provide a great user experience.

Building scalable jobs has never been so easy

Runly jobs are easy to build and easy to scale. Open source and MIT licensed.

public override IAsyncEnumerable<string> GetItemsAsync()
	// get a list of items to process
	return Config.Names.ToAsyncEnumerable();

public override Task<Runly.Result> ProcessAsync(string name)
	// do the work to process each item
	logger.LogInformation("Hello, {name}", name);
	return Task.FromResult(Runly.Result.Success());
> myapp helloworld --names Rick --names Morty

  log: Hello, Rick
  log: Hello, Morty

  Job Successful with 2 items

Batch processing

Process large files, queue and send emails, generate PDFs, handle ETL scenarios, and more. Runly makes it easy to solve common problems in software development.


Move heavy workloads to different machines and parallelize tasks without changing your code. Set the amount of parallel tasks via configuration or from the command line.

Retries built-in

Build resilient applications that are fault tolerant. Don't let intermittent or temporary errors bring down your app's critical path.

Developer friendly

Runly is not a plugin architecture. Run your job app as a CLI and use tools you are already familiar with to debug. Get direct, useful results even when code fails.

How it works

If you can write a for-each loop, you can write a Runly job.

Create your job app

Use a repository template for your language to easily bootstrap a console/CLI project. Or if you are not into templates, just add a reference in your app to one of the core Runly packages:
Then let the Runly job host parse the CLI arguments and run your job.
class Program
	static async Task Main(string[] args)
		await JobHost.CreateDefaultBuilder(args)
			.ConfigureServices((host, services) =>
				// register any dependencies your jobs may need
				services.AddHttpClient<IPlaceApi, HttpPlaceApi>();

Build your jobs

Runly abstracts a common interface for jobs so that you can think of your job as a for-each loop, where a block of code executes for each item in a list. This simple construct naturally fits many problems that developers face everyday such as:
  • processing results from API calls
  • processing results from database queries
  • processing files on disk
{ "items": [ { "id": 13, "address": "509 S Carrollton Ave", "isMapped": true }, { "id": 19, "address": "8124 Oak St", "isMapped": false }, { "id": 35, "address": "4801 Magazine St", "isMapped": true } ] }
13509 S Carrollton Avetrue
198124 Oak Stfalse
354801 Magazine Sttrue
13,"509 S Carrollton Ave",true
19,"8124 Oak St",false
35,"4801 Magazine St",true

Run your jobs

Building and running jobs in a predictable way allows us to build-in goodies on top of your core jobs. Things like an automated, parameterized CLI, multi-threading, scaling work across different machines, and resiliency and fault-tolerance become almost trivial for you to implement.
Running a job

Go beyond background jobs

Your app's long-running work is killing your performance and driving your users away. Let's fix it.

Runly App

Background jobs without the hassle

Automate the deployment, monitoring, and scaling of your jobs with the Runly Platform. Deploy your jobs as simple NuGet/npm packages to run on your hardware or your favorite cloud.

Running your job...

100 unprocessed

Bring UX to the foreground

Make your app more responsive and less error-prone. Don't make your users wait for background work without any feedback. Notify them when work is finished by integrating progress bars and results into your app with Runly UI.

Get started with the Runly Platform for free

No credit card, no commitment