What is caching and why is it used in system design?
Caching stores frequently used or expensive-to-compute data in a faster location so later requests can be served with less latency and less load on the original data source.
Questions 26-50: Caching, CDN, Queues & Asynchronous Processing.
Open a question for the full answer, code and interview guidance.
Caching stores frequently used or expensive-to-compute data in a faster location so later requests can be served with less latency and less load on the original data source.
Cache-Aside is a common caching pattern in which the application first checks the cache. On a miss, it loads the data from the source, stores the result in the cache, and returns it.
An in-memory cache stores data inside one application process. It is extremely fast but each application instance has its own cache and the data disappears when that process stops.
IMemoryCache is appropriate for data that can be cached independently within each application instance and does not require synchronization across servers. Examples include small reference data, computed values, or short-lived local optimizations.
Use a distributed cache when multiple application instances need access to shared cached data or when cached state should survive the replacement of an individual web server.
Cache invalidation is the process of removing or updating cached data when it is no longer valid. It is one of the most difficult parts of caching because incorrect invalidation can return stale information.
Absolute expiration removes a cache entry after a fixed time measured from creation or a specified timestamp. Sliding expiration extends the lifetime when the entry is accessed, provided it continues to be used.
Cache eviction removes entries to free space or because entries are expired or no longer useful. Eviction may be triggered by expiration, explicit invalidation, memory pressure, or a cache replacement policy.
A cache stampede occurs when many requests simultaneously discover that a popular cache entry is missing or expired and all perform the same expensive operation against the backing system.
Cache penetration occurs when requests repeatedly ask for data that does not exist, causing every request to miss the cache and reach the database or downstream service.
Cache warming preloads selected cache entries before normal traffic needs them. It can reduce cold-start latency for predictable, frequently requested data.
A CDN is a geographically distributed network that caches and serves content from locations closer to users. It is commonly used for static files such as images, JavaScript, CSS, downloads, and video.
Asynchronous processing moves work that does not need to finish within the original request into a separate execution path. The request can acknowledge or record the work while a background processor performs it later.
A message queue stores messages until consumers are able to process them. It decouples producers from consumers in time and can absorb temporary differences between production and processing rates.
Queues reduce direct temporal coupling because the producer does not require the consumer to be available at exactly the same moment. They can buffer bursts, enable independent scaling, and support retries.
A queue commonly represents competing consumers: one logical message is processed by one consumer from a consumer group. Publish-subscribe distributes an event to multiple independent subscribers that each need to react.
At-most-once delivery means a message is delivered zero or one time. The system avoids duplicate delivery, but a message can be lost if a failure occurs before or during processing.
At-least-once delivery retries messages until they are acknowledged or a failure policy is reached. This reduces the risk of message loss but means a consumer may receive the same message multiple times.
Exactly-once processing means the intended business effect occurs once despite failures, retries, or duplicate delivery. Achieving this across distributed components is difficult and often depends on transaction boundaries, idempotency, deduplication, or technology-specific guarantees.
A dead-letter queue stores messages that could not be processed successfully after the configured retry or rejection policy. It prevents one repeatedly failing message from blocking normal processing.
A poison message is a message that repeatedly fails processing because of invalid content, an incompatible schema, an unrecoverable business condition, or a persistent application defect.
Message idempotency ensures that processing the same logical message more than once does not create unintended duplicate business effects.
Some workflows require messages to be processed in a meaningful order, while others do not. Parallel consumers and partitioned brokers can cause messages to complete in a different order from which they were produced.
ASP.NET Core supports long-running hosted work through IHostedService and BackgroundService. These are useful for tasks such as polling, scheduled maintenance, or consuming messages when the work belongs inside the application host.
BackgroundService is normally registered as a singleton, so it should not capture scoped dependencies such as an EF Core DbContext directly through its constructor.