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.
Multi-threading
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()
.RunJobAsync();
}
}
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
API
{
"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
}
]
}
Database
Id | Address | IsMapped |
---|---|---|
13 | 509 S Carrollton Ave | true |
19 | 8124 Oak St | false |
35 | 4801 Magazine St | true |
File
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.
Go beyond background jobs
Your app's long-running work is killing your performance and driving your users away. Let's fix it.

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.
Job complete
100 successful items
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.