Redis-backed queue system for .NET 8+.
$ dotnet add package Yardios.RedisQueueYardios.RedisQueue is a Redis-backed queue system for .NET 8+, inspired by Laravel's queue system. Easily enqueue jobs into Redis and process them using background workers.
IJob into RedisAdd via CLI:
dotnet add package Yardios.RedisQueue
Or via .csproj:
<PackageReference Include="Yardios.RedisQueue" Version="0.4.1" />
In your Program.cs:
var builder = WebApplication.CreateBuilder(args);
// Add RedisQueue using IConfiguration (appsettings.json)
builder.Services.AddRedisQueue(builder.Configuration);
var app = builder.Build();
app.Run();
In your appsettings.json:
{
"Redis": {
"ConnectionString": "localhost:6379"
},
"QueueProcessorOptions": {
"QueueNames": [ "default", "emails" ],
"JobRetryOptions": {
"MaxRetries": {
"Yardios.API.Application.Jobs.SendTeamInvite": 3
},
"FailUntilAttempt": {
"Yardios.API.Application.Jobs.SendTeamInvite": 2
}
}
},
"QueueWorkerOptions": {
"DelayMilliseconds": 1000
}
}
Implement the IJob interface:
public class SendEmailJob : IJob
{
public string Email { get; set; }
public string Message { get; set; }
public async Task HandleAsync(IServiceProvider services, CancellationToken cancellationToken)
{
var emailService = services.GetRequiredService<IEmailService>();
await emailService.SendAsync(Email, Message);
}
}
You can specify the queue name and an optional delay when enqueuing jobs:
await _queue.EnqueueAsync(new SendEmailJob
{
Email = "future@example.com",
Message = "This is a delayed job!"
}, queueName: "emails", delay: TimeSpan.FromSeconds(30));
queueName (optional): The Redis queue to push the job onto. Must match one of the QueueNames in appsettings.json.delay (optional): A TimeSpan specifying how long to delay before processing the job.Example without delay:
await _queue.EnqueueAsync(new SendEmailJob
{
Email = "test@example.com",
Message = "Hello!"
}, queueName: "default");
✅ Always inject the IQueue interface into your services — never inject the concrete RedisQueue class directly.
This allows for better abstraction, future flexibility, and proper dependency resolution by the DI container.
For example, in your services:
public class TeamService : ITeamService
{
private readonly IQueue _queue;
public TeamService(IQueue queue)
{
_queue = queue;
}
// Use _queue.EnqueueAsync(...) in your methods
}
✅ Avoid injecting the RedisQueue class directly:
// ❌ Do not do this
public class TeamService
{
public TeamService(RedisQueue queue) { }
}
This will cause runtime errors because RedisQueue is registered under the interface IQueue in the service collection.
appsettings.json under Redis:ConnectionString.FailUntilAttempt and MaxRetries.Example appsettings.json:
{
"Redis": {
"ConnectionString": "localhost:6379"
},
"QueueProcessorOptions": {
"QueueNames": [ "default", "emails" ],
"JobRetryOptions": {
"MaxRetries": {
"Yardios.API.Application.Jobs.SendTeamInvite": 3
},
"FailUntilAttempt": {
"Yardios.API.Application.Jobs.SendTeamInvite": 2
}
}
},
"QueueWorkerOptions": {
"DelayMilliseconds": 5000
}
}
MIT License