AI prompts
base on 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. # TickerQ
[](https://discord.gg/ZJemWvp9MK)
[](https://www.nuget.org/packages/tickerq)
[](https://www.nuget.org/packages/tickerq)
[](https://github.com/Arcenox-co/TickerQ/actions/workflows/build.yml)
[](https://tickerq.net)
[](https://opencollective.com/tickerq)
**Robust. Adaptive. Precise.**
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.
### 📚 Full Docs: [https://tickerq.net](https://tickerq.net)
> **Repo:** https://github.com/Arcenox-co/TickerQ-UI (docs are open-source and anyone can help us improving.)
> **Note:**
As of v2.2.0, all TickerQ packages are versioned together — even if a package has no changes — to keep the ecosystem in sync. Always update all packages to the same version.
---
## ✨ Features
- **Time and Cron Scheduling**
- **Stateless Core** with source generator
- **EF Core Persistence**
- **Live Dashboard UI**
- **Live Dashboard UI** - [View Screenshots](https://tickerq.net/intro/dashboard-overview.html)
- **Retry Policies & Throttling**
- **Dependency Injection support**
- **Multi-node distributed coordination**
---
## 📦 Installation
### Core (required)
```bash
dotnet add package TickerQ
```
### Entity Framework Integration (optional)
```bash
dotnet add package TickerQ.EntityFrameworkCore
```
### Dashboard UI (optional)
```bash
dotnet add package TickerQ.Dashboard
```
---
## ⚙️ Basic Setup
### In `Program.cs` or `Startup.cs`
```csharp
builder.Services.AddTickerQ(options =>
{
options.SetMaxConcurrency(10);
options.AddOperationalStore<MyDbContext>(efOpt =>
{
efOpt.SetExceptionHandler<MyExceptionHandlerClass>();
efOpt.UseModelCustomizerForMigrations();
});
options.AddDashboard(uiopt =>
{
uiopt.BasePath = "/tickerq-dashboard";
uiopt.AddDashboardBasicAuth();
});
});
...
app.UseTickerQ(); // Activates job processor
```
> 💡 **Recommendation:**
Use `UseModelCustomizerForMigrations()` to cleanly separate infrastructure concerns from your core domain model, especially during design-time operations like migrations.
**Note:** If you're using third-party libraries (e.g., OpenIddict) that also override `IModelCustomizer`, you must either merge customizations or fall back to manual configuration inside `OnModelCreating()` to avoid conflicts.
❗️If Not Using `UseModelCustomizerForMigrations()` You must apply TickerQ configurations manually in your `DbContext`:
```csharp
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Apply TickerQ entity configurations explicitly
builder.ApplyConfiguration(new TimeTickerConfigurations());
builder.ApplyConfiguration(new CronTickerConfigurations());
builder.ApplyConfiguration(new CronTickerOccurrenceConfigurations());
// Alternatively, apply all configurations from assembly:
// builder.ApplyConfigurationsFromAssembly(typeof(TimeTickerConfigurations).Assembly);
}
}
```
## Add Migrations
Migrations would be created for `Context` that is declared at `AddOperationalStore`.
```PM
PM> add-migration "TickerQInitialCreate" -c MyDbContext
```
## Job Definition
### 1. **Cron Job (Recurring)**
```csharp
public class CleanupJobs(ICleanUpService cleanUpService)
{
private readonly ICleanUpService _cleanUpService = cleanUpService;
[TickerFunction(functionName: "CleanupLogs", cronExpression: "0 0 * * *" )]
public async Task CleanupLogs(TickerFunctionContext<string> tickerContext, CancellationToken cancellationToken)
{
var logFileName = tickerContext.Request; // output cleanup_example_file.txt
await _cleanUpService.CleanOldLogsAsync(logFileName, cancellationToken);
}
}
```
> This uses a cron expression to run daily at midnight.
---
Schedule Time Ticker:
```csharp
//Schedule on-time job using ITimeTickerManager<TimeTicker>.
await _timeTickerManager.AddAsync(new TimeTicker
{
Function = "CleanupLogs",
ExecutionTime = DateTime.UtcNow.AddMinutes(1),
Request = TickerHelper.CreateTickerRequest<string>("cleanup_example_file.txt"),
Retries = 3,
RetryIntervals = new[] { 30, 60, 120 }, // Retry after 30s, 60s, then 2min
// Optional batching
BatchParent = Guid.Parse("...."),
BatchRunCondition = BatchRunCondition.OnSuccess
});
```
Schedule Cron Ticker:
```csharp
//Schedule cron job using ICronTickerManager<CronTicker>.
await _cronTickerManager.AddAsync(new CronTicker
{
Function = "CleanupLogs",
Expression = "0 */6 * * *", // Every 6 hours
Request = TickerHelper.CreateTickerRequest<string>("cleanup_example_file.txt"),
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
- If you are building this project locally, you must replace the `$(PackageVersion)` with any version NuGet package version (ideally the latest).
- If you are getting random 403 responses, make sure that you don't have any filter in some endpoint that might be triggering it, thus causing issues with TickerQ's dashboard. Check this [issue](https://github.com/Arcenox-co/TickerQ/issues/155#issuecomment-3175214745) for more details.
---
## 💖 Sponsors & Backers
We want to acknowledge the individuals and organizations who support the development of TickerQ through [OpenCollective](https://opencollective.com/tickerq). Your contributions help us maintain and grow this project. If you'd like to support, check out the tiers below and join the community!
[Become a Sponsor or Backer on OpenCollective](https://opencollective.com/tickerq)
---
### 🏆 Gold Sponsors
*Become a gold sponsor and get your logo here with a link to your site.*
---
### 🥈 Silver Sponsors
*Become a silver sponsor and get your logo here with a link to your site.*
---
### 🥉 Bronze Sponsors
*Become a bronze sponsor and get your logo here with a link to your site.*
---
### 🙌 Backers
[Become a backer](https://opencollective.com/tickerq#backer) and get your image on our README on GitHub with a link to your site.
<a href="https://opencollective.com/tickerq/backer/0/website?requireActive=false" target="_blank"><img width="30" src="https://opencollective.com/tickerq/backer/0/avatar.svg?requireActive=false"></a>
---
## 🤝 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](https://arcenox.com)
You may choose either license to use this software.
", Assign "at most 3 tags" to the expected json: {"id":"14461","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"