Comparison
Milvaion vs Hangfire
and why it isn't either/or
Hangfire is an excellent library and the default answer for background jobs in .NET. Milvaion solves a different problem: what happens when those jobs are spread across a dozen services and nobody can see them all at once.
The short version
Both schedule background jobs in .NET. The difference is where the job actually runs, and how many applications you are trying to keep track of.
Stay on Hangfire if…
- You run one application, or a small handful
- You don't want to operate Redis and RabbitMQ
- You're on .NET Framework or an older TFM
- Jobs are short and in-process execution is fine
- Minimal ops overhead matters more than isolation
Reach for Milvaion if…
- Jobs are scattered across many services
- A long-running job blocks or destabilises your app
- You need workers on different hardware (GPU, high-memory)
- You need audit-grade execution history
- You want multi-step pipelines with branching
Run both if…
- You already have Hangfire in production
- You want visibility before committing to anything
- Migration risk is unacceptable right now
- Different teams picked different schedulers
- You want one dashboard without a rewrite
The architectural difference
Hangfire runs jobs inside your application process, coordinated through your database. Milvaion splits the decision of when a job runs from the process that runs it.
Hangfire
Your app hosts the server. Jobs are picked up from storage by polling and executed on threads inside the same process. Scaling job throughput means scaling the application itself.
Simple to run, few moving parts, and the failure modes are the ones you already understand. A job that leaks memory or blocks for hours affects the host application.
Milvaion
A scheduler API decides when jobs are due using a Redis sorted set, then publishes them to RabbitMQ. Separate worker processes consume and execute them, reporting status and logs back.
More infrastructure to run, but workers scale independently, a crashing job cannot take down the scheduler, and you can route specific job types to specialised hardware.
Feature comparison
Where the two genuinely differ. Both handle the basics - cron scheduling, automatic retries, a dashboard - well.
| Feature | Milvaion | Hangfire |
|---|---|---|
| Execution model | Separate processes | In-process |
| Job dispatch | RabbitMQ | Storage polling |
| Scale execution independently of the app | ||
| Route jobs to specific hardware | ||
| Crashing job can't affect the scheduler | ||
| Built-in dashboard | ||
| Dashboard spans multiple applications | ||
| Real-time log streaming per execution | ||
| DAG workflows with conditional branching | ||
| Multi-channel alerting built in | ||
| OpenTelemetry / Prometheus metrics | ||
| Role-based access control | ||
| Built-in HTTP / SQL / Email workers | ||
| MCP server for AI assistants | ||
| Runs on .NET Framework | ||
| Infrastructure required | PostgreSQL + Redis + RabbitMQ | A database |
| Licence | Apache 2.0 | LGPL v3 + commercial tiers |
| Monitors the other one |
'Partial' means the capability is achievable but needs extra packages, plugins or manual wiring rather than being built in. Hangfire's continuations cover simple job chaining but not conditional branching or merge nodes. Comparison reflects Milvaion 1.1.x and Hangfire 1.8.x - if something here is out of date or unfair, open an issue on GitHub and we'll correct it.
You don't have to choose
Milvaion integrates with Hangfire rather than replacing it. Two lines in Program.cs and every Hangfire job in that application starts reporting into the Milvaion dashboard - without touching your job code.
// Your existing Hangfire setup stays exactly as it is builder.Services.AddMilvaionHangfireIntegration(builder.Configuration); builder.Services.AddHangfire((sp, config) => config.UseMilvaion(sp));
Add monitoring
One package, two registrations. No migration window, no change to job code.
Get visibility
Every Hangfire job appears in one dashboard, flagged as external, with history and alerts.
Migrate selectively, or never
Move only the jobs that outgrow in-process execution. The rest keep running on Hangfire.
Plenty of teams stop at step two, and that is a perfectly good outcome. Milvaion is useful as an observability layer even if you never schedule a single job through it.
Frequently asked questions
Can I use Milvaion and Hangfire together?+
Yes, and for most teams that is the recommended starting point. The Milvasoft.Milvaion.Sdk.Worker.Hangfire package registers a Hangfire filter that reports job registrations and executions to Milvaion over RabbitMQ. Hangfire keeps scheduling and executing the jobs; Milvaion observes them.
Do I have to rewrite my Hangfire jobs to use Milvaion?+
No. The integration requires one NuGet package and two service registrations in Program.cs. Your job classes, triggers, storage and cron expressions stay exactly as they are.
Does Milvaion replace the Hangfire dashboard?+
It complements it. The Hangfire dashboard shows the jobs of a single application. Milvaion aggregates jobs from every application and scheduler into one dashboard, with execution history persisted in PostgreSQL beyond Hangfire's retention window. Jobs owned by Hangfire appear flagged as external, and actions such as trigger and delete stay disabled because Hangfire still owns them.
Is Milvaion free?+
Milvaion is open source under the Apache 2.0 licence, including the dashboard, workflow engine, alerting and role-based access control. Hangfire's core is open source under LGPL v3, while some capabilities such as Redis storage and batches are part of the commercial Hangfire Pro and Ace products.
What infrastructure does Milvaion need?+
PostgreSQL, Redis and RabbitMQ. That is genuinely more moving parts than Hangfire, which needs only a database. If you run a single application on a single server, that overhead is hard to justify and Hangfire is the better choice.
Does Milvaion run on .NET Framework or older .NET versions?+
No. Milvaion targets .NET 10. Hangfire and Quartz.NET support a much wider range of target frameworks including .NET Framework, so for legacy applications they remain the practical option - though you can still add Milvaion monitoring to them from a supported worker process.
See your Hangfire jobs in one dashboard
The integration guide covers configuration, how external jobs behave in the dashboard, and the pre-built Docker images you can use to try it before wiring anything into your own applications.