Background Jobs with Hangfire & Quartz.NET
Schedule and run background tasks reliably — from simple cleanup routines to complex enterprise job pipelines with persistence and retry logic.
What You'll Learn
- • Built-in
BackgroundServicefor lightweight tasks - • Hangfire: fire-and-forget, delayed, recurring, and continuation jobs
- • Quartz.NET: CRON triggers, job data, and graceful shutdown
- • When to use each approach
⏰ Real-World Analogy
BackgroundService is like a janitor who continuously walks the building cleaning up. Hangfire is like a calendar reminder — you schedule tasks and it runs them, retrying if they fail, with a dashboard showing history. Quartz.NET is like an industrial scheduling system — complex CRON rules, job dependencies, and cluster support for mission-critical workloads.
Built-in BackgroundService
For simple background tasks, .NET's BackgroundService is enough. No external dependencies needed. Great for timed cleanup, queue processors, and health checks.
BackgroundService — Timer & Queue
Build a cleanup timer and email queue processor with BackgroundService.
// ══════════════════════════════════════════════
// Built-in BackgroundService — lightweight option
// ══════════════════════════════════════════════
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
// Simple timed background task
public class CleanupService : BackgroundService
{
private readonly ILogger<CleanupService> _logger;
private readonly IServiceProvider _provider;
public CleanupService(ILogger<CleanupService> logger, IServiceProvider provider)
...Hangfire — Persistent Job Scheduling
Hangfire stores jobs in a database (SQL Server, PostgreSQL, Redis). Jobs survive application restarts, have automatic retry, and come with a built-in dashboard.
Hangfire — Fire & Forget, Recurring, Continuations
Schedule background jobs with Hangfire's fluent API and CRON schedules.
// ══════════════════════════════════════════════
// Hangfire — persistent job scheduling with dashboard
// ══════════════════════════════════════════════
using Hangfire;
using Hangfire.SqlServer;
// Program.cs — Setup
builder.Services.AddHangfire(config => config
.SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(builder.Configuration.GetConnectionString("Hangfire")));
buil
...Quartz.NET — Enterprise Scheduling
Quartz.NET is the most powerful option — complex CRON expressions, job data, misfire handling, and cluster mode for high availability.
Quartz.NET — CRON Jobs & Job Data
Schedule enterprise jobs with CRON triggers and job data parameters.
// ══════════════════════════════════════════════
// Quartz.NET — enterprise-grade job scheduling
// ══════════════════════════════════════════════
using Quartz;
// Define a job
public class InvoiceGenerationJob : IJob
{
private readonly IInvoiceService _invoiceService;
private readonly ILogger<InvoiceGenerationJob> _logger;
public InvoiceGenerationJob(IInvoiceService invoiceService,
ILogger<InvoiceGenerationJob> logger)
{
_invoiceService = invoiceService;
...Pro Tip
Choose wisely: BackgroundService for simple, in-process tasks. Hangfire for most web apps — easy setup, great dashboard, persistent. Quartz.NET when you need advanced scheduling, clustering, or calendar-based triggers.
Common Mistakes
- • Injecting scoped services in BackgroundService without creating a scope — causes runtime errors
- • Not using
stoppingToken— background services don't shut down gracefully - • Complex object parameters in Hangfire — use simple types; Hangfire serializes them to JSON
Lesson Complete!
You've mastered background job scheduling. Next, learn to profile and benchmark your .NET applications for peak performance.
Sign up for free to track which lessons you've completed and get learning reminders.