{"id":13414864,"url":"https://github.com/ZiggyCreatures/FusionCache","last_synced_at":"2025-03-14T22:32:18.771Z","repository":{"id":37588549,"uuid":"325843416","full_name":"ZiggyCreatures/FusionCache","owner":"ZiggyCreatures","description":"FusionCache is an easy to use, fast and robust hybrid cache with advanced resiliency features.","archived":false,"fork":false,"pushed_at":"2025-03-02T19:58:36.000Z","size":7073,"stargazers_count":2642,"open_issues_count":24,"forks_count":123,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-03-05T23:41:45.187Z","etag":null,"topics":["async","cache","cache-stampede","caching","csharp","dotnet","hybrid","hybrid-cache","multi-level","performance","stampede"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ZiggyCreatures.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-31T17:14:11.000Z","updated_at":"2025-03-05T22:39:01.000Z","dependencies_parsed_at":"2023-10-15T09:32:01.340Z","dependency_job_id":"c531d29a-fd5e-4632-9382-5c333de93444","html_url":"https://github.com/ZiggyCreatures/FusionCache","commit_stats":{"total_commits":349,"total_committers":11,"mean_commits":"31.727272727272727","dds":0.03151862464183386,"last_synced_commit":"b1f8522d7ec830b5152a99c766037e458d607b34"},"previous_names":["jodydonetti/ziggycreatures.fusioncache"],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZiggyCreatures%2FFusionCache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZiggyCreatures%2FFusionCache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZiggyCreatures%2FFusionCache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZiggyCreatures%2FFusionCache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ZiggyCreatures","download_url":"https://codeload.github.com/ZiggyCreatures/FusionCache/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243324310,"owners_count":20273104,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","cache","cache-stampede","caching","csharp","dotnet","hybrid","hybrid-cache","multi-level","performance","stampede"],"created_at":"2024-07-30T21:00:38.747Z","updated_at":"2025-03-14T22:32:18.766Z","avatar_url":"https://github.com/ZiggyCreatures.png","language":"C#","readme":"\u003cdiv align=\"center\"\u003e\n\n![FusionCache logo](docs/logo-256x256.png)\n\t\n# FusionCache\n\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache)\n\n\u003c/div\u003e\n\n| 🙋‍♂️ Updating to `v2` ? please [read here](docs/Update_v2_0_0.md). |\n|:-------|\n\n### FusionCache is an easy to use, fast and robust hybrid cache with advanced resiliency features.\n\nIt was born after years of dealing with all sorts of different types of caches: memory, distributed, hybrid, HTTP caching, CDNs, browser cache, offline cache, you name it.\n\nSo I tried to put together these experiences and came up with FusionCache.\n\n\u003cdiv style=\"text-align:center;\"\u003e\n\n![FusionCache diagram](docs/images/diagram.png)\n\n\u003c/div\u003e\n\nBeing a hybrid cache means it can transparently work as either a normal memory cache (L1) or as a multi-level cache (L1+L2), where the distributed 2nd level (L2) can be any implementation of the standard `IDistributedCache` interface: this will get us better cold starts, better horizontal scalability, more resiliency and overall better performance.\n\nFusionCache includes an optional [backplane](docs/Backplane.md) for realtime sync between multiple nodes and advanced resiliency features like [cache stampede](docs/CacheStampede.md) protection, a [fail-safe](docs/FailSafe.md) mechanism, [soft/hard timeouts](docs/Timeouts.md), [eager refresh](docs/EagerRefresh.md), full observability via [logging](docs/Logging.md) and [OpenTelemetry](docs/OpenTelemetry.md), [tagging](docs/Tagging.md) and much more.\n\nIt's being used in production on real-world projects with huge volumes for years, and is even used by Microsoft itself in its products like [Data API Builder](https://devblogs.microsoft.com/azure-sql/data-api-builder-ga/).\n\nIt's also compatible with the new HybridCache from Microsoft, thanks to a [powerful integration](docs/MicrosoftHybridCache.md).\n\n## 🏆 Awards\n\n\u003cdiv align=\"center\"\u003e\n\n![Google OSS Award](docs/google-award-128x128.png)\n\n\u003c/div\u003e\n\nIn 2021 FusionCache received the [Google Open Source Peer Bonus Award](https://twitter.com/jodydonetti/status/1422550932433350666): here is the [official blogpost](https://opensource.googleblog.com/2021/09/announcing-latest-open-source-peer-bonus-winners.html).\n\n## 📕 Getting Started\n\nWith [🦄 A Gentle Introduction](docs/AGentleIntroduction.md) you'll get yourself comfortable with the overall concepts.\n\nWant to start using it immediately? There's a [⭐ Quick Start](#-quick-start) for you.\n\nWhat about each global or entry option? Sure thing, there's an 🎚️ [Options](docs/Options.md) page for that.\n\nCurious about what you can achieve from start to finish? There's a [👩‍🏫 Step By Step ](docs/StepByStep.md) guide.\n\nIn search of all the docs? There's a [page](docs/README.md) for that, too.\n\n## 🧬 Diagrams\n\nSometimes it's nice to be able to visualize the internal flow of a system, even more so for such a complex beast as an hybrid cache like FusionCache.\n\nSo, diagrams!\n\n\u003cdiv align=\"center\"\u003e\n\n[![FusionCache flow diagrams](docs/images/diagrams.png)](docs/Diagrams.md)\n\n\u003c/div\u003e\n\n## 📺 Media\n\nAre you more into videos?\n\nI've been lucky enough to be invited on some shows and podcasts here and there: you can find them in the [Media](docs/Media.md) section.\n\nA good example is when the fine folks at [On .NET](https://learn.microsoft.com/en-us/shows/on-net/) invited me on the show to allow me to mumbling random caching stuff.\n\n\u003cdiv align=\"center\"\u003e\n\n[![On .NET Talk](docs/images/talks/on-dotnet-small.jpg)](https://www.youtube.com/watch?v=hCswI2goi7s)\n\n\u003c/div\u003e\n\n## ✔ Features\n\nFusionCache has a lot of features, let's see them grouped together:\n\n#### Resiliency\n- [**🛡️ Cache Stampede**](docs/CacheStampede.md): automatic protection from the Cache Stampede problem\n- [**💣 Fail-Safe**](docs/FailSafe.md): a mechanism to avoids transient failures, by reusing an expired entry as a temporary fallback\n- [**↩️ Auto-Recovery**](docs/AutoRecovery.md): self-healing for the entire cache, all automatically\n\n#### Performance \u0026 Scalability\n- [**🔀 L1+L2**](docs/CacheLevels.md): any implementation of `IDistributedCache` can be used as an optional 2nd level, all transparently\n- [**📢 Backplane**](docs/Backplane.md): in a multi-node scenario, it can notify the other nodes about changes in the cache, so all will be in-sync\n- [**⏱ Soft/Hard Timeouts**](docs/Timeouts.md): a slow factory (or distributed cache) will not slow down your application, and no data will be wasted\n- [**🦅 Eager Refresh**](docs/EagerRefresh.md): start a non-blocking background refresh before the expiration occurs\n- [**🔂 Conditional Refresh**](docs/ConditionalRefresh.md): like HTTP Conditional Requests, but for caching\n- [**🚀 Background Distributed Operations**](docs/BackgroundDistributedOperations.md): distributed operations can easily be executed in the background, safely, for better performance\n\n#### Flexibility\n- [**📛 Named Caches**](docs/NamedCaches.md): easily work with multiple named caches, even if differently configured\n- [**🏷️ Tagging**](docs/Tagging.md): tags can be associated to entries, to later expire them all at once\n- [**🧼 Clear**](docs/Clear.md): clear an entire cache, even with shared L2, cache key prefix, etc\n- [**Ⓜ️ Microsoft HybridCache**](docs/MicrosoftHybridCache.md): can be used as an implementation of the new HybridCache abstraction from Microsoft, all while adding extra features\n- [**🧙‍♂️ Adaptive Caching**](docs/AdaptiveCaching.md): for when you don't know upfront the entry options (eg: `Duration`), since they depends on the value being cached itself\n- [**🔃 Dependency Injection + Builder**](docs/DependencyInjection.md): native support for Dependency Injection, with a nice fluent interface including a Builder support\n- [**♊ Auto-Clone**](docs/AutoClone.md): be sure that cached values returned can be safely modified\n- [**💫 Fully sync/async**](docs/CoreMethods.md): native support for both the synchronous and asynchronous programming model\n- [**🧩 Plugins**](docs/Plugins.md): extend FusionCache with additional behavior like adding support for metrics, statistics, etc...\n\n#### Observability\n- [**🔭 OpenTelemetry**](docs/OpenTelemetry.md): native observability support via OpenTelemetry\n- [**📜 Logging**](docs/Logging.md): comprehensive, structured and customizable, via the standard `ILogger` interface\n- [**📞 Events**](docs/Events.md): a comprehensive set of events, both at a high level and at lower levels (memory/distributed)\n\nThat was a lot, but not all!\n\n\u003cdetails\u003e\n\t\u003csummary\u003eSomething more 😏 ?\u003c/summary\u003e\n\n\u003cbr/\u003e\n\nAlso, FusionCache has some nice **additional features**:\n\n- **✅ Portable**: targets .NET Standard 2.0, so it can run almost everywhere\n- **✅ High Performance**: FusionCache is optimized to minimize CPU usage and memory allocations to get better performance and lower the cost of your infrastructure all while obtaining a more stable, error resilient application\n- **✅ Null caching**: explicitly supports caching of `null` values differently than \"no value\". This creates a less ambiguous usage, and typically leads to better performance because it avoids the classic problem of not being able to differentiate between *\"the value was not in the cache, go check the database\"* and *\"the value was in the cache, and it was `null`\"*\n- **✅ Circuit-breaker**: it is possible to enable a simple circuit-breaker for when the distributed cache or the backplane become temporarily unavailable. This will prevent those components to be hit with an excessive load of requests (that would probably fail anyway) in a problematic moment, so it can gracefully get back on its feet. More advanced scenarios can be covered using a dedicated solution, like \u003ca href=\"https://github.com/App-vNext/Polly\"\u003ePolly\u003c/a\u003e\n- **✅ Dynamic Jittering**: setting `JitterMaxDuration` will add a small randomized extra duration to a cache entry's normal duration. This is useful to prevent variations of the \u003ca href=\"https://en.wikipedia.org/wiki/Cache_stampede\"\u003eCache Stampede problem\u003c/a\u003e in a multi-node scenario\n- **✅ Cancellation**: every method supports cancellation via the standard `CancellationToken`, so it is easy to cancel an entire pipeline of operation gracefully\n- **✅ Code comments**: every property and method is fully documented in code, with useful informations provided via IntelliSense or similar technologies\n- **✅ Fully annotated for [nullability](https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references)**: every usage of nullable references has been annotated for a better flow analysis by the compiler\n\n\u003c/details\u003e\n\n\n## 📦 Packages\n\nMain packages:\n\n| Package Name                   | Version | Downloads |\n|--------------------------------|:---------------:|:---------:|\n| [ZiggyCreatures.FusionCache](https://www.nuget.org/packages/ZiggyCreatures.FusionCache/) \u003cbr/\u003e The core package | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache) |\n| [ZiggyCreatures.FusionCache.OpenTelemetry](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.OpenTelemetry/) \u003cbr/\u003e Adds native support for OpenTelemetry setup | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.OpenTelemetry.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.OpenTelemetry/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.OpenTelemetry) |\n| [ZiggyCreatures.FusionCache.Chaos](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Chaos/) \u003cbr/\u003e A package to add some controlled chaos, for testing | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Chaos.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Chaos/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Chaos) |\n\nSerializers:\n\n| Package Name                   | Version | Downloads |\n|--------------------------------|:---------------:|:---------:|\n| [ZiggyCreatures.FusionCache.Serialization.NewtonsoftJson](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.NewtonsoftJson/) \u003cbr/\u003e A serializer, based on Newtonsoft Json.NET | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Serialization.NewtonsoftJson.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.NewtonsoftJson/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Serialization.NewtonsoftJson) |\n| [ZiggyCreatures.FusionCache.Serialization.SystemTextJson](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.SystemTextJson/) \u003cbr/\u003e A serializer, based on the new System.Text.Json | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Serialization.SystemTextJson.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.SystemTextJson/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Serialization.SystemTextJson) |\n| [ZiggyCreatures.FusionCache.Serialization.NeueccMessagePack](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.NeueccMessagePack/) \u003cbr/\u003e A MessagePack serializer, based on the most used [MessagePack](https://github.com/neuecc/MessagePack-CSharp) serializer on .NET | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Serialization.NeueccMessagePack.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.NeueccMessagePack/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Serialization.NeueccMessagePack) |\n| [ZiggyCreatures.FusionCache.Serialization.ProtoBufNet](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.ProtoBufNet/) \u003cbr/\u003e A Protobuf serializer, based on one of the most used [protobuf-net](https://github.com/protobuf-net/protobuf-net) serializer on .NET | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Serialization.ProtoBufNet.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.ProtoBufNet/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Serialization.ProtoBufNet) |\n| [ZiggyCreatures.FusionCache.Serialization.CysharpMemoryPack](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.CysharpMemoryPack/) \u003cbr/\u003e A serializer based on the uber fast new serializer by Neuecc, [MemoryPack](https://github.com/Cysharp/MemoryPack) | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Serialization.CysharpMemoryPack.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.CysharpMemoryPack/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Serialization.CysharpMemoryPack) |\n| [ZiggyCreatures.FusionCache.Serialization.ServiceStackJson](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.ServiceStackJson/) \u003cbr/\u003e A serializer based on the [ServiceStack](https://servicestack.net/) JSON serializer | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Serialization.ServiceStackJson.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Serialization.ServiceStackJson/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Serialization.ServiceStackJson) |\n\nBackplanes:\n\n| Package Name                   | Version | Downloads |\n|--------------------------------|:---------------:|:---------:|\n| [ZiggyCreatures.FusionCache.Backplane.Memory](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Backplane.Memory/) \u003cbr/\u003e An in-memory backplane (mainly for testing) | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Backplane.Memory.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Backplane.Memory/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Backplane.Memory) |\n| [ZiggyCreatures.FusionCache.Backplane.StackExchangeRedis](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Backplane.StackExchangeRedis/) \u003cbr/\u003e A Redis backplane, based on StackExchange.Redis | [![NuGet](https://img.shields.io/nuget/v/ZiggyCreatures.FusionCache.Backplane.StackExchangeRedis.svg)](https://www.nuget.org/packages/ZiggyCreatures.FusionCache.Backplane.StackExchangeRedis/) | ![Nuget](https://img.shields.io/nuget/dt/ZiggyCreatures.FusionCache.Backplane.StackExchangeRedis) |\n\nThird-party packages:\n\n| Package Name                   | Version | Downloads |\n|--------------------------------|:---------------:|:---------:|\n| [JoeShook.ZiggyCreatures.FusionCache.Metrics.Core](https://www.nuget.org/packages/JoeShook.ZiggyCreatures.FusionCache.Metrics.Core/)         | [![NuGet](https://img.shields.io/nuget/v/JoeShook.ZiggyCreatures.FusionCache.Metrics.Core.svg)](https://www.nuget.org/packages/JoeShook.ZiggyCreatures.FusionCache.Metrics.Core/) | ![Nuget](https://img.shields.io/nuget/dt/JoeShook.ZiggyCreatures.FusionCache.Metrics.Core) |\n| [JoeShook.ZiggyCreatures.FusionCache.Metrics.EventCounters](https://www.nuget.org/packages/JoeShook.ZiggyCreatures.FusionCache.Metrics.EventCounters/)         | [![NuGet](https://img.shields.io/nuget/v/JoeShook.ZiggyCreatures.FusionCache.Metrics.EventCounters.svg)](https://www.nuget.org/packages/JoeShook.ZiggyCreatures.FusionCache.Metrics.EventCounters/) | ![Nuget](https://img.shields.io/nuget/dt/JoeShook.ZiggyCreatures.FusionCache.Metrics.EventCounters) |\n| [JoeShook.ZiggyCreatures.FusionCache.Metrics.AppMetrics](https://www.nuget.org/packages/JoeShook.ZiggyCreatures.FusionCache.Metrics.AppMetrics/)         | [![NuGet](https://img.shields.io/nuget/v/JoeShook.ZiggyCreatures.FusionCache.Metrics.AppMetrics.svg)](https://www.nuget.org/packages/JoeShook.ZiggyCreatures.FusionCache.Metrics.AppMetrics/) | ![Nuget](https://img.shields.io/nuget/dt/JoeShook.ZiggyCreatures.FusionCache.Metrics.AppMetrics) |\n\n\n## ⭐ Quick Start\n\nJust install the `ZiggyCreatures.FusionCache` Nuget package:\n\n```PowerShell\nPM\u003e Install-Package ZiggyCreatures.FusionCache\n```\n\nThen, let's say we have a method that loads a product from the database:\n\n```csharp\nProduct GetProductFromDb(int id) {\n\t// DATABASE CALL HERE\n}\n```\n\n(This is using the **sync** programming model, but it would be equally valid with the newer **async** one)\n\nThen we create a FusionCache instance:\n\n```csharp\nvar cache = new FusionCache(new FusionCacheOptions());\n```\n\nor, if using [dependency injection](docs/DependencyInjection.md):\n\n```csharp\nservices.AddFusionCache();\n```\n\nNow, to get the product from the cache and, if not there, get it from the database in an optimized way and cache it for `30 sec`:\n\n```csharp\nvar id = 42;\n\ncache.GetOrSet\u003cProduct\u003e(\n\t$\"product:{id}\",\n\t_ =\u003e GetProductFromDb(id),\n\tTimeSpan.FromSeconds(30)\n);\n```\n\nThat's it.\n\n\u003cdetails\u003e\n\t\u003csummary\u003eWant a little bit more 😏 ?\u003c/summary\u003e\n\n\u003cbr/\u003e\n\nWe can also specify some global options, like a default `FusionCacheEntryOptions` object to serve as a default for each call we'll make, with a duration of `2 minutes` and a `Low` priority:\n\n```csharp\nvar cache = new FusionCache(new FusionCacheOptions() {\n\tDefaultEntryOptions = new FusionCacheEntryOptions {\n\t\tDuration = TimeSpan.FromMinutes(2),\n\t\tPriority = CacheItemPriority.Low\n\t}\n});\n```\n\nOr, using DI, like this:\n\n```csharp\nservices.AddFusionCache()\n\t.WithDefaultEntryOptions(new FusionCacheEntryOptions {\n\t\tDuration = TimeSpan.FromMinutes(2),\n\t\tPriority = CacheItemPriority.Low\n\t})\n;\n```\n\nNow, imagine we want to do the same, but also:\n- set the **priority** of the cache item to `High` (mainly used in the underlying memory cache)\n- enable **fail-safe** for `2 hours`, to allow an expired value to be used again in case of problems with the database ([read more](docs/FailSafe.md))\n- set a factory **soft timeout** of `100 ms`, to avoid too slow factories crumbling your application when there's a fallback value readily available ([read more](docs/Timeouts.md))\n- set a factory **hard timeout** of `2 sec`, so that, even if there is no fallback value to use, you will not wait undefinitely but instead an exception will be thrown to let you handle it however you want ([read more](docs/Timeouts.md))\n\nTo do all of that we simply have to change the last line (reformatted for better readability):\n\n```csharp\ncache.GetOrSet\u003cProduct\u003e(\n\t$\"product:{id}\",\n\t_ =\u003e GetProductFromDb(id),\n\t// THIS IS WHERE THE MAGIC HAPPENS\n\toptions =\u003e options\n\t\t.SetDuration(TimeSpan.FromSeconds(30))\n\t\t.SetPriority(CacheItemPriority.High)\n\t\t.SetFailSafe(true, TimeSpan.FromHours(2))\n\t\t.SetFactoryTimeouts(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(2))\n);\n```\n\nBasically, on top of specifying the *cache key* and the *factory*, instead of specifying just a *duration* as a `TimeSpan` we specify a `FusionCacheEntryOptions` object - which contains all the options needed to control the behavior of FusionCache during each operation - in the form of a lambda that automatically duplicates the default entry options defined before (to copy all our defaults) while giving us a chance to modify it as we like for this specific call.\n\nNow let's say we really like these set of options (*priority*, *fail-safe* and *factory timeouts*) and we want them to be the overall defaults, while keeping the ability to change something on a per-call basis (like the *duration*).\n\nTo do that we simply **move** the customization of the entry options where we created the `DefaultEntryOptions`, by changing it to something like this (the same is true for the DI way):\n\n```csharp\nvar cache = new FusionCache(new FusionCacheOptions() {\n\tDefaultEntryOptions = new FusionCacheEntryOptions()\n\t\t.SetDuration(TimeSpan.FromMinutes(2))\n\t\t.SetPriority(CacheItemPriority.High)\n\t\t.SetFailSafe(true, TimeSpan.FromHours(2))\n\t\t.SetFactoryTimeouts(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(2))\n});\n```\n\nNow these options will serve as the **cache-wide default**, usable in every method call as a \"starting point\".\n\nThen, we just change our method call to simply this:\n\n```csharp\nvar id = 42;\n\ncache.GetOrSet\u003cProduct\u003e(\n\t$\"product:{id}\",\n\t_ =\u003e GetProductFromDb(id),\n\toptions =\u003e options.SetDuration(TimeSpan.FromSeconds(30))\n);\n```\n\nThe `DefaultEntryOptions` we did set before will be duplicated and only the duration will be changed for this call.\n\n\u003c/details\u003e\n\n## **👩‍🏫 Step By Step**\nIf you are in for a ride you can read a complete [step by step example](docs/StepByStep.md) of why a cache is useful, why FusionCache could be even more so, how to apply most of the options available and what **results** you can expect to obtain.\n\n\u003cdiv style=\"text-align:center;\"\u003e\n\n![FusionCache diagram](docs/images/stepbystep-intro.png)\n\n\u003c/div\u003e\n\n## 🖥️ Simulator\n\nDistributed systems are, in general, quite complex to understand.\n\nWhen using FusionCache with the [distributed cache](docs/CacheLevels.md), the [backplane](docs/Backplane.md) and [auto-recovery](docs/AutoRecovery.md) the Simulator can help us **see** the whole picture.\n\n[![FusionCache Simulator](https://img.youtube.com/vi/6jGX6ePgD3Q/maxresdefault.jpg)](docs/Simulator.md)\n\n## 🧰 Supported Platforms\n\nFusionCache targets `.NET Standard 2.0` so any compatible .NET implementation is fine: this means `.NET Framework` (the old one), `.NET Core 2+` and `.NET 5/6/7/8+` (the new ones), `Mono` 5.4+ and more (see [here](https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support) for a complete rundown).\n\n**NOTE**: if you are running on **.NET Framework 4.6.1** and want to use **.NET Standard** packages Microsoft suggests to upgrade to .NET Framework 4.7.2 or higher (see the [.NET Standard Documentation](https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support)) to avoid some known dependency issues.\n\n## 🆎 Comparison\n\nThere are various alternatives out there with different features, different performance characteristics (cpu/memory) and in general a different set of pros/cons.\n\nA [feature comparison](docs/Comparison.md) between existing .NET caching solutions may help you choose which one to use.\n\n## 💼 Is it Production Ready :tm: ?\n\nYes!\n\nFusionCache is being used **in production** on **real world projects** for years, happily handling billions of requests.\n\nConsidering that the FusionCache packages have been downloaded more than **10 million times** (thanks everybody!) it may very well be used even more.\n\nOh, and it is being used in products by Microsoft itself, like [Data API Builder](https://devblogs.microsoft.com/azure-sql/data-api-builder-ga/)!\n\n## 💰 Support\n\nNothing to do here.\n\nAfter years of using a lot of open source stuff for free, this is just me trying to give something back to the community.\n\nIf you really want to talk about money, please consider making  **❤ a donation to a good cause** of your choosing, and let me know about that.\n\n## 😍 Are you using it?\n\nIf you find FusionCache useful please [let me know](https://github.com/ZiggyCreatures/FusionCache/discussions/new?category=show-and-tell\u0026title=I%27m%20using%20FusionCache!\u0026body=%23%23%20Scenario%0ADescribe%20how%20you%20are%20using%20FusionCache:%20commercial%20product,%20oss%20project,%20monolith,%20microservice,%20web,%20mobile%20app,%20CLI,%20etc%0A%0A%23%23%20Liked%0AWhat%20you%20liked,%20features,%20docs%20or%20anything%0A%0A%23%23%20Unliked/Missing%0AThings%20you%20didn%27t%20like%20or%20felt%20was%20missing%0A%0A%23%23%20Closing%20Thoughts%0AAny%20closing%20thoughts), I'm  really interested!\n\nThis is the only way for me to know how it is helping people.\n","funding_links":[],"categories":["Caching","csharp","dotnet","C# #","C\\#"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FZiggyCreatures%2FFusionCache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FZiggyCreatures%2FFusionCache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FZiggyCreatures%2FFusionCache/lists"}