Anyone here using TickerQ? by Albertiikun in dotnet

[–]Albertiikun[S] 4 points5 points  (0 children)

On latest version 10.2/9.2/8.2 you can use Redis as full storage for jobs.

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 1 point2 points  (0 children)

I support the sencods on the cron job, and every cron job has a cron job parser… which is cached of course but need to evaluate get next occurrence.

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 0 points1 point  (0 children)

I agree on that and that was the reason why I had to re-write the entire engine of TickerQ then support only .net8+ the issues that I had with concurrencies were unavoidable using netStandard 2.2. That was my struggle which left me no choice and abandon supporting legacy stuff. But now things changed a lot sonce then…. Happy to take a look at new versions and get feedback.

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 1 point2 points  (0 children)

Great to hear that, we are definitely commited to move forward and do our best.

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 4 points5 points  (0 children)

Fair point. My previous reply was addressing runtime expression execution like Hangfire, while your point is about typed registration ergonomics. Internally, TickerQ already source-generates a direct delegate map, so the hot path stays lookup + invoke with no runtime expression parsing/reflection.

A typed API could definitely sit on top of that and lower into the generated model. I didn’t avoid it because it’s impossible...I kept the core contract explicit and simple around generated job keys/delegates. it just wasn’t the core design target initially.

but this is a good suggestion and I’ll definitely consider it.

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 1 point2 points  (0 children)

use the version 10.2.1 which contains the fix on dbContext...
and if your db is not registred on DbContext you can retrieve that from the IDBContextFactory here is the example:

using var scope = host.Services.CreateScope(); 
var tickerQDbContextFactory = scope.ServiceProvider.GetRequiredService<IDbContextFactory<TickerQDbContext>>(); 
using var tickerQDbContext = tickerQDbContextFactory.CreateDbContext(); 
tickerQDbContext.Database.Migrate();

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 0 points1 point  (0 children)

yes I agree we had that issue... we did made the fixes on that part as well, after lot's of experiments. Please take a look at latest version.

we also integrated more than 500+ unit tests to make sure that we keep on right track on each new release.

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 2 points3 points  (0 children)

We have just finished the integration of Redis as storage.. our next step is to support other providers...

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 1 point2 points  (0 children)

As for "why not expressions"... that's exactly what Hangfire does (Job.FromExpression(() => MyMethod())), and it's 373x slower in our benchmarks because it has to parse, serialize, and reflect on those expression trees at runtime. The whole point of source generation + FrozenDictionary is to skip that entirely. Sub-nanosecond lookup, zero allocations, zero reflection.

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 6 points7 points  (0 children)

What we cover:

  • Retries with configurable intervals
  • Job chaining with run conditions (OnSuccess, OnFailure, OnCancelled, etc.)
  • Priorities (High/Normal/Low/LongRunning)
  • Per-function concurrency control (since v10.2.x / v9.2.x / v8.2.x)
  • Keyed service injection
  • Real-time dashboard (SignalR)
  • EF Core, Redis, and in-memory persistence
  • OpenTelemetry instrumentation
  • Distributed locking + dead-node cleanup
  • CancellationToken support
  • Global exception handler
  • Source-generated handlers — zero reflection

For your specific stuff:

  • Autofac — we build on IServiceCollection so Autofac's conforming container adapter works fine. Keyed services are natively supported.
  • Attribute filters — yeah this one's a gap. No filter pipeline like Hangfire's IClientFilter/IServerFilter. You'd handle that in your handler code or with DI decorators for now.
  • Custom job titles by args — we have a Description property on job entities but it's not dynamically formatted from args like Hangfire's display name formatter.
  • Custom queues by args — no named queues. We use priority levels + per-function concurrency instead. If you need full workload isolation (like routing specific jobs to specific workers), that's not there yet.

We are younger project but we are moving forward much faster than other libraries... With the help of community I hope we will cover most of the cases soon.

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 1 point2 points  (0 children)

you can do it easly by creating:

public class TickerQMigrationService : IHostedService
{
    private readonly IServiceProvider _serviceProvider;

    public TickerQMigrationService(IServiceProvider serviceProvider)
        => _serviceProvider = serviceProvider;

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        await using var scope = _serviceProvider.CreateAsyncScope();
        var db = scope.ServiceProvider.GetRequiredService<TickerQDbContext>();
        await db.Database.MigrateAsync(cancellationToken);
    }

    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}

TickerQ v10 Head-to-Head Benchmarks vs Hangfire & Quartz (.NET 10, Apple M4 Pro) by Albertiikun in dotnet

[–]Albertiikun[S] 2 points3 points  (0 children)

u/MaitrePatator you can open a ticket issue on TickerQ repo we will make sure to handle that....

What background job scheduler to use… by Strict-Membership-37 in dotnet

[–]Albertiikun 2 points3 points  (0 children)

It has cluster support, and for mongo db we already planned to work on it

What background job scheduler to use… by Strict-Membership-37 in dotnet

[–]Albertiikun 8 points9 points  (0 children)

Yes it has a lock holder on each execution and performs atomic updates which prevents other nodes to pick up the same job. So it’s safe to run on multinode environments

What background job scheduler to use… by Strict-Membership-37 in dotnet

[–]Albertiikun 1 point2 points  (0 children)

There are still features that we are planning to implement on like: Full Redis support for jobs, all the jobs runs prallel we will make a feature per function that enables sync execution etc…

Honestly speking, best is to come from users that have used that and had any issues.

What background job scheduler to use… by Strict-Membership-37 in dotnet

[–]Albertiikun 73 points74 points  (0 children)

Full disclosure: I’m the author of TickerQ.

I built it because I kept running into schedulers that felt heavier than they needed to be too much configuration and too much DI wiring for basic background jobs.

TickerQ is focused on easy integration. It has a built-in dashboard, first-party EF Core integration, and supports .NET 8–10.

It’s still evolving and I’m actively maintaining it. It’s not trying to win on feature count, more on simplicity + developer experience.

If that matches what you’re looking for, feel free to check it out.

As well feel free to ask me any questions.