Soenneker.Flywheel.Redis
4.0.4
Prefix Reserved
See the version list below for details.
dotnet add package Soenneker.Flywheel.Redis --version 4.0.4
NuGet\Install-Package Soenneker.Flywheel.Redis -Version 4.0.4
<PackageReference Include="Soenneker.Flywheel.Redis" Version="4.0.4" />
<PackageVersion Include="Soenneker.Flywheel.Redis" Version="4.0.4" />
<PackageReference Include="Soenneker.Flywheel.Redis" />
paket add Soenneker.Flywheel.Redis --version 4.0.4
#r "nuget: Soenneker.Flywheel.Redis, 4.0.4"
#:package Soenneker.Flywheel.Redis@4.0.4
#addin nuget:?package=Soenneker.Flywheel.Redis&version=4.0.4
#tool nuget:?package=Soenneker.Flywheel.Redis&version=4.0.4
Soenneker.Flywheel.Redis
Keep Flywheel jobs in Redis and share the work across app instances. This provider saves jobs, schedules, and logs, and coordinates which worker can update each job.
Why use it?
| Feature | What it does for you |
|---|---|
| Persistent job state | Keep pending jobs and schedules across app restarts, subject to your Redis persistence settings. |
| Worker recovery | Let another worker retry abandoned work after the original worker's ownership expires. |
| Ownership checks | Reject updates from a worker whose ownership has expired or been replaced. |
| Shared limits and priorities | Apply concurrency and rate limits across workers, and select higher-priority jobs first. |
| Duplicate-submission protection | Return the original job ID when the same enqueue key is submitted again. |
| Stored logs and job search | Supply the dashboard with searchable jobs and logs from multiple attempts. |
| Cron schedules | Save calendar schedules with time zones and recover one missed occurrence after downtime. |
| Durable chains | Save all steps together and release each next step in the same transaction that records predecessor success. |
What makes it different?
Coordination uses C# and native Redis transactions, with no Lua scripts. Redis supplies the clock for worker ownership and stored scheduling, so those decisions share one clock across machines. Connections are reused through Soenneker.Redis.Client.
Each namespace keeps related keys in one Redis Cluster slot so job updates can be committed together. Namespaces also let separate apps or environments share a Redis deployment without mixing their jobs.
Setup
Requires Redis 6.0.9 or newer. Reference this project alongside Core and Generators using the Core setup guide.
Usage
Register in your host's Program.cs:
using Soenneker.Flywheel.Core.Registrars;
using Soenneker.Flywheel.Generated;
using Soenneker.Flywheel.Redis;
builder.Services.AddFlywheel()
.AddRedis(options =>
{
options.ConnectionString = "localhost:6379";
options.Namespace = "my-app";
options.HistoryRetention = TimeSpan.FromDays(30);
options.RetainCompletedJobs = true;
})
.AddGeneratedJobs();
Use the same namespace and job registrations on workers that should share jobs. Use different namespaces for separate apps or environments.
Notes
- Enable Redis persistence and set
maxmemory-policytonoevictionso Redis does not evict job data when memory fills up. - Redis failover can lose recent writes. Choose persistence and backups for your needs.
- Aggregate activity is retained for
HistoryRetention(one day by default, from five minutes through 365 days). - With
RetainCompletedJobsenabled, terminal job records and logs are retained for the same period. Disable it to retain only aggregate activity after maintenance processes the terminal job. - Logs keep up to 1,000 entries per job and expire no sooner than 30 days after the last entry; retained jobs use the longer configured history period.
- Stop older workers before upgrading the storage implementation.
- Upgrade every worker before submitting cron schedules or chains. Older workers do not understand cron metadata or release chain successors. Existing interval schedules remain readable.
- Chains contain up to 100 steps. Permanent failure or cancellation cancels the remaining steps; ordinary retries keep them waiting.
Related
Committed change notifications
RedisJobStore implements IJobChangeFeed. Job writes, recurring schedule creation and log appends queue a native Redis PUBLISH inside the same conditional transaction. Known transaction conflicts do not publish changes, and there is no separate process-crash gap between committing data and publishing its notification. Messages contain only a change kind and optional job ID.
Every dashboard node subscribes to its namespace/database channel, then pushes snapshots to its own authenticated SignalR clients. A separate SignalR backplane is not required for these storage notifications. Pub/Sub is not a durable event log: subscriptions emit Resync after establishment/reconnection and on buffer overflow so consumers reread authoritative state. Subscription queues are bounded and disconnected subscriptions are removed.
The Redis account needs PUBLISH, SUBSCRIBE, and UNSUBSCRIBE in addition to the existing read/transaction commands. No Lua was introduced. Upgrade the server and dashboard client together because the old timed invalidation protocol has been removed.
Running count and execution IDs
IJobRunningCountStore.GetRunningCount reads the cardinality of the running index. Claim adds a job; completion, cancellation cleanup, or lease recovery removes it. It includes running jobs outside the current search and chart window. An expired lease can remain in the count until maintenance recovers it. History's Running field has different semantics: it records attempt-start events in a bucket.
New execution IDs are GUIDs in N format, including recurring occurrences. Recurring schedule registration keys remain caller supplied. Existing IDs are preserved, so callers should not reject older IDs that are not GUIDs.
Redis consumes Core, Redis Client, and Redis Semaphores through NuGet. The complete demo lives in the Dashboard repository. Build it against the same package versions that will be deployed.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Soenneker.Cron.Parser (>= 4.0.2)
- Soenneker.Flywheel.Core (>= 4.0.1)
- Soenneker.Redis.Client (>= 4.0.2314)
- Soenneker.Redis.Semaphores (>= 4.0.49)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 5.0.32 | 0 | 9/11/2026 |
| 5.0.31 | 0 | 9/11/2026 |
| 5.0.30 | 0 | 9/11/2026 |
| 5.0.29 | 0 | 9/11/2026 |
| 5.0.28 | 27 | 9/11/2026 |
| 5.0.27 | 37 | 9/11/2026 |
| 5.0.26 | 55 | 9/10/2026 |
| 5.0.25 | 56 | 9/10/2026 |
| 5.0.24 | 60 | 9/10/2026 |
| 5.0.23 | 58 | 9/10/2026 |
| 5.0.22 | 66 | 9/10/2026 |
| 5.0.21 | 75 | 9/9/2026 |
| 5.0.12 | 93 | 9/9/2026 |
| 5.0.8 | 77 | 9/8/2026 |
| 5.0.7 | 79 | 9/8/2026 |
| 5.0.4 | 87 | 9/8/2026 |
| 5.0.3 | 83 | 9/8/2026 |
| 4.0.23 | 70 | 9/8/2026 |
| 4.0.22 | 82 | 9/8/2026 |
| 4.0.4 | 94 | 9/6/2026 |