Soenneker.Deduplication.SlidingWindow
4.0.103
Prefix Reserved
See the version list below for details.
dotnet add package Soenneker.Deduplication.SlidingWindow --version 4.0.103
NuGet\Install-Package Soenneker.Deduplication.SlidingWindow -Version 4.0.103
<PackageReference Include="Soenneker.Deduplication.SlidingWindow" Version="4.0.103" />
<PackageVersion Include="Soenneker.Deduplication.SlidingWindow" Version="4.0.103" />
<PackageReference Include="Soenneker.Deduplication.SlidingWindow" />
paket add Soenneker.Deduplication.SlidingWindow --version 4.0.103
#r "nuget: Soenneker.Deduplication.SlidingWindow, 4.0.103"
#:package Soenneker.Deduplication.SlidingWindow@4.0.103
#addin nuget:?package=Soenneker.Deduplication.SlidingWindow&version=4.0.103
#tool nuget:?package=Soenneker.Deduplication.SlidingWindow&version=4.0.103
Soenneker.Deduplication.SlidingWindow
A thread-safe, in-memory “seen recently” set with bucketed expiration and compact XXH3-64 keys.
Installation
dotnet add package Soenneker.Deduplication.SlidingWindow
Usage
using Soenneker.Deduplication.SlidingWindow;
await using var dedupe = new SlidingWindowXxHashDedupe(
window: TimeSpan.FromMinutes(5),
rotationInterval: TimeSpan.FromSeconds(10),
capacityHint: 100_000);
if (dedupe.TryMarkSeen("event:01J..."))
{
// First observation inside the active window.
}
TryMarkSeen returns true when the hash was absent and adds it. A repeat returns false and refreshes that hash into the current time bucket, so it remains present until a full window passes without another observation.
Use Contains for a non-refreshing lookup and TryRemove to make a value immediately eligible again:
bool recentlySeen = dedupe.Contains(eventId);
bool removed = dedupe.TryRemove(eventId);
Window precision
Expiration is bucketed rather than per-item. The bucket count is Ceiling(window / rotationInterval), with a minimum of two buckets. A key therefore expires on a rotation near the configured window boundary, not at an exact timestamp.
Choose a shorter rotation interval for finer expiry precision, at the cost of more buckets and more frequent cleanup. capacityHint sizes the internal dictionary initially; it is not a hard memory limit.
Repeated observations are queued so the implementation can preserve the latest bucket safely. Memory use therefore depends on both unique keys and observation rate; it is not simply eight bytes per unique hash.
Hash representation
Original values are not retained. The string and ReadOnlySpan<char> APIs hash UTF-16 characters, while the Utf8 APIs hash the supplied bytes. Use one representation consistently for mark, lookup, and removal.
Different inputs can theoretically share a 64-bit hash. Use exact keys when collision tolerance is unacceptable.
Lifetime and scope
The instance owns a background rotation task and must be disposed. It is process-local: restarts lose history, and separate application instances do not share it. It is useful for best-effort suppression and reducing repeated work, but it is not an exactly-once or durable idempotency boundary.
| 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.Hashing.XxHash (>= 4.0.89)
- Soenneker.Sets.Concurrent.SlidingWindow (>= 4.0.70)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Soenneker.Deduplication.SlidingWindow:
| Package | Downloads |
|---|---|
|
Soenneker.Deduplication.SlidingWindow.Registry
A keyed registry of sliding window dedupe instances. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.106 | 66 | 9/9/2026 |
| 4.0.105 | 83 | 9/8/2026 |
| 4.0.104 | 95 | 9/8/2026 |
| 4.0.103 | 102 | 9/7/2026 |
| 4.0.102 | 103 | 9/7/2026 |
| 4.0.101 | 101 | 9/7/2026 |
| 4.0.100 | 111 | 9/7/2026 |
| 4.0.99 | 117 | 9/5/2026 |
| 4.0.98 | 135 | 9/4/2026 |
| 4.0.97 | 189 | 8/31/2026 |
| 4.0.96 | 106 | 8/31/2026 |
| 4.0.95 | 108 | 8/31/2026 |
| 4.0.94 | 109 | 8/31/2026 |
| 4.0.93 | 130 | 8/30/2026 |
| 4.0.92 | 99 | 8/30/2026 |
| 4.0.91 | 118 | 8/30/2026 |
| 4.0.90 | 86 | 8/30/2026 |
| 4.0.89 | 96 | 8/29/2026 |
| 4.0.88 | 196 | 8/21/2026 |
| 4.0.87 | 270 | 8/18/2026 |
Updated Soenneker.Hashing.XxHash to 4.0.89