TickerQ: a source-generated job scheduler for .NET with EF Core and Redis persistence
TickerQ is a fast, reflection-free background task scheduler for .NET built with source generators, EF Core integration, cron + time-based execution, and a real-time dashboard.
At a glance
- What is it?
- TickerQ registers scheduled methods at compile time instead of through reflection, persists jobs in your existing database or Redis, and ships a SignalR dashboard. Here is how the pieces fit, and where it stops being the right tool.
- Who is it for?
- Adopt TickerQ if you are on .NET, already run EF Core or Redis, and want job state in a database you own plus a dashboard without a paid tier. Skip it if you need a scheduler outside .NET, or want to register jobs by scanning assemblies at runtime, since registration is compile-time and reflection-free by design.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What TickerQ solves, and who ends up using it
Scheduled work in a .NET service usually arrives as a scatter of hosted services, timers and hand-rolled polling loops. TickerQ replaces that with a single registration call and decorated methods. The README frames the pitch around four properties: source generators at compile time, persistence in a database you already run, a built-in SignalR dashboard, and multi-node coordination through Redis heartbeats and dead-node cleanup.
The audience is narrow and specific. You need to be on .NET, and you need scheduled work that outlives a process restart. A service that fires one timer and forgets about it gains little. A service that needs to know which jobs ran, which failed, and which are still queued gains a great deal, because that state lives in tables you can query directly rather than in an in-memory queue.
The reflection-free claim is the part that separates it from older schedulers. Registration happens at compile time through TickerQ.SourceGenerator, which the README describes as compile-time function registration and lists as its own package. The practical consequence is trimmability and AOT readiness, both stated in the feature table. The cost is that job methods are discovered by the compiler, not by scanning assemblies at startup, so the set of jobs is fixed when you build.
How registration, persistence and the dashboard connect
The mechanism has three layers. At build time, the source generator reads your decorated methods and emits registration code. At startup, AddTickerQ() wires the scheduler into the service container and UseTickerQ() hooks it into the request pipeline. At runtime, a manager writes job records into the configured store, and the engine picks them up for execution.
Persistence is a choice, not a default. TickerQ.EntityFrameworkCore covers PostgreSQL, SQL Server, SQLite and MySQL. TickerQ.Caching.StackExchangeRedis covers Redis and also supplies the distributed coordination the multi-node story depends on. The README's phrasing is that you use your database and there is no separate storage, which matters operationally: backups, migrations and access control already exist for that database.
Multi-node behaviour is described as Redis heartbeats, dead-node cleanup and lock-based coordination, with the instruction to just add instances. That is a design where nodes announce liveness and the system reclaims work from nodes that stop announcing. The README does not document what happens to a job that was mid-execution on a node that died, so treat that as an open question for your own failure testing.
The dashboard is a separate package, TickerQ.Dashboard, and the README points to screenshots on tickerq.net rather than describing the UI in text. It is SignalR-based and described as built-in rather than a paid add-on, which is a deliberate contrast with schedulers that charge for their monitoring layer.
Installing TickerQ and scheduling a first job
The README gives a single install command. Everything else is configuration in your existing application.
dotnet add package TickerQRegister the scheduler on the service collection and hook it into the pipeline. The README's example is a minimal WebApplication and does not show options, so this is the whole of the documented setup.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTickerQ();
var app = builder.Build();
app.UseTickerQ();
app.Run();Jobs are methods decorated with TickerFunction. The attribute takes a name, and the method receives a TickerFunctionContext plus a CancellationToken. The README's sample prints the job id from the context.
using TickerQ.Utilities.Base;
public class MyJobs
{
[TickerFunction("HelloWorld")]
public async Task HelloWorld(
TickerFunctionContext context,
CancellationToken cancellationToken)
{
Console.WriteLine($"Hello from TickerQ! Job ID: {context.Id}");
}
}Scheduling is a manager call. The README injects ITimeTickerManager<TimeTickerEntity> and adds a record with the function name and an execution time. The function string must match the name given to the attribute.
public class MyService(ITimeTickerManager<TimeTickerEntity> manager)
{
public async Task Schedule()
{
await manager.AddAsync(new TimeTickerEntity
{
Function = "HelloWorld",
ExecutionTime = DateTime.UtcNow.AddSeconds(10)
});
}
}Two things to check before this runs in a real application. First, the README notes that all packages are versioned together and that you should always update all packages to the same version, so pin TickerQ and any provider package to the same release. Second, the README does not show how the EF Core provider is registered or how its tables are created, so the persistence setup is a documentation gap you will need to close from the site at tickerq.net.
Where TickerQ is the wrong choice
The compile-time registration model is a real constraint, not a marketing detail. If your jobs are supplied by plugins, loaded from assemblies at runtime, or generated dynamically, a source generator that runs during the build cannot see them. The reflection-free property and dynamic registration are mutually exclusive, and TickerQ has chosen the first.
Multi-node coordination requires Redis. The README ties heartbeats, dead-node cleanup and lock-based coordination to Redis, so a deployment that wants horizontal scheduling but runs only PostgreSQL or SQL Server has a gap the README does not bridge. Redis becomes a second piece of infrastructure regardless of which EF Core provider you picked.
The README does not document rollback, and it does not describe what happens to in-flight work when a node disappears beyond the phrase dead-node cleanup. If your jobs are not idempotent, that silence should stop you before you scale out. A job that charged a card and then lost its node is exactly the case the documentation does not address.
Finally, the ecosystem is .NET only. There is no cross-language client in the package list. A polyglot system that wants one scheduler for Python and .NET services is not what this project is.
TickerQ compared with Hangfire and Quartz.NET
Hangfire is the obvious reference point, and the search data shows people asking about alternatives to it. The difference in approach is registration and storage. Hangfire discovers job methods and serialises calls, and it is commonly deployed with its own storage schema. TickerQ generates registration code at compile time from decorated methods and stores jobs in your EF Core database or Redis. If you want to avoid runtime reflection and keep the job tables inside your existing schema, that is the case for TickerQ. If you rely on enqueuing arbitrary expression trees at runtime, TickerQ's model does not offer that.
Quartz.NET sits at the other end. It is a mature scheduling engine with its own job and trigger abstractions, and it is not tied to a particular persistence story in the same way. TickerQ's differentiator against it is the combination of source generation, an integrated dashboard and the hub for cross-application scheduling. Quartz.NET's advantage is age and the breadth of integrations built around it. Treat this as an architectural comparison rather than a feature audit.
The comparison that matters most is not against either of them. It is against a hosted service with a timer. TickerQ earns its dependency when you need persisted job state, retries with backoff, and visibility into failures. For one periodic cleanup task, it is more machinery than the problem requires.
Versioning, licences and the cost of staying current
Maintenance looks current. The last push to the default branch was on 2026-09-20, and the most recent release listed is v10.3.0 from 2026-04-13, following v10.2.5 and v10.2.4 in March 2026. The repository is not archived. That is a project with recent activity on both the code and the release side.
The upgrade cost is dominated by the versioning rule in the README: all packages are versioned together, and you should always update all packages to the same version. If you use the core package, an EF Core provider, the dashboard and the OpenTelemetry instrumentation, that is four packages moving in lockstep. A single mismatched version is the failure mode the note is warning about. Budget for updating them as a set.
The licence line is the one to read carefully. The README states dual licensing under MIT and Apache 2.0, credited to Arcenox LLC, while the repository metadata reports the licence as NOASSERTION, meaning GitHub could not classify the LICENSE file automatically. Those two statements are not necessarily in conflict, but they are not the same statement either. Read the LICENSE file in the repository root yourself before you ship, and note that contributors are asked to sign a CLA. This is a description of what the files say, not legal advice.
There is also a commercial surface. TickerQ Hub is described as centralized scheduling across applications at hub.tickerq.net, and the project takes funding through OpenCollective. The core scheduler and dashboard are presented as free and without paid add-ons, but the hub is a separate hosted service, so a team that later wants cross-application scheduling should understand what that dependency means before adopting.
Editorial conclusion
Adopt TickerQ if you are on .NET, already run EF Core or Redis, and want job state in a database you own plus a dashboard without a paid tier. Skip it if you need a scheduler outside .NET, or want to register jobs by scanning assemblies at runtime, since registration is compile-time and reflection-free by design. Before committing, verify the LICENSE file for the exact dual-licence terms, confirm that every TickerQ package you install is pinned to the same version, and check which persistence provider covers your database, since the README lists PostgreSQL, SQL Server, SQLite and MySQL under EF Core.
Frequently asked questions
What is TickerQ?
TickerQ is a background task scheduler for .NET. It registers job methods through source generators at compile time, persists jobs in EF Core databases or Redis, supports cron and one-off time-based execution, and includes a real-time SignalR dashboard.
Is TickerQ free?
The README describes the scheduler and the dashboard as built-in with no paid add-ons, and the project is dual licensed under MIT and Apache 2.0. TickerQ Hub, the centralized scheduling service at hub.tickerq.net, is a separate offering, and the repository metadata reports the licence as NOASSERTION, so read the LICENSE file yourself.
How does TickerQ compare with Hangfire and Quartz.NET?
TickerQ registers jobs at compile time through source generators and stores them in your EF Core database or Redis, which is the main contrast with schedulers that rely on runtime reflection or their own storage schema. Quartz.NET is a longer-established scheduling engine with its own job and trigger abstractions, while TickerQ pairs source generation with an integrated dashboard and the hub for cross-application scheduling.
Is TickerQ production ready?
The repository is not archived and the last push to the default branch was on 2026-09-20, with v10.3.0 released on 2026-04-13. The README does not document rollback or what happens to a job that was mid-execution on a node that died, so that behaviour needs testing on your side before you rely on it.
How does TickerQ compare with Quartz.NET?
TickerQ generates job registration at compile time from decorated methods and pairs that with an integrated SignalR dashboard and the hub for cross-application scheduling. Quartz.NET is a longer-established scheduling engine with its own job and trigger abstractions and no equivalent built-in dashboard documented in the TickerQ README.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/arcenox-co-tickerq)