Background Processing with Hangfire
Relevant source files
The following files were used as context for generating this wiki page:
Background processing with Hangfire allows the Resend .NET SDK to send emails asynchronously. This approach improves application reliability by handling transient failures such as network interruptions, provider outages, or rate limits through automatic retries and persistent queues.
In this architecture, the application offloads the email delivery task to a background job, ensuring that the primary request flow remains responsive. Hangfire manages the lifecycle of these jobs, including storage, execution, and error recovery.
Sources: examples/README.md:27-33, examples/AsyncHangfire/README.md:1-4
System Architecture
The Hangfire integration consists of a client that enqueues jobs and a server that processes them. The system uses a persistent storage provider to maintain job state, ensuring durability even if the application restarts.
Components
| Component | Description |
|---|---|
| Hangfire Client | Enqueues background jobs using BackgroundJob.Enqueue. |
| Hangfire Server | Picks up jobs from the queue and executes the job logic. |
| Storage (SQLite) | Persists job data to a database (e.g., z-jobs.db). |
| EmailSendJob | Contains the logic for sending emails via the Resend API. |
| Dashboard | Provides a web UI to monitor and manage background jobs. |
Sources: examples/AsyncHangfire/Program.cs:24-31, examples/AsyncHangfire/README.md:46-51
Execution Flow
The following diagram illustrates the sequence of events when a user initiates an email send request.
Configuration and Setup
To use Hangfire with the Resend SDK, you must configure the necessary services and middleware in the application startup.
Service Registration
Configure Hangfire to use SQLite for job persistence and register the Resend client in the DI container.
// Hangfire Configuration
builder.Services.AddHangfire( cfg =>
{
cfg.SetDataCompatibilityLevel( CompatibilityLevel.Version_180 );
cfg.UseSimpleAssemblyNameTypeSerializer();
cfg.UseRecommendedSerializerSettings();
cfg.UseSQLiteStorage( "z-jobs.db" );
} );
builder.Services.AddHangfireServer();
// Resend Configuration
builder.Services.Configure<ResendClientOptions>( o =>
{
o.ApiToken = Environment.GetEnvironmentVariable( "RESEND_APITOKEN" )!;
} );
builder.Services.AddHttpClient<ResendClient>();
builder.Services.AddTransient<IResend, ResendClient>();
Sources: examples/AsyncHangfire/Program.cs:22-42
Middleware and Dashboard
The Hangfire dashboard is mapped to a specific route to allow monitoring of job progress, retries, and failures.
app.UseHangfireDashboard( "/jobs", new DashboardOptions()
{
DashboardTitle = "Async Hangfire",
DarkModeEnabled = true,
DefaultRecordsPerPage = 20,
} );
Sources: examples/AsyncHangfire/Program.cs:51-56
Job Implementation
The core logic for sending the email resides in the EmailSendJob class. This class uses dependency injection to access the IResend client and logger.
BackgroundSendAsync Method
This method performs the following actions:
- Receives an
EmailMessageobject and aCancellationToken. - Validates and processes any attachments.
- Calls
_resend.EmailSendAsyncto deliver the message. - Logs the resulting Email ID upon success.
Best Practices and Considerations
Payload Size
Hangfire serializes method arguments (the EmailMessage) into JSON strings using TypeConverter. Large objects or complex entities can bloat the job database. It is recommended to keep the payload size small.
Sources: examples/AsyncHangfire/README.md:57-65
Handling Attachments
Avoid using large inline attachments directly in the enqueued EmailMessage. Instead, use the Path property with a special prefix (e.g., load:) and load the actual byte[] content within the background job execution. This prevents large binary data from being stored in the Hangfire database.
Sources: examples/AsyncHangfire/README.md:67-73, examples/AsyncHangfire/Jobs/EmailSendJob.cs:33-43
Error Simulation
For testing purposes, implement ResendMockClient to simulate transient failures. The mock implementation is designed to fail the first two execution attempts, triggering Hangfire's built-in retry mechanism.
Sources: examples/AsyncHangfire/README.md:31-41
Summary
Background processing with Hangfire provides a durable and scalable way to handle email delivery in .NET applications. By offloading requests to a persistent queue, the system ensures that emails are eventually delivered despite transient errors, while maintaining high responsiveness for the end user.