TickerQ 2.0.1

TickerQ

NuGet NuGet Documentation

Robust. Adaptive. Precise.
TickerQ is a high-performance, modular background job scheduler for .NET applications. It supports cron-based and one-time jobs, integrates with Entity Framework Core for persistence, and offers a live dashboard UI powered by SignalR.

๐Ÿ“š Full Docs

๐Ÿ‘‰ https://tickerq.arcenox.com


Dashboard: TickerQ Dashboard

โœจ Features

  • Time and Cron Scheduling
  • Stateless Core with source generator
  • EF Core Persistence (optional)
  • Live Dashboard UI
  • Retry Policies & Throttling
  • Dependency Injection support
  • Multi-node distributed coordination

๐Ÿ“ฆ Installation

Core (required)

dotnet add package TickerQ

Entity Framework Integration (optional)

dotnet add package TickerQ.EntityFrameworkCore

Dashboard UI (optional)

dotnet add package TickerQ.Dashboard

โš™๏ธ Basic Setup

In Program.cs or Startup.cs

builder.Services.AddTickerQ(options =>
{
    options.SetMaxConcurrency(4); // Optional
    options.SetExceptionHandler<MyExceptionHandler>(); // Optional
    options.AddOperationalStore<MyDbContext>(); // Enables EF-backed storage
    options.CancelMissedTickersOnApplicationRestart(); // Useful in distributed mode
    options.AddDashboard(basePath: "/tickerq-dashboard"); // Dashboard path
    options.AddDashboardBasicAuth(); // Enables simple auth
});

app.UseTickerQ();             // Activates job processor

Job Definition

1. Cron Job (Recurring)

public class CleanupJobs
{
    [TickerFunction(FunctionName = "CleanupLogs", CronExpression = "0 0 * * *")]
    public void CleanupLogs()
    {
        // Runs every midnight
    }
}

This uses a cron expression to run daily at midnight.


2. One-Time Job (TimeTicker)

public class NotificationJobs
{
    [TickerFunction(FunctionName = "SendWelcome")]
    public Task SendWelcome(TickerFunctionContext<string> tickerContext ,CancellationToken ct)
    {
        Console.WriteLine(tickerContext.Request); // Output: User123
        return Task.CompletedTask;
    }
}

Then schedule it:

await _timeTickerManager.AddAsync(new TimeTicker
{
    Function = "SendWelcome",
    ExecutionTime = DateTime.UtcNow.AddMinutes(1),
    Request = TickerHelper.CreateTickerRequest<string>("User123"),
    Retries = 3,
    RetryIntervals = new[] { 30, 60, 120 } // Retry after 30s, 60s, then 2min
});

3. Injecting Services in Jobs (Fully DI Support)

public class ReportJobs
{
    private readonly IReportService _reportService;

    public ReportJobs(IReportService reportService)
    {
        _reportService = reportService;
    }

    [TickerFunction(FunctionName = "GenerateDailyReport", CronExpression = "0 6 * * *")]
    public async Task GenerateDailyReport()
    {
        await _reportService.GenerateAsync();
    }
}

Dashboard UI

Enabled by adding:

options.AddDashboard(basePath: "/tickerq-dashboard");
options.AddDashboardBasicAuth(); // Optional

Accessible at /tickerq-dashboard, it shows:

  • System status
  • Active tickers
  • Job queue state
  • Cron ticker stats
  • Execution history
  • Trigger/cancel/edit jobs live

Auth config (optional):

"TickerQBasicAuth": {
  "Username": "admin",
  "Password": "admin"
}

TickerQ vs Hangfire vs Quartz.NET

| Feature | TickerQ | Hangfire | Quartz.NET | |--------------------------------------|-----------------------------------|-----------------------------------|-------------------------------------| | Cron scheduling | โœ… Yes | โœ… Yes | โœ… Yes | | Time-based one-time jobs | โœ… Yes (TimeTicker) | โš ๏ธ Simulated via delay | โœ… Yes | | Persistent job store | โœ… With EF Core | โœ… Yes | โœ… Yes | | In-memory mode | โœ… Built-in | โœ… Built-in | โœ… Built-in | | Retry/cooldown logic | โœ… Advanced & configurable | โš ๏ธ Basic retries only | โš ๏ธ Manual | | Dashboard UI | โœ… First-party + real-time | โœ… Basic | โš ๏ธ Third-party required | | DI support | โœ… Native and seamless | ๐ŸŸ  Partial โ€“ type-based only | โš ๏ธ Requires extra config | | Reflection-free job discovery | โœ… Roslyn-based, compile-time | โŒ Uses reflection | โŒ Uses reflection | | Multi-node/distributed support | โœ… Native with EF Core | โš ๏ธ Depends on storage | โœ… Yes | | Custom tickers (plugin model) | โœ… Fully extensible | โŒ Not extensible | โš ๏ธ Limited | | Parallelism & concurrency control | โœ… Built-in scheduler threadpool | โœ… Queues/ServerCount | โœ… ThreadPools | | Performance under high load | โœ… Optimized, no overhead | โš ๏ธ Depends on storage/db | โš ๏ธ Thread blocking possible | | Async/await support | โœ… Yes | โš ๏ธ Limited โ€“ wrapped sync methods| โœ… Yes | | CancellationToken support | โœ… Propagated & honored | โŒ Not natively supported | ๐ŸŸ  Optional โ€“ must check manually |

๐Ÿ” Retry & Locking

TickerQ supports:

  • Retries per job
  • Retry intervals (RetryIntervals)
  • Distributed locking (EF mode only)
  • Job ownership tracking across instances
  • Cooldown on job failure

๐Ÿงช Advanced: Manual CronTicker Scheduling

await _cronTickerManager.AddAsync(new CronTicker
{
    Function = "CleanupLogs",
    CronExpression = "0 */6 * * *", // Every 6 hours
    Retries = 2,
    RetryIntervals = new[] { 60, 300 }
});

๐Ÿ› ๏ธ Developer Tips

  • Use [TickerFunction] to register jobs
  • Use FunctionName consistently across schedule and handler
  • Use CancellationToken for graceful cancellation
  • Use Request to pass dynamic data to jobs
  • Use .AddDashboard() only when EF Core is configured

๐Ÿค Contribution

PRs, ideas, and issues are welcome!

  1. Fork & branch
  2. Code your change
  3. Submit a Pull Request

๐Ÿ“„ License

MIT OR Apache 2.0 ยฉ Arcenox
You may choose either license to use this software.


Showing the top 20 packages that depend on TickerQ.

Packages Downloads
Verto.Vcp.TickerQ
Package Description
3
Verto.Vcp.TickerQ
Package Description
1

Version Downloads Last updated
10.2.5 1 03/28/2026
10.2.4 1 03/28/2026
10.2.3 1 03/28/2026
10.2.2 0 03/16/2026
10.2.1 1 03/20/2026
10.2.0 1 03/20/2026
10.1.1 1 02/20/2026
10.1.0 2 02/10/2026
10.1.0-beta 2 02/10/2026
10.0.5.2-beta 2 02/10/2026
10.0.5.1-beta 2 02/10/2026
10.0.5-beta 2 02/10/2026
10.0.4-beta 2 02/10/2026
10.0.3-beta 2 02/10/2026
10.0.2 2 02/10/2026
10.0.1 2 02/10/2026
10.0.0 2 02/10/2026
10.0.0-beta.19 2 02/10/2026
10.0.0-beta.18 2 02/10/2026
10.0.0-beta.17 2 02/10/2026
10.0.0-beta.16 2 02/10/2026
9.2.5 1 03/28/2026
9.2.4 1 03/28/2026
9.2.3 1 03/28/2026
9.2.2 0 03/16/2026
9.2.1 0 03/16/2026
9.2.0 0 03/15/2026
9.1.1 1 02/20/2026
9.1.0 2 02/10/2026
9.1.0-beta 2 02/10/2026
9.0.2 2 02/10/2026
9.0.1 2 02/10/2026
9.0.0 2 02/10/2026
9.0.0-beta.19 2 02/10/2026
9.0.0-beta.18 2 02/10/2026
9.0.0-beta.17 2 02/10/2026
9.0.0-beta.15 2 02/10/2026
9.0.0-beta.14 2 02/10/2026
9.0.0-beta.13 2 02/10/2026
9.0.0-beta.12 2 02/10/2026
9.0.0-beta.11 2 02/10/2026
9.0.0-beta.1 2 02/10/2026
8.2.5 1 03/28/2026
8.2.4 1 03/28/2026
8.2.3 1 03/28/2026
8.2.2 0 03/16/2026
8.2.1 0 03/16/2026
8.2.0 0 03/15/2026
8.1.1 1 02/20/2026
8.1.0 2 02/10/2026
8.1.0-beta 2 02/10/2026
8.0.2 2 02/10/2026
8.0.1 2 02/10/2026
8.0.0 2 02/10/2026
8.0.0-beta.19 2 02/10/2026
8.0.0-beta.18 2 02/10/2026
8.0.0-beta.17 2 02/10/2026
8.0.0-beta.16 2 02/10/2026
8.0.0-beta.15 2 02/10/2026
8.0.0-beta.14 2 02/10/2026
8.0.0-beta.13 2 02/10/2026
8.0.0-beta.12 2 02/10/2026
8.0.0-beta.11 2 02/10/2026
8.0.0-beta.10 2 02/10/2026
8.0.0-beta.9 2 02/10/2026
8.0.0-beta.8 2 02/10/2026
8.0.0-beta.6 2 02/10/2026
8.0.0-beta.5 2 02/10/2026
8.0.0-beta.4 2 02/10/2026
8.0.0-beta.3 2 02/10/2026
8.0.0-beta.2 2 02/10/2026
8.0.0-beta.1 2 02/10/2026
2.5.3 2 02/10/2026
2.5.3-preview 2 02/10/2026
2.5.2 2 02/10/2026
2.5.1 2 02/10/2026
2.5.0 2 02/10/2026
2.4.4 2 02/10/2026
2.4.3 2 02/10/2026
2.4.2 2 02/10/2026
2.4.1 1 02/10/2026
2.4.0 2 02/10/2026
2.3.0 2 02/10/2026
2.2.2 2 02/10/2026
2.2.2-preview 2 02/10/2026
2.2.1 2 02/10/2026
2.2.1-preview-1 2 02/10/2026
2.2.1-preview 2 02/10/2026
2.2.0 2 02/10/2026
2.2.0-preview 2 02/10/2026
2.1.7-preview 2 02/10/2026
2.1.6-preview 2 02/10/2026
2.1.5 2 02/10/2026
2.1.3 2 02/10/2026
2.1.1 2 02/10/2026
2.1.0 2 02/10/2026
2.0.1 2 02/10/2026
2.0.0 2 02/10/2026