<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: CSJcode</title>
    <description>The latest articles on Forem by CSJcode (@csjcode).</description>
    <link>https://forem.com/csjcode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F235304%2F4c41c627-459e-4855-9fdf-8a04049105c5.jpg</url>
      <title>Forem: CSJcode</title>
      <link>https://forem.com/csjcode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/csjcode"/>
    <language>en</language>
    <item>
      <title>Ultimate Caching Guide 3: Browser/Chrome</title>
      <dc:creator>CSJcode</dc:creator>
      <pubDate>Tue, 07 Mar 2023 13:25:44 +0000</pubDate>
      <link>https://forem.com/csjcode/ultimate-caching-guide-3-browserchrome-37h1</link>
      <guid>https://forem.com/csjcode/ultimate-caching-guide-3-browserchrome-37h1</guid>
      <description>&lt;p&gt;This article is focused on caching in Chrome Browser. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most of the concepts in this article are applicable to other browsers. &lt;/li&gt;
&lt;li&gt;Chrome is most used and documented so it is a good place to start.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Caching in Chrome is important for performance and reducing latency, bandwidth and memory. It's also useful for offline functionality.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asset/page caching is a major part of Chrome's capabilities, but there are many others you may not know about.&lt;/li&gt;
&lt;li&gt;There are surprising number of obscure ways to cache in Chrome ranging from IndexDB to cookies to Service Workers.&lt;/li&gt;
&lt;li&gt;PWAs (Progressive Web Apps) are a good example of using Service Workers in Chrome for offline functionality. &lt;/li&gt;
&lt;li&gt;Even other specialized applications like Google AMP (Accelerated Mobile Pages) utilize Chrome's caching capabilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before getting into implementation in Chrome, let's look at the basics of HTTP caching and how you can monitor it in Chrome browser.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ultimate Caching Guide Series
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://dev.to/csjcode/ultimate-caching-guide-1-overview-and-strategies-222h"&gt;Ultimate Caching Guide 1: Overview and Strategies&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/csjcode/ultimate-caching-guide-2-javascriptreact-2lie"&gt;Ultimate Caching Guide 2: Javascript/React&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is an ongoing series. I have at least 7 planned.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP Caching and Monitoring Caches in Chrome
&lt;/h2&gt;

&lt;h3&gt;
  
  
  HTTP Caching
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching" rel="noopener noreferrer"&gt;MDN docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some general background about the HTTP caching model, which is the foundation of the browser cache:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Heuristic caching&lt;/strong&gt;: responses are reused if conditions are met. 

&lt;ul&gt;
&lt;li&gt;Although conditions may be made in the Cache-Control http response header, they are not always enforced. Included are directives like "max-age", "no-cache", "no-store", "must-revalidate", "public", "private" and more.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Common header heuristics&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;max-age:&lt;/strong&gt; Specifies the maximum age of the resource in seconds. After this time, the resource should be considered stale and a new copy should be fetched from the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;no-cache:&lt;/strong&gt; Instructs the cache to revalidate the resource with the server before using a cached copy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;no-store:&lt;/strong&gt; Instructs the cache to not store any copies of the resource at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;public:&lt;/strong&gt; Specifies that the resource can be cached by any cache, including intermediate proxies. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;private:&lt;/strong&gt; Specifies that the resource can only be cached by the user's browser and not by any intermediate proxies. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Other headers are used to control caching.

&lt;ul&gt;
&lt;li&gt;Vary (properties of the request that can change the response).&lt;/li&gt;
&lt;li&gt;Validation based other factors such as last modified, ETags, forced revalidation.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Private cache&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;Private cache is a cache tied to a specific client, such as the browser. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Shared cache&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Proxy (gateway) cache&lt;/strong&gt;: a shared cache between clients and servers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed cache&lt;/strong&gt;: CDNs, services deployed by developers to offload the origin server and to deliver content efficiently.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;HTTP can use HTTP caching though is complicated by TLS/SSL extra security measures, which may prevent proper caching..&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  View Cache Data in Chrome
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://developer.chrome.com/docs/devtools/storage/cache/" rel="noopener noreferrer"&gt;https://developer.chrome.com/docs/devtools/storage/cache/&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test if you optimized your page for instant loads when using the browser's back and forward buttons.&lt;/li&gt;
&lt;li&gt;Identify issues that may prevent your page from being eligible for this type of caching&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/docs/devtools/application/back-forward-cache/" rel="noopener noreferrer"&gt;Back-Forward Cache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Also you can use Chrome console commands which you can dig around on to see what's going on with your cache and other settings: &lt;a href="https://www.webnots.com/useful-chrome-url-commands/" rel="noopener noreferrer"&gt;https://www.webnots.com/useful-chrome-url-commands/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Chrome DevTools&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can use the DevTools Network tab to monitor requests and responses and see caching information such as cache hits and misses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open Chrome Dev Tools with "Ctrl+Shift+I" (Windows, Linux) or "Cmd+Opt+I" (Mac), on the Application tab of you can see the Cache Storage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqanu0476pdviqo88y2u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqanu0476pdviqo88y2u.png" alt="Dev Tools Storage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network Tab&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Here you can see the cache status of each request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3d78v0i1q3is3tat38t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3d78v0i1q3is3tat38t.png" alt="Dev Tools Network"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can also disable the cache, if you want to be sure you are not getting cached data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasycgw9n2p85cs7yzqp4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasycgw9n2p85cs7yzqp4.png" alt="DevTools Disable Cache"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can open dev tools and right click the browser's reload button and select "Empty Cache and Hard Reload"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7lkm8t4kyltt0z2o9qr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7lkm8t4kyltt0z2o9qr.png" alt="Empty Cache and Hard Reload"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lighthouse&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open Chrome Dev Tools with "Ctrl+Shift+I" (Windows, Linux) or "Cmd+Opt+I" (Mac) , on the Lighthouse tab of you can analyze your app and get cache -related feedback among other metrics. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lighthouse is an open-source tool that can audit a website's performance, including caching. It provides suggestions for improving caching behavior.&lt;/li&gt;
&lt;li&gt;Serve static assets with an efficient cache policy&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/docs/lighthouse/performance/uses-long-cache-ttl/" rel="noopener noreferrer"&gt;Long Cache TTL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaeceiybw9lqcrd9rmlu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaeceiybw9lqcrd9rmlu.png" alt="Lighthouse Cache"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2wv8i9hqstjczsosclb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2wv8i9hqstjczsosclb.png" alt="Lighthouse Service Worker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Chrome browser url input: chrome://serviceworker-internals&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This page provides information about registered service workers and their cache storage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgpkt52jwd7jih47prbf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgpkt52jwd7jih47prbf.png" alt="ServiceWorker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other possible ways to checking Caching from the browser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google Analytics&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;Google Analytics can be used to track cache hits and misses by setting up custom events and tracking them in the Analytics dashboard.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Chrome extensions:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;There are several Chrome extensions available that can provide more detailed information about caching, such as "Cache Killer" and "Clear Cache."&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Command Line:&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;You can use the Chrome command line to view detailed caching information, such as cache size and usage, by running the command "chrome://net-internals/#httpCache" or chrome://net-internals/#dns in the Chrome address bar. &lt;a href="https://www.minitool.com/news/chrome-urls.html" rel="noopener noreferrer"&gt;List of shortcuts&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Types of Caching in Chrome
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Memory Caching /  HTTP (browser) Cache
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Caching that temporarily stores and retrieves web page resources, such as HTML, CSS, JavaScript, and images, in memory for faster access. &lt;/li&gt;
&lt;li&gt;The Page (browser) Cache may store in memory and/or disk depending on the assets.&lt;/li&gt;
&lt;li&gt;Managed by the browser's networking layer &lt;/li&gt;
&lt;li&gt;"Ctrl+Shift+I" (Windows, Linux) or "Cmd+Opt+I" (Mac) + NETWORK tab. Click on the "Network" tab.&lt;/li&gt;
&lt;li&gt;Used along with other types of caches like disk and service worker caches.&lt;/li&gt;
&lt;li&gt;When a user visits a website, the browser initiates a request to fetch the web page and its resources. &lt;/li&gt;
&lt;li&gt;If the resource is not in the memory cache, the browser fetches the resource from the network and stores it in the cache for faster access in the future. &lt;/li&gt;
&lt;li&gt;The cache uses a Least Recently Used (LRU) algorithm to determine which resources to evict from memory when the cache becomes full.&lt;/li&gt;
&lt;li&gt;Faster than disk-based caches because it doesn't require the time to read and write data to disk.&lt;/li&gt;
&lt;li&gt;Limited size (can be modified by the user) and can quickly fill up with frequently used resources.&lt;/li&gt;
&lt;li&gt;Checks HTTP headers to control cache behavior. For example, the Cache-Control header can be used to set the maximum age of a resource in the cache.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disk Caching / HTTP (browser) Cache
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Website assets, such as HTML files, CSS stylesheets, JavaScript files, images, and other resources, and stores them in the disk cache. &lt;/li&gt;
&lt;li&gt;When users revisit the site, the browser checks the disk cache to see if the assets are already stored there, and if so, it retrieves them from the cache instead of downloading them again.&lt;/li&gt;
&lt;li&gt;Chrome Disk Cache works in conjunction with the Memory Cache.&lt;/li&gt;
&lt;li&gt;The Chrome Disk Cache uses Least Recently Used (LRU) algorithm to determine which resources to evict from the cache when it becomes full.&lt;/li&gt;
&lt;li&gt;HTTP headers are also used on this like the memory cache.&lt;/li&gt;
&lt;li&gt;Devs could use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage" rel="noopener noreferrer"&gt;LocalStorage&lt;/a&gt; for caching as well, and Session Storage may be either in memory or disk.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage" rel="noopener noreferrer"&gt;SessionStorage&lt;/a&gt; uses disk caching.&lt;/li&gt;
&lt;li&gt;IndexDB and WebSQL are also disk based.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Page Cache
&lt;/h3&gt;

&lt;p&gt;The difference of the Page cache and Browser cache is a bit confusing. &lt;/p&gt;

&lt;p&gt;There are 2 different methods in the Chrome API under "chrome.browsingData" to clear each (remove and removeCache). Although the examples given don't specify much of the difference (in the code itself). Some I'm going to leave this section general for now, just noting the difference.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Page Cache caches the entire rendered content of a web page, including its HTML, CSS, and JavaScript, as well as any data fetched by the page through APIs or other means. &lt;/li&gt;
&lt;li&gt;The Page Cache is stored separately from the regular browser cache.&lt;/li&gt;
&lt;li&gt;It's only used for pages that have been visited recently or frequently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Back/forward cache
&lt;/h3&gt;

&lt;p&gt;Back/forward cache differs from browser cache and HTTP cache.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.chrome.com/docs/devtools/application/back-forward-cache/" rel="noopener noreferrer"&gt;Back-Forward Cache&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Back-Forward Cache is different from the regular browser cache in that it only stores pages that the user has visited during the current browsing session, and it is optimized for quick access to those pages. &lt;/li&gt;
&lt;li&gt;It is also different from the Page Cache, which is used to cache pages that are opened from links in new tabs.

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Cache" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Cache&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cookies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Cookies can be used to store data in the browser cache.&lt;/li&gt;
&lt;li&gt;Cookies can be set to expire after a certain time, or  when the browser is closed (session cookie).&lt;/li&gt;
&lt;li&gt;The topic of cookies is covered in more detail here: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies" rel="noopener noreferrer"&gt;Cookies&lt;/a&gt; article.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Service Worker Cache
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Service workers intercept network requests and cache responses in the browser (see code below in Cache Storage API section).&lt;/li&gt;
&lt;li&gt;They can be used offline or on a slow internet connection.&lt;/li&gt;
&lt;li&gt;Steps to implementation:

&lt;ul&gt;
&lt;li&gt;Register a Service Worker using the navigator.serviceWorker.register() method.&lt;/li&gt;
&lt;li&gt;Implement the caching logic in the fetch event listener of the Service Worker. With an event listener, you can intercept requests made by the browser and cache the responses.&lt;/li&gt;
&lt;li&gt;Use the Cache API provided by the Service Worker. The Cache API provides methods like cache.addAll() and cache.match() to add and retrieve responses from the cache.&lt;/li&gt;
&lt;li&gt;You can see Service Workers as listed aboe in the article in Chrome DevTools in the Application panel.&lt;/li&gt;
&lt;li&gt;Cache versioning and expiration should also be implemented to ensure that the cache is updated when the service worker is updated.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Web Workers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Web Workers operate independently of the main thread of the web page&lt;/li&gt;
&lt;li&gt;They use a similar mechanism of caching as the page cache, however this can be customized by the developer.&lt;/li&gt;
&lt;li&gt;Stored in memory cache or disk cache, depending on the size and type of data being cached.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cache Storage API
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage" rel="noopener noreferrer"&gt;The Cache Storage API&lt;/a&gt; is a newer API that allows developers to cache network resources programmatically. It provides more control over caching behavior and allows for more advanced caching strategies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caching of HTTP responses: Developers cache HTTP responses.&lt;/li&gt;
&lt;li&gt;Support for different cache strategies.&lt;/li&gt;
&lt;li&gt;Separation of caches: You can create multiple caches with different names, to keep different types of resources separate. For example, create a cache for images and another for scripts.&lt;/li&gt;
&lt;li&gt;Management of cache entries: The API provides methods for adding, retrieving, and deleting cache entries. Developers can also set expiration times for entries or update them if the original resource has changed.&lt;/li&gt;
&lt;li&gt;Programmatic caching: The API allows developers to cache resources programmatically, which can be useful for pre-caching resources that are likely to be needed in the future or for updating the cache in the background.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define the name of the cache&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CACHE_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-static-cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define the URLs of the files to cache&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;urlsToCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/styles.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/script.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/images/logo.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Install the service worker and cache the static assets&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;install&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CACHE_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;urlsToCache&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Serve cached files if available, otherwise fetch them from the network&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Push Cache
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Used for push notifications in Chrome. When a user receives a push notification, Chrome stores the resource in the push cache so that it can be quickly accessed if the user wants to view it.&lt;/li&gt;
&lt;li&gt;Separate from the browser's regular cache and is only available for the lifetime of a single session.&lt;/li&gt;
&lt;li&gt;The server sends the resources along with a PUSH_PROMISE frame to the client, which tells the browser to cache the resources in the Push Cache. &lt;/li&gt;
&lt;li&gt;The browser then stores the resources in the Push Cache and can retrieve them without making a request to the server.&lt;/li&gt;
&lt;li&gt; HTTP/2 Push is required to use the Push Cache. &lt;/li&gt;
&lt;li&gt;Monitor the Push Cache using the Chrome DevTools in the Application tab and select Push Cache. You can also use the Performance panel to see the requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DNS Cache
&lt;/h3&gt;

&lt;p&gt;Chrome stores recently resolved DNS queries in a cache to reduce the time it takes to resolve domain names.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DNS prefetching&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;By including the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ" rel="noopener noreferrer"&gt;dns-prefetch &lt;/a&gt; link relation in your HTML code, you can instruct the browser to resolve DNS records for a domain in advance, before the user clicks on a link to that domain. This can help reduce latency and improve page load times.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;My Website&amp;lt;/title&amp;gt;
  &amp;lt;link rel="dns-prefetch" href="//example.com"&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;h1&amp;gt;Welcome to My Website&amp;lt;/h1&amp;gt;
  &amp;lt;p&amp;gt;This is an example of how to use the dns-prefetch link tag.&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add a dns-prefetch link tag to the head section of the HTML document. &lt;/li&gt;
&lt;li&gt;The href attribute specifies the domain name we want to pre-resolve, in this case, example.com.&lt;/li&gt;
&lt;li&gt;**preconnect: **This option allows the browser to set up an early connection to a domain before the user requests any resources from it. This can reduce the latency of establishing a new connection and improve page loading speed.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="preconnect" href="https://example.com"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;prefetch:&lt;/strong&gt; This option allows the browser to fetch and cache a resource in advance, before the user requests it. This can improve page loading speed by reducing the time it takes to fetch the resource when the user requests it.
*
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="prefetch" href="https://example.com/styles.css"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;prerender:&lt;/strong&gt; This option allows the browser to pre-render a web page in the background, before the user requests it. This can improve page loading speed by pre-rendering the page's HTML, CSS, and JavaScript, and making it available immediately when the user requests it.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="prerender" href="https://example.com/page.html"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See more on preconnect, prefetch, and prerender in the &lt;a href="https://web.dev/preconnect-and-dns-prefetch/" rel="noopener noreferrer"&gt;Link prefetching&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS and SSL/TLS certificates&lt;/strong&gt;: When a user visits a website with a valid SSL/TLS certificate, Chrome will cache the certificate for a certain period of time. This helps to speed up subsequent visits to the same site, as the browser does not need to download the certificate again. However, if the certificate is invalid or has expired, Chrome will not cache it and will require a new certificate to be downloaded.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Font Cache
&lt;/h3&gt;

&lt;p&gt;The Font Cache is a specialized cache used to store font data. It caches font files downloaded so that they can be reused across different web pages on the same site. This helps improve performance by reducing the number of requests needed to download font files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Data Cache
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Form data can be saved in local storage and autofilled.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Plugin caching
&lt;/h3&gt;

&lt;p&gt;Chrome caches plugin content like Flash and Java to speed up the loading of multimedia content on web pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  AMP
&lt;/h3&gt;

&lt;p&gt;AMP (Accelerated Mobile Pages) is not specifically designed for caching, but it does use caching as a key component of its optimization strategy at several levels to speed up the delivery of content on mobile devices. Some of the caching is done by the browser, while other parts are done by the AMP Cache a global Google CDN. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AMP uses a service worker to cache the content on the user's device. &lt;/li&gt;
&lt;li&gt;When a user visits an AMP page, the Chrome browser may display a lightning bolt icon in the address bar, indicating that the page is an AMP page and has been cached by the AMP Cache. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other useful pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.mnot.net/cache_docs/" rel="noopener noreferrer"&gt;Web caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching" rel="noopener noreferrer"&gt;HTTP caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/http-cache/" rel="noopener noreferrer"&gt;HTTP Caching more, examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/learn/pwa/caching/" rel="noopener noreferrer"&gt;PWA Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Cache" rel="noopener noreferrer"&gt;Service Worker API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control" rel="noopener noreferrer"&gt;Cache-Control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers" rel="noopener noreferrer"&gt;Using Service Workers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API" rel="noopener noreferrer"&gt;Web Storage API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Ultimate Caching Guide 2: Javascript/React</title>
      <dc:creator>CSJcode</dc:creator>
      <pubDate>Mon, 27 Feb 2023 04:12:57 +0000</pubDate>
      <link>https://forem.com/csjcode/ultimate-caching-guide-2-javascriptreact-2lie</link>
      <guid>https://forem.com/csjcode/ultimate-caching-guide-2-javascriptreact-2lie</guid>
      <description>&lt;p&gt;This article is focused on caching in Javascript and React. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most of the concepts in this article are applicable to other languages and frameworks. &lt;/li&gt;
&lt;li&gt;Javascript is familiar to many and intertwined with the browser caching APIs, so it is a good place to start.&lt;/li&gt;
&lt;li&gt;In this article, I am not going into too much detail on browser cache-related APIs and will leave that to a future article. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also see: &lt;br&gt;
&lt;a href="https://dev.to/csjcode/ultimate-caching-guide-1-overview-and-strategies-222h"&gt;Ultimate Caching Guide 1: Overview and Strategies&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Javascript caching
&lt;/h2&gt;

&lt;p&gt;Using caching techniques at the application level can improve performance and reduce the load on the server. &lt;/p&gt;

&lt;p&gt;There are a number of caching methods available to Javascript developers to improve performance.&lt;/p&gt;
&lt;h3&gt;
  
  
  Closure caching
&lt;/h3&gt;

&lt;p&gt;Returning a closure from a function that caches the result of a computation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculateSum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculateSum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Output: 2&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Output: 6&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Output: 6 (cached value)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Output: 11&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Output: 11 (cached value)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data Structure Caching
&lt;/h3&gt;

&lt;p&gt;Similar caching can be done with various data structures, such as arrays, objects, Maps, Sets, etc.&lt;/p&gt;

&lt;p&gt;Basic object cache, usually placed inside a function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getFromCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addToCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;complexCalculation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nf"&gt;addToCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mathResult&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;complexCalculation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getFromCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mathResult&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Output: '0.12392517788687459'&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;Set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cachedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Data is cached&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// fetchData(data)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cachedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cachedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Memoization
&lt;/h3&gt;

&lt;p&gt;Object caching is focused on the data structures used by a program, while memoization is focused on the results of a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;memoize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Returning from cache...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;expensiveComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Performing expensive computation...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;memoizedComputation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memoize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expensiveComputation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;memoizedComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Performing expensive computation... 5&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;memoizedComputation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// 5 (returned from cache)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Memory-based Storage API (eg. SessionStorage)
&lt;/h3&gt;

&lt;p&gt;It's simple and straightforward to use the Storage API to cache data in the browser.&lt;/p&gt;

&lt;p&gt;SessionStorage and LocalStorage are similar in terms of functionality, but LocalStorage persists data across browser sessions. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there is a separate sessionStorage for each tab or window.&lt;/li&gt;
&lt;li&gt;When the tab or window is closed, the web browser ends the session and clears sessionStorage.&lt;/li&gt;
&lt;li&gt;it's specific to the protocol of the page.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Store data in SessionStorage&lt;/span&gt;
&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="c1"&gt;// Retrieve data from SessionStorage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Disk-based (LocalStorage, IndexDB)
&lt;/h3&gt;

&lt;p&gt;LocalStorage is a key-value store persisting data across browser sessions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Storage" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Storage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IndexDB is a more complex API for storing data in the browser and allows more complex querying and indexing of structured data. It can store data in different formats, including binary data, and provides asynchronous APIs for better performance. IndexedDB is asynchronous, while LocalStorage is synchronous.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SessionStorage is cleared when the browser is closed. LocalStorage is cleared when the user clears their browser cache.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cacheKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cachedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cachedData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Data is not in cache, fetch it from the server&lt;/span&gt;
  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/my/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Cache the response data&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Use cached data&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Using cached data:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cachedData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  WebWorker
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/learn/pwa/caching/" rel="noopener noreferrer"&gt;https://web.dev/learn/pwa/caching/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WebWorkers can be used for background caching and to store data in memory, basically non-blocking interaction with the app's main thread with 'postMessage'. Also it can be used for offline functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Listen for requests from the main thread&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cacheKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Check if the data is cached in localStorage&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cachedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cachedData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// If cached data is found, send the data back to the main thread&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cachedData&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// If cached data is not found, fetch the data from the API&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Store the fetched data in localStorage for future use&lt;/span&gt;
        &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="c1"&gt;// Send the fetched data back to the main thread&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If an error occurs, send an error message back to the main thread&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Service Worker
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/offline-cookbook/#serving-suggestions" rel="noopener noreferrer"&gt;https://web.dev/offline-cookbook/#serving-suggestions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/jonchen/service-worker-caching-and-http-caching-p82"&gt;https://dev.to/jonchen/service-worker-caching-and-http-caching-p82&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/service-worker-lifecycle/" rel="noopener noreferrer"&gt;https://web.dev/service-worker-lifecycle/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://create-react-app.dev/docs/making-a-progressive-web-app/#offline-first-considerations" rel="noopener noreferrer"&gt;https://create-react-app.dev/docs/making-a-progressive-web-app/#offline-first-considerations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Network Only, Network first, then cache, Stale-While-Revalidate, Cache First,fall back to network, Cache Only &lt;/p&gt;

&lt;p&gt;The Service Worker is a bit more versatile than the WebWorker and will cache the specified files when it is installed, and intercept fetch requests to return cached responses if available. It will also clean up old caches when the new version of the Service Worker is activated. &lt;/p&gt;

&lt;p&gt;You can think of it like a local reverse proxy server that intercepts requests and returns cached responses if available.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Install the Service Worker and cache some files&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;install&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addAll&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/styles.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/script.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/image.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Intercept fetch requests and return cached responses if available&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Clean up old caches when activating the new version of the Service Worker&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;activate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheNames&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;cacheNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cacheName&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Libraries
&lt;/h3&gt;

&lt;h4&gt;
  
  
  lru-cache
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/lru-cache" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/lru-cache&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;provides a caching mechanism with a least recently used (LRU) eviction policy.&lt;/li&gt;
&lt;li&gt;The LRU policy means that when the cache reaches its maximum size, the least recently used items are removed from the cache to make room for new items. &lt;/li&gt;
&lt;li&gt;Optimize memory usage and performance by ensuring that the most frequently accessed items remain in the cache, while less frequently accessed items are evicted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  node-cache-manager
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/cache-manager" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/cache-manager&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  React (other SPAs have similar options)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Memoization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React provides a built-in utility called React.memo() that can be used to memoize functional components. However, modern usage of React Hooks makes it easier and is the common usage.&lt;/li&gt;
&lt;li&gt;useMemo&lt;/li&gt;
&lt;li&gt;useCallback &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A code example is below:&lt;/p&gt;

&lt;p&gt;The two hooks are similar, but they have different use cases. useMemo is used to memoize the result of a function, while useCallback is used to memoize the function itself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;useMemo is used to memoize the result of the calculateSum function.&lt;/li&gt;
&lt;li&gt;useCallback is used to memoize the calculateSum function. The calculateSum function will only be re-created if one of these values changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By using useCallback and useMemo, we're able to optimize our code and avoid unnecessary re-renders.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNum1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNum2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calculateSum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Calculating sum...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;calculateSum&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;calculateSum&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setNum1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setNum2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Query caching
&lt;/h3&gt;

&lt;p&gt;Another important React caching technique is query caching. Query caching is used to store the results of a query so that the query doesn't have to be executed again if the same query is made. This can be useful for reducing the number of API requests made to a server.&lt;/p&gt;

&lt;p&gt;Most popular libraries have their own query caching mechanism. &lt;/p&gt;

&lt;p&gt;This chart shows some of the varieties available:&lt;br&gt;
&lt;a href="https://redux-toolkit.js.org/rtk-query/comparison" rel="noopener noreferrer"&gt;https://redux-toolkit.js.org/rtk-query/comparison&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caching in Apollo Client 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.apollographql.com/docs/react/caching/overview/" rel="noopener noreferrer"&gt;https://www.apollographql.com/docs/react/caching/overview/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TanStack Query/React Query QueryCache

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tanstack.com/query/latest" rel="noopener noreferrer"&gt;https://tanstack.com/query/latest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react-query-v3.tanstack.com/reference/QueryCache" rel="noopener noreferrer"&gt;https://react-query-v3.tanstack.com/reference/QueryCache&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RTK Query - Redux Toolkit 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redux-toolkit.js.org/rtk-query/usage/cache-behavior" rel="noopener noreferrer"&gt;https://redux-toolkit.js.org/rtk-query/usage/cache-behavior&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SWR - React Hooks for Data Fetching

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://swr.vercel.app/" rel="noopener noreferrer"&gt;https://swr.vercel.app/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  PureComponent (deprecated, but still in some codebases)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;PureComponent is a subclass of the React.Component that implements a shallow comparison of props and state to determine if a re-render is necessary. This can improve performance by preventing unnecessary re-renders.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://beta.reactjs.org/reference/react/PureComponent" rel="noopener noreferrer"&gt;https://beta.reactjs.org/reference/react/PureComponent&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  React.lazy() and Suspense
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React.lazy() is a newer feature introduced in React 16.6 that allows for lazy loading of components. Suspense is a component that allows you to handle loading states and fallbacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's mainly use for code-splitting, but could facilitate caching since it dynamically loads components of code and stores in memory to be re-used in other components.&lt;/p&gt;
&lt;h3&gt;
  
  
  Context API
&lt;/h3&gt;

&lt;p&gt;The Context API provides a way to pass data through the component tree without having to pass props down manually at every level.&lt;/p&gt;

&lt;p&gt;By using context, we are effectively caching props and can avoid unnecessary re-renders and improve performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define a context with a default value&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// A component that uses the context&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Get the value of the context using useContext hook&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contextValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Context&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;contextValue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// A parent component that provides the context value&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/MyContext.Provider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Next.js and Server-side rendering
&lt;/h3&gt;

&lt;p&gt;Server-side rendering is the process of rendering the initial HTML and React components on the server before sending it to the client. This can improve performance by reducing the time it takes for the client to receive and render the content.&lt;/p&gt;

&lt;p&gt;Next.js provides several built-in caching mechanisms that allow pages to be cached in memory or on disk, reducing the need to re-render pages for subsequent requests.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Static file caching: there are static files for each page served directly from disk for subsequent requests. These files are cached in memory by default, and can also be cached by a reverse proxy server or CDN.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Incremental Static Regeneration (ISR): Next.js supports a feature called ISR, which allows pages to be revalidated and regenerated incrementally at a specified interval or on demand. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration" rel="noopener noreferrer"&gt;https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Server-side rendering (SSR) caching: Next.js provides an API for caching the output of server-side rendering (SSR) for a given request. Cache-control headers can be used to control how long the cached output is valid for. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/api-reference/next.config.js/headers#cache-control" rel="noopener noreferrer"&gt;https://nextjs.org/docs/api-reference/next.config.js/headers#cache-control&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Memory caching: Next.js provides an in-memory cache that can be used to store arbitrary data, such as database queries or API responses.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;ETags: Next.js supports the use of HTTP ETags to cache responses from the server. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/api-reference/next.config.js/disabling-etag-generation" rel="noopener noreferrer"&gt;https://nextjs.org/docs/api-reference/next.config.js/disabling-etag-generation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Minimum Cache TTL&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/api-reference/next/image#minimum-cache-ttl" rel="noopener noreferrer"&gt;https://nextjs.org/docs/api-reference/next/image#minimum-cache-ttl&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Memoized selectors
&lt;/h3&gt;

&lt;p&gt;Redux is a popular state management library used with React.&lt;/p&gt;

&lt;p&gt;Memoized selectors are functions that compute derived data from the Redux store (stored state data in memory). &lt;/p&gt;

&lt;p&gt;Redux and RTK provide built-in support for memoized selectors through the reselect library - &lt;a href="https://github.com/reduxjs/reselect" rel="noopener noreferrer"&gt;https://github.com/reduxjs/reselect&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By memoizing these functions, you can avoid re-computing the same data over and over again.&lt;/p&gt;

&lt;p&gt;This is basically extending memoization to the Redux framework and state management data structures.&lt;/p&gt;




&lt;p&gt;We've looked at how caching can be used at the application level in Javascript and React to improve performance.&lt;/p&gt;

&lt;p&gt;There are quite a few choices to make when it comes to caching, and it's important to understand the tradeoffs and use cases for each. &lt;/p&gt;

&lt;p&gt;Some like useMemo and useCallback are used to optimize the performance of React components.&lt;/p&gt;

&lt;p&gt;Others like Apollo Client and React Query are used to cache API requests and reduce the number of requests made to a server.&lt;/p&gt;

&lt;p&gt;While some like Next.js and SSR are used to cache the output of server-side rendering.&lt;/p&gt;

&lt;p&gt;Also, in the first article in this series we already examined some of the main caching patterns which can be applied across all types of services.&lt;/p&gt;

&lt;p&gt;Next article we'll continue to trace our caching options through the cloud and into large-scale distributed systems.&lt;/p&gt;

&lt;p&gt;Also see: &lt;br&gt;
&lt;a href="https://dev.to/csjcode/ultimate-caching-guide-1-overview-and-strategies-222h"&gt;Ultimate Caching Guide 1: Overview and Strategies&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/csjcode/150-solutions-architect-metricscalculations-cheatsheet-4m40"&gt;150+ Solutions Architect metrics/calculations cheatsheet&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Ultimate Caching Guide 1: Overview and Strategies</title>
      <dc:creator>CSJcode</dc:creator>
      <pubDate>Mon, 27 Feb 2023 03:08:15 +0000</pubDate>
      <link>https://forem.com/csjcode/ultimate-caching-guide-1-overview-and-strategies-222h</link>
      <guid>https://forem.com/csjcode/ultimate-caching-guide-1-overview-and-strategies-222h</guid>
      <description>&lt;p&gt;Caching is a technique in the Dev toolbox that can work some "magic" to resolve scalability challenges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caching:&lt;/strong&gt; storing frequently accessed or computationally expensive data in a temporary storage area, often closer in space/time to the requester.&lt;/p&gt;

&lt;p&gt;A software or hardware component that does this is a cache and there are local or remote methods to accomplish this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Potential app benefits from caching&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;better performance,&lt;/li&gt;
&lt;li&gt;better reliability,&lt;/li&gt;
&lt;li&gt;less resources required,&lt;/li&gt;
&lt;li&gt;less resources may reduce cost/complexity,&lt;/li&gt;
&lt;li&gt;decreasing latency and user-perceived lag,&lt;/li&gt;
&lt;li&gt;increasing resilience/uptime,&lt;/li&gt;
&lt;li&gt;extending existing capabilities,&lt;/li&gt;
&lt;li&gt;improving usability.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This article is a high-level introduction.  &lt;/p&gt;

&lt;p&gt;In future articles we will explore implementation in great detail from pure Javascript code to React to CDNs, microservices, APIs and databases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is caching important?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What are some major caching patterns we should know about? &lt;/p&gt;

&lt;h3&gt;
  
  
  🛠 Implementation
&lt;/h3&gt;

&lt;p&gt;Implementation of caching is interesting for a few reasons...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ubiquitous&lt;/strong&gt;. 

&lt;ul&gt;
&lt;li&gt;We have many areas of the application ecosystem to implement it. &lt;/li&gt;
&lt;li&gt;Multiply performance optimizations, from the client to CDN, database, and/or servers. Opportunities are abundant.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Fast Results&lt;/strong&gt;. Easy benefits which can extend existing capabilities at low cost.

&lt;ul&gt;
&lt;li&gt;Basic caching can be achieved without much difficulty. &lt;/li&gt;
&lt;li&gt;A simple approach can yield quick results and save a lot of money!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Reliability&lt;/strong&gt;. 

&lt;ul&gt;
&lt;li&gt;Caching can potentially prevent users knowing about a service or website outage.&lt;/li&gt;
&lt;li&gt;We can mitigate the impact of a service outage by serving cached content.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Overcome geographic and offline obstacles&lt;/strong&gt;.

&lt;ul&gt;
&lt;li&gt;Caching can help with reliability and usability in a variety of geographic and low/no-connectivity challenges.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Increase performance knowledge&lt;/strong&gt; of the app.

&lt;ul&gt;
&lt;li&gt;Exploring caching techniques helps us better understand the apps' limitations, and areas for optimization throughout the entire system.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Sound great? &lt;/p&gt;

&lt;p&gt;Almost.... because caching is not perfect for all cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Risks
&lt;/h3&gt;

&lt;p&gt;Possible downsides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Complexity&lt;/strong&gt;. May increase app complexity, especially when used a lot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging&lt;/strong&gt;. A lot of of caching can lead to a lot of difficult debugging! (been there, done that!)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data consistency&lt;/strong&gt; and usability may be harmed if implemented incorrectly. Users may not be served the correct data/images&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;. Storing data remotely for example could result in security risk in some cases, such as with PII (Personally Identifiable Information).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unnecessary?&lt;/strong&gt; In some cases it simply may be unnecessary to implement.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  💡 Considerations
&lt;/h3&gt;

&lt;p&gt;Considerations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Is your app making expensive/complex calculations or stalling from compute bottlenecks?&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;If so, it may help to refactor code with caching for lower memory usage, read/writes and CPU cycles.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;What is the response time of your application?&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;If the response time is slow, caching may help improve performance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Is it serving the same content to many users?&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;If so, caching can help reduce the number of requests to the server and improve response times.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Do you have a large amount of static content on your website or app?&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Caching can help reduce the data over the network, improving performance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Are there limited or unstable network resources?&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Caching can help reduce the amount of data that needs to be sent over the network, conserving bandwidth and reducing costs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Do you have a high volume of concurrent users accessing your application&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;It can help improve performance and reduce server load.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Is your application frequently requesting data from external sources?&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Caching can help reduce the load on external servers and improve response times.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Caching is used universally and a critical part of popular apps, despite potential drawbacks. &lt;/p&gt;

&lt;h2&gt;
  
  
  Caching Strategies
&lt;/h2&gt;

&lt;p&gt;Basic caching patterns are implemented across different services, technologies and languages. One of the reason we look at this in the intro is because it is applicable throughout the series.&lt;/p&gt;

&lt;p&gt;The caching strategy can optimize how effective it is for your use-case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Locality
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Local cache&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache is stored with the app, such as in memory in the client browser, or app server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Remote cache&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache is stored as a remote independent service, such as CDN.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;note: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some of the info below can get a bit tricky. And even some sources use slightly different terminology!&lt;/li&gt;
&lt;li&gt;The main thing is that you need to understand the trade-offs and the potential impact on your app. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, Write-Through will better ensure data consistency but will have higher latency (slightly slower). Write-Back will have lower latency (faster) but may have more issues with data inconsistency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1r5r1b3oy0a48yh4cmo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1r5r1b3oy0a48yh4cmo.png" alt="Cache Aside" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cache-Aside
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Among the most common caching strategies, aka "lazy loading".&lt;/li&gt;
&lt;li&gt;Fetch data from the cache when it's available, and if it's not, fetch it from the backend.&lt;/li&gt;
&lt;li&gt;Then the client would add it to the cache for future use. &lt;/li&gt;
&lt;li&gt;Cache and database are independent and don't communicate with each other.&lt;/li&gt;
&lt;li&gt;Cache hit: Read from the cache. Cache miss: read from the backend store. &lt;/li&gt;
&lt;li&gt;Best for low write-to-read ratios. (more for heavy reads)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cache-Aside with Read-Through
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Similar to above but with a slight difference - the cache or a 3rd-party library may communicate with the backend store to fetch data when it's not available in the cache. The client does not do this.&lt;/li&gt;
&lt;li&gt;Cache hit/miss same as above, write to cache.&lt;/li&gt;
&lt;li&gt;Good for high read-to-write ratios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xnhfo5ie4o51he1fxaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xnhfo5ie4o51he1fxaz.png" alt="Caching Write Through" width="800" height="133"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Write-Through (SYNCHRONOUS Write)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Writes data to the cache and to the backend store SYNCHRONOUSLY.&lt;/li&gt;
&lt;li&gt;Also, the backend store can load new data (independently of the cache) and then the cache can be updated with the new data.&lt;/li&gt;
&lt;li&gt;The main point here is that the cache is populated only AFTER the new write data is in the backend store.&lt;/li&gt;
&lt;li&gt;Used for better data consistency on the backend. Higher latency for writes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa8p38zqmftm0bwalo8o5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa8p38zqmftm0bwalo8o5.png" alt="Write Back" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Write-Back (Write Behind, ASYNCHRONOUS Write)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Write data to the cache first and ASYNCHRONOUSLY write to the backend store. &lt;/li&gt;
&lt;li&gt;The main difference with Write-Through is that the cache is updated first, returns a response, and in the background then the backend store is updated separately. This does create a risk of data inconsistency but returns a response to the user faster.&lt;/li&gt;
&lt;li&gt;Faster due to lower latency, but more risk of data inconsistency.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cache-Aside with Write-Back
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Write data to the cache first and then asynchronously write it to the backend. &lt;/li&gt;
&lt;li&gt;High write-to-read ratios and requires data consistency between the cache and the backend.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Write allocate
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Data at the missed-write location is put into cache, followed by a write-hit operation. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Write around (No-Write allocate)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Data at the missed-write location is not loaded to cache, and is written directly to the backing store. Data is loaded into the cache on read misses only.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Refresh Cache
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The cache is periodically refreshed ("invalidated") with data from the backing store to ensure that the data in the cache is up-to-date. &lt;/li&gt;
&lt;li&gt;Good if data in the backing store changes frequently, but it can also introduce some latency in read operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cache-Aside with Refresh-Ahead
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The Cache-Aside with Refresh-Ahead pattern is a caching strategy that involves pre-fetch data into the cache before it's requested. &lt;/li&gt;
&lt;li&gt;Good for applications that have predictable access patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Caching with Replicas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Implementing caching and replicating multiple nodes of the cache store for increased availability.&lt;/li&gt;
&lt;li&gt;Used with cache managers like Redis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cache-pinning
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keeping frequently accessed data in the cache, even if it is not being used. &lt;/li&gt;
&lt;li&gt;Used to reduce the frequency of cache misses and improve cache hit rates. &lt;/li&gt;
&lt;li&gt;Good for applications that have a small number of frequently accessed data items.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Time-to-live (TTL)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Setting an expiration time for cached data, after which the data is invalidated and must be retrieved from the backend store. &lt;/li&gt;
&lt;li&gt;Ensure that cached data does not become stale and to free up space in the cache. &lt;/li&gt;
&lt;li&gt;Useful for applications that have data with a short lifespan, such as news or weather data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Invalidating the Cache
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Invalidating the cache whenever the data in the underlying data source changes. For example, if you're caching data from a database, you could invalidate the cache whenever a record is updated or deleted. This ensures that the cache always contains up-to-date data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the primary strategies, although there are others that may be used in special cases.&lt;/p&gt;

&lt;p&gt;Also different caching services and software may implement additional performance enhancement - we'll check that out later.&lt;/p&gt;




&lt;p&gt;We've looked at why caching is useful, and some downsides. Also, some considerations for deciding what and how too implement.&lt;/p&gt;

&lt;p&gt;Also, we examined some of the main caching patterns which can be applied across all types of services.&lt;/p&gt;

&lt;p&gt;Next article we'll start examining caching from the application/client and trace it through the cloud and into large-scale distributed systems.&lt;/p&gt;

&lt;p&gt;If you liked this article check out my previous article on:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/csjcode/150-solutions-architect-metricscalculations-cheatsheet-4m40"&gt;150+ Solutions Architect Metrics&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/architecture/patterns/cache-aside" rel="noopener noreferrer"&gt;Azure Cache Aside&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/architecture/patterns/category/caching" rel="noopener noreferrer"&gt;Azure Caching strategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codeahoy.com/2017/08/11/caching-strategies-and-how-to-choose-the-right-one/" rel="noopener noreferrer"&gt;Caching Strategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.prisma.io/dataguide/managing-databases/introduction-database-caching" rel="noopener noreferrer"&gt;Database caching&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>webperf</category>
      <category>seo</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>150+ Solutions Architect metrics/calculations cheatsheet</title>
      <dc:creator>CSJcode</dc:creator>
      <pubDate>Thu, 23 Feb 2023 01:00:46 +0000</pubDate>
      <link>https://forem.com/csjcode/150-solutions-architect-metricscalculations-cheatsheet-4m40</link>
      <guid>https://forem.com/csjcode/150-solutions-architect-metricscalculations-cheatsheet-4m40</guid>
      <description>&lt;p&gt;150+ Solutions Architect metrics and calculations for systems design, technology comparisons, planning and projects. btw, If there is interest, I'll make this into tables, I made a few but haven't had time to do it all yet.&lt;/p&gt;

&lt;p&gt;Categories: User, Network, Reliability, Compute, Storage, Database, Queues/Events, Security, Cost.&lt;/p&gt;

&lt;p&gt;Thanks for checking it out... if you have ideas for improvements, feel free to comment or make a PR on my github repo: &lt;a href="https://github.com/csjcode/solutions-architect-metrics-cheatsheet" rel="noopener noreferrer"&gt;https://github.com/csjcode/solutions-architect-metrics-cheatsheet&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ⭐️ User
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Daily Active Users (DAU)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Unique active users / day &lt;/li&gt;
&lt;li&gt;Performance and capacity needs, daily, projections.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Monthly Active Users (MAU)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Unique active users / month&lt;/li&gt;
&lt;li&gt;Performance and capacity over longer time periods, projections.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Concurrent Users, Avg/Max&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;Number of users at same time, average and peaks&lt;/li&gt;
&lt;li&gt;Reliability, server capacity, quotas, service bottlenecks&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Actions Per User (APU): Average actions per user&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Actions performed by all unique users / by the number of unique users.&lt;/li&gt;
&lt;li&gt;Performance, bandwidth, concurrency, cost optimization for high/low microservices.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Actions Per User delta (APU Δ)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Change in actions per user over a given time period&lt;/li&gt;
&lt;li&gt;Speed of scalability, concurrency, performance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Daily User Actions (DUA)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Total actions performed by all users in a day.&lt;/li&gt;
&lt;li&gt;System load, performance, cost and capacity growth needs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Requests Per Second (RPS)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Service requests per second&lt;/li&gt;
&lt;li&gt;Reliability in high traffic, quotas, performance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;User Delta&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Change in the number of users over a given time period&lt;/li&gt;
&lt;li&gt;Speed of scalability, capacity planning, concurrency, performance, cost..&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Session length&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Average duration of user session&lt;/li&gt;
&lt;li&gt;Server resources, cost, performance, concurrency planning.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Network
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CIDR/Subnet Calculation&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;IP address and network mask calculation, &lt;/li&gt;
&lt;li&gt;Number of IPs = 2&lt;sup&gt;32&lt;/sup&gt;-2&lt;sup&gt;prefix&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;10.0.0.0/24 = 2&lt;sup&gt;32&lt;/sup&gt;-2&lt;sup&gt;24&lt;/sup&gt; = 2&lt;sup&gt;8&lt;/sup&gt; = 256&lt;/li&gt;
&lt;li&gt;For network sizing and planning&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Bandwidth Consumed/Utilization&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;(Bandwidth used / Total available bandwidth) x 100%&lt;/li&gt;
&lt;li&gt;Network resource usage, potential bottlenecks, cost, quotas, performance&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Available Bandwidth&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Total available bandwidth - bandwidth used.&lt;/li&gt;
&lt;li&gt;Cost, performance, quotas, adequate resources for network traffic and avoiding slowdowns.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Data Transmission Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of data transferred / time taken&lt;/li&gt;
&lt;li&gt;Data transfer speed and network efficiency.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Link Capacity&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Maximum bandwidth capacity of a link.&lt;/li&gt;
&lt;li&gt;Reliability - determines maximum bandwidth available for a link to ensure it can handle traffic.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Network Throughput&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;(Amount of data transferred / Total time) x 100%&lt;/li&gt;
&lt;li&gt;Performance, operations, network efficiency and data transfer speed.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Network Latency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Delay between sending and receiving data.  Round-trip time (RTT)&lt;/li&gt;
&lt;li&gt;Performance, delay in data transfer and network responsiveness.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Network I/O&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Input/output rate of network data.&lt;/li&gt;
&lt;li&gt;Warning of network bottlenecks, performance, cost.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Request Error rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Percentage of failed requests,  (Number of failed requests / Total requests) x 100%&lt;/li&gt;
&lt;li&gt;Identifies issues in the network or application that need to be addressed.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Packet Loss Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Percentage of lost packets.&lt;/li&gt;
&lt;li&gt;Identifies potential vulnerabilities or issues in the network or application.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;HTTP response codes&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;Partial list, see &lt;a href="https://en.wikipedia.org//wiki/List_of_HTTP_status_codes" rel="noopener noreferrer"&gt;full list&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1xx info&lt;/strong&gt;, processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2xx successful&lt;/strong&gt;: 200 OK&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3xx redirection&lt;/strong&gt;: 301 Moved Permanently, 302 Found, 304 Not Modified&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4xx client error&lt;/strong&gt;: 400 Bad Request (parameters missing?), 401 Unauthorized (API token missing?), 403 Forbidden (permissions?), 404 Not Found (url incorrect?), 405 Method Not Allowed (eg. POST not accepted on resource), 429 Too Many Requests (exceeded rate limits?), 499 Client Closed Request&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5xx server errors&lt;/strong&gt;:  500 Internal Server Error, 501 Not Implemented, 502 Bad Gateway, 503 Service Unavailable (overload?), 504 Gateway Timeout (upstream timeout?)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;HTTP Header Fields&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;List of &lt;a href="https://en.wikipedia.org/wiki/List_of_HTTP_header_fields" rel="noopener noreferrer"&gt;standard headers&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Reliability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recovery Time Objective (RTO)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Maximum time window delay within which a service must be restored after a disaster.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Recovery Point Objective (RPO)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Maximum amount of time before unacceptable amounts of data have been lost due to a disaster, failure, or comparable event&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Single Point of Failure (SPOF)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Component that can cause system failure.&lt;/li&gt;
&lt;li&gt;1 - (redundant components/total components).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cloud Services Quotas&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Limits on usage of cloud services.&lt;/li&gt;
&lt;li&gt;Possible SPOF, if quota reached, service unavailable/degraded.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Availability (% of time)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;proportion of time a system is operational&lt;/li&gt;
&lt;li&gt;uptime / (uptime + downtime)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Availability (% of requests)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;proportion of time a system is operational&lt;/li&gt;
&lt;li&gt;successful requests / (valid requests)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Availability in 9s ("nines")&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Percentage of uptime in a year.&lt;/li&gt;
&lt;li&gt;(total time - downtime) / total time&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Maximum Availability with Dependencies&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Maximum Availability estimate for multiple services in a distributed system.&lt;/li&gt;
&lt;li&gt;Availability of Service 1 * Availability of Service 2 * ... Availability of Service n&lt;/li&gt;
&lt;li&gt;MTBF / MTBF + MTTR
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Maximum Availability with redundant components&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Maximum Availability estimate with duplicated components (higher reliability)&lt;/li&gt;
&lt;li&gt;A = 1-F ≈ 1-f(1-a)&lt;sup&gt;s+1&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;where s = spare components, F= failure modes, a= availability (in %)&lt;/li&gt;
&lt;li&gt;ex: 99.5% availability, with two spares the workload’s availability is A ≈ 1 − (1)(1−.995)3 = 99.9999875% availability&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mean Time to Failure (MTTF)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Average time until a component fails.&lt;/li&gt;
&lt;li&gt;total uptime / number of any failures.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mean Time Between Critical Failures (MTBCF)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;total uptime / number of critical failures.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mean Time to Data Loss (MTTDL)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Average time before data loss.&lt;/li&gt;
&lt;li&gt;MTTDL = (1 - Annualized Rate of Data Loss) / Annualized Rate of Data Loss&lt;/li&gt;
&lt;li&gt;Annualized Rate of Data Loss = (Total Data Stored) x (Data Loss Rate)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Recovery Time (RT)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt; TTR + MTTD + MTTI + MTTRM, where TTR is Time to Respond.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mean Recovery Time (MRT)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Average time it takes to recover from a failure.&lt;/li&gt;
&lt;li&gt;MRT = ∑RT / Number of incidents&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mean Time to Detect (MTTD)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Average time it takes to detect a failure.&lt;/li&gt;
&lt;li&gt;MTTD = ∑time taken to detect incidents / Number of incidents.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mean Time to Identify (MTTI)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Average time it takes to identify a failure.&lt;/li&gt;
&lt;li&gt;MTTI = ∑time taken to identify incidents / Number of incidents.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mean Time to Remediate (MTTRM)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Average time it takes to fix a failure.&lt;/li&gt;
&lt;li&gt;∑time taken to remediate incidents / Number of incidents.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mean Time to Resolve (MTTR)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Average time it takes to resolve a failure.&lt;/li&gt;
&lt;li&gt;MTTR = ∑time taken to resolve incidents / Number of incidents.
&lt;strong&gt;Mean Time to Respond (MTTR)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Average time it takes to respond to a failure.&lt;/li&gt;
&lt;li&gt;MTTR = ∑time taken to respond to incidents / Number of incidents.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Change Failure Rate (CFR)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Rate at which changes introduce failures.&lt;/li&gt;
&lt;li&gt;CFR = Number of failed changes / Number of changes attempted.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Defect Escape Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Rate at which defects escape detection.&lt;/li&gt;
&lt;li&gt;DER = Number of defects found after release / Total number of defects.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Defect Density&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of defects per unit of code.&lt;/li&gt;
&lt;li&gt;Number of defects / Size of the software.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Failure Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Rate at which components fail.&lt;/li&gt;
&lt;li&gt;Number of failures / Unit of time&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Service restoration time&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time taken to restore a failed system.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Redundancy&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;(Number of redundant (backup) components / Total number of components) x 100%&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Resiliency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Ability to recover from a failure.&lt;/li&gt;
&lt;li&gt;Availability x Reliability x Maintainability x Recoverability&lt;/li&gt;
&lt;li&gt;Availability (% time), reliability (probability of working service), maintainability, and recoverability (MTTR)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Compute
&lt;/h3&gt;

&lt;p&gt;Many of the following metrics are available in analytics services of the cloud provider tools such as AWS Cloudwatch or service dashboards. Metrics are included here for awareness and a reminder when evaluating Compute resources.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CPU utilization&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;CPU usage rate. Monitor performance &amp;amp; efficiency. Optimize performance.&lt;/li&gt;
&lt;li&gt;Total CPU time / Elapsed time &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Disk I/O&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Disk input/output. Measure read/write speeds for the Compute device. Optimize throughput.&lt;/li&gt;
&lt;li&gt;Total bytes read/written / Elapsed time &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Network I/O&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Network input/output. Measure bandwidth usage on the Compute device. Optimize connectivity. &lt;/li&gt;
&lt;li&gt;Total bytes sent/received / Elapsed time &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;IOPS&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Input/Output operations/second. Assess data access performance. Optimize throughput.&lt;/li&gt;
&lt;li&gt;Total operations / Elapsed time &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Memory utilization&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;RAM usage rate. Assess RAM usage for performance.&lt;/li&gt;
&lt;li&gt;Total RAM usage / Total RAM available &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Caching&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Data storage/retrieval. Improve data performance. &lt;/li&gt;
&lt;li&gt;Hits / Misses &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cost&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Expense management. Estimate resource expenses. &lt;/li&gt;
&lt;li&gt;Actual cost/Estimated cost &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Container density&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Resource utilization. Optimize resource use. &lt;/li&gt;
&lt;li&gt;Used resources / Total resources &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Function duration vs. limits&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Execution time. Gauge execution time. &lt;/li&gt;
&lt;li&gt;Analytics or Start time - End time vs. quota&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Function concurrency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Simultaneous operations. Measure concurrency.&lt;/li&gt;
&lt;li&gt;Analytics or Number of operations per lambda / Elapsed time&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Function response time&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Execution time. Evaluate speed. Gauge execution time.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Load Balancing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Load Balancing Algorithm&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Algorithm used by the load balancer to distribute traffic&lt;/li&gt;
&lt;li&gt;Round Robin, Least Connections, Weighted Round Robin, Weighted Least Connections, Dynamic Least Connections, Source IP Hash, Least Time,  Least Packets, Agent-Based Load Balancing, URL Hash, Server Affinity (Sticky Sessions)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Request Success Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of successful requests/Total number of requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Latency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time taken to serve a request&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Error Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of failed requests/Total number of requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Connection Count&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of connections between clients and servers&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Active Connections&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of active connections between clients and servers&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Backend Server Health&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Availability and response time of backend servers&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;SSL Handshake Time&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time taken to establish a secure connection&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Connection Rebalancing Time&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time taken to rebalance connections across servers&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Autoscaling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scaling metric&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A metric that determines when autoscaling should occur, such as CPU utilization or request count&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Scaling policy&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A set of rules that define how autoscaling should occur, such as increasing or decreasing the number of instances based on the scaling metric&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Target Tracking Scaling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Adjusts capacity based on target metrics.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Step Scaling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Adds or removes capacity based on specific thresholds.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple Scaling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Adds or removes capacity based on logging or cloudwatch alarms.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scheduled Scaling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Changes capacity at specific times or dates.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Predictive Scaling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Uses ML to forecast demand and adjust capacity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dynamic Scaling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Resizes based on changing demand and traffic patterns.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Capacity Optimized Scaling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Provisions instances for optimal cost and performance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Scale-out threshold&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The threshold value for the scaling metric that triggers scaling out (adding instances)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Scale-in threshold&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The threshold value for the scaling metric that triggers scaling in (removing instances)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cool-down period&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The period of time after scaling has occurred during which autoscaling is suspended to prevent rapid scaling up and down&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Elasticity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resource utilization&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The percentage of available resources (such as CPU or memory) that are currently in use&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Capacity planning&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The process of estimating future resource needs based on historical usage patterns and growth projections&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Time to Scale&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The time it takes to add or remove resources to meet demand changes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cost Optimization&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The process of minimizing costs while maintaining the necessary level of elasticity and performance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Database
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Throughput&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The amount of data transferred per unit of time&lt;/li&gt;
&lt;li&gt;Data transferred / time&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Latency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The time it takes to process a request&lt;/li&gt;
&lt;li&gt;Time to first byte + time to last byte&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Response time&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The time it takes to respond to a request&lt;/li&gt;
&lt;li&gt;Time to last byte - time to first byte&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Concurrency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The number of simultaneous users or connections&lt;/li&gt;
&lt;li&gt;Simultaneous requests / time&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Read-to-Write Ratio&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The ratio of read requests to write requests&lt;/li&gt;
&lt;li&gt;Read requests / write requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cache Hit Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The percentage of data that is retrieved from cache&lt;/li&gt;
&lt;li&gt;cache hit rate = cache hits / (cache hits + cache misses)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Database Connections&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The number of active database connections&lt;/li&gt;
&lt;li&gt;Measured using database monitoring tools.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Query performance&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time to execute a database query&lt;/li&gt;
&lt;li&gt;Execution time = end time - start time&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Index usage&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;How frequently an index is used to retrieve data&lt;/li&gt;
&lt;li&gt;Index usage = (number of times index is used) / (total number of queries)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Lock waits&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time spent waiting for a locked database object&lt;/li&gt;
&lt;li&gt;Lock wait time = total time spent waiting for a lock&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Deadlocks&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Occurrences of simultaneous locking conflicts in transactions&lt;/li&gt;
&lt;li&gt;Deadlocks = number of occurrences of simultaneous locking conflicts&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Data consistency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Degree of uniformity and accuracy in data across systems&lt;/li&gt;
&lt;li&gt;Data consistency = (number of errors detected / total number of checks) * 100&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Backup and Recovery&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time taken to backup and recover data in case of failure&lt;/li&gt;
&lt;li&gt;Time taken to backup or recover / number of backups or recoveries&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Database Size and Growth&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Total size of the database and its growth rate&lt;/li&gt;
&lt;li&gt;Current size of database + (growth rate * time interval)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;CAP Theorum&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Pick two of the following three properties:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Each read request receives the most recent write or an error when consistency can’t be guaranteed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Availability&lt;/strong&gt;: Each request receives a non-error response, even when nodes are down or unavailable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partition tolerance&lt;/strong&gt;: The system operates despite the loss of messages between nodes.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;ACID&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Atomicity&lt;/strong&gt;: All or nothing. Either all operations succeed or all operations fail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Data is consistent before and after the transaction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt;: Transactions are isolated from each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durability&lt;/strong&gt;: Once a transaction has been committed, it will remain so, even in the event of power loss or system crash.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;BASE&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Basically Available&lt;/li&gt;
&lt;li&gt;Soft state (may be inconsistent for brief periods) &lt;/li&gt;
&lt;li&gt;Eventually consistent&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Storage
&lt;/h3&gt;

&lt;h4&gt;
  
  
  General Storage metrics
&lt;/h4&gt;

&lt;p&gt;Applies to most storage mediums, including block, file, and object storage.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data Durability&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Probability of data remaining intact over time&lt;/li&gt;
&lt;li&gt;(1 - Annual Failure Rate) ^ Years&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Latency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time for data to be accessed&lt;/li&gt;
&lt;li&gt;Total time to read or write data&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Replication Latency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time for replica data to be transferred or accessed&lt;/li&gt;
&lt;li&gt;Total time to read or write data after transfer&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;IOPS (Input/Output Operations Per Second)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of read/write operations per second&lt;/li&gt;
&lt;li&gt;Total number of operations / time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Throughput&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of data transferred per unit of time&lt;/li&gt;
&lt;li&gt;Total data transferred / time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Maximum Throughput&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of data transferred per unit of time&lt;/li&gt;
&lt;li&gt;Total data transferred / time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Object storage
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Object Storage Utilization&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of object storage used versus total available object storage&lt;/li&gt;
&lt;li&gt;Used object storage / Total object storage&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Object Storage Tier Data Stored&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Length of time objects are stored in a tier before being transfered/deleted&lt;/li&gt;
&lt;li&gt;Object transfer or deletion execution duration by tier&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Object Storage API/request Calls&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;API requests made to object storage service&lt;/li&gt;
&lt;li&gt;API requests / Time interval&lt;/li&gt;
&lt;li&gt;PUT, COPY, POST, LIST requests (pricing may be different)&lt;/li&gt;
&lt;li&gt;GET, SELECT, and all other requests&lt;/li&gt;
&lt;li&gt;Lifecycle Transition requests&lt;/li&gt;
&lt;li&gt;Data Retrieval requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Object Storage Latency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time taken for object storage service to process a request&lt;/li&gt;
&lt;li&gt;Total time for requests / Number of requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Data Transfer per time interval&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Total amount of data transferred&lt;/li&gt;
&lt;li&gt;Data Transferred (in bytes) / time interval &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Object Storage Retention&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Length of time objects are stored before being deleted&lt;/li&gt;
&lt;li&gt;Object transfer or deletion execution duration&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Geographic Put/Get requests&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Latency of Put/Get requests&lt;/li&gt;
&lt;li&gt;Latency (in milliseconds) / time interval &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Availability metrics&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of requests that fail&lt;/li&gt;
&lt;li&gt;Requests that fail / total number of requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Data Consistency metrics&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of objects that are successfully stored/retrieved&lt;/li&gt;
&lt;li&gt;Number of objects successfully stored/retrieved / time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Bandwidth used in/out total, timeframe, region, internet, inside cloud provider&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of data transferred in/out of object storage&lt;/li&gt;
&lt;li&gt;Data transferred in/out / time interval&lt;/li&gt;
&lt;li&gt;There may be different policies per cloud provider.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Disk storage
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Disk Utilization&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of disk space used versus total available disk space&lt;/li&gt;
&lt;li&gt;Used disk space / Total disk space&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Disk IOPS&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of read and write requests to a disk in a second&lt;/li&gt;
&lt;li&gt;Number of requests / Time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Disk Latency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time taken for a disk to process a read/write request&lt;/li&gt;
&lt;li&gt;Total time for read/write requests / Number of requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Data Replication Latency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Time taken to replicate data from one location to another&lt;/li&gt;
&lt;li&gt;Time for replication completion - Time of data creation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Data Replication Bandwidth&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of data replicated per second&lt;/li&gt;
&lt;li&gt;Amount of data / Time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;SSD Endurance&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of data that can be written to an SSD before failure&lt;/li&gt;
&lt;li&gt;Total bytes written / (Drive size in GB * Drive endurance)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Disk Utilization&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Percentage of disk space used&lt;/li&gt;
&lt;li&gt;(Amount of space used / Total amount of space) x 100&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;RAID Reliability&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Probability that the RAID will remain operational&lt;/li&gt;
&lt;li&gt;(1 - Probability of failure) ^ Number of disks&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Storage Capacity&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Total amount of storage space available&lt;/li&gt;
&lt;li&gt;Amount of space used + amount of space available&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Block Storage IOPS&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of read and write requests to a block storage device in a second&lt;/li&gt;
&lt;li&gt;Number of requests / Time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Block Storage Latency&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time taken for a block storage device to process a read/write request&lt;/li&gt;
&lt;li&gt;Total time for read/write requests / Number of requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Types of RAIDS&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;RAID Level&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAID 0&lt;/td&gt;
&lt;td&gt;Data is striped across multiple disks for increased performance, but offers no redundancy.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAID 1&lt;/td&gt;
&lt;td&gt;Data is mirrored across two disks for fault tolerance, but offers no performance improvement.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAID 5&lt;/td&gt;
&lt;td&gt;Data is striped across multiple disks with parity information stored on each disk for fault tolerance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAID 6&lt;/td&gt;
&lt;td&gt;Similar to RAID 5, but with two sets of parity information for even greater fault tolerance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAID 10&lt;/td&gt;
&lt;td&gt;A combination of RAID 1 and RAID 0, where data is mirrored and striped for both performance and fault tolerance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAID 50&lt;/td&gt;
&lt;td&gt;A combination of RAID 5 and RAID 0, where data is striped across multiple RAID 5 arrays for increased performance and fault tolerance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAID 60&lt;/td&gt;
&lt;td&gt;A combination of RAID 6 and RAID 0, where data is striped across multiple RAID 6 arrays for even greater performance and fault tolerance.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  ⭐️ Queues/Events
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Queue Depth&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Number of events in a queue waiting to be processed.&lt;/li&gt;
&lt;li&gt;Total events - Processed events&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Queue Wait Time&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of time an event spends waiting in a queue before being processed.&lt;/li&gt;
&lt;li&gt;Total time events spend in queue / Number of events in queue&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Event Arrival Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Rate at which events are arriving at a queue.&lt;/li&gt;
&lt;li&gt;Number of events arriving / Time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Event Processing Time&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Amount of time it takes to process an event.&lt;/li&gt;
&lt;li&gt;Total time spent processing events / Number of events processed&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Event Processing Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Rate at which events are being processed.&lt;/li&gt;
&lt;li&gt;Number of events processed / Time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Queue Processing Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Rate at which events are being processed from a queue.&lt;/li&gt;
&lt;li&gt;Number of events processed from queue / Time interval&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Queue Time&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Total time that events spend in a queue, including both wait time and processing time.&lt;/li&gt;
&lt;li&gt;Queue Wait Time + Event Processing Time&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Queue Throughput&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The rate at which events are moving through a queue, including both incoming and outgoing events.&lt;/li&gt;
&lt;li&gt;Incoming Event Rate + Outgoing Event Rate&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Event Drop Rate&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;the rate at which events are being dropped or lost, typically due to queue overflow.&lt;/li&gt;
&lt;li&gt;Number of dropped events / Total number of events&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Queue Latency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;the time it takes for an event to travel through a queue, including both wait time and pr**ocessing time.&lt;/li&gt;
&lt;li&gt;Queue Time / Number of events&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Network Security Score: a metric that measures the security posture of a network, including factors such as the number of vulnerabilities, exposure to threats, and compliance with security standards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Incident Response Time&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The amount of time it takes to respond to a security incident&lt;/li&gt;
&lt;li&gt;Detection Time + Response Time + Mitigation Time&lt;/li&gt;
&lt;li&gt;Time Detected - Time Reported&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Risk Assessment Score&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A numerical score based on a risk assessment methodology such as the NIST Risk Management Framework&lt;/li&gt;
&lt;li&gt;(risk rating x probability of risk) + (residual risk x probability of residual risk)&lt;/li&gt;
&lt;li&gt;Number of Potential Risks / Number of Acceptable Risks&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Attack Surface&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The total number of entry points or attack vectors available to attackers &lt;/li&gt;
&lt;li&gt;Attack surface = sum of (threats x vulnerabilities) &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Vulnerability Assessment Score&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A numerical score based on a vulnerability assessment methodology such as CVSS&lt;/li&gt;
&lt;li&gt;Common Vulnerability Scoring System [CVSS calculator(&lt;a href="https://www.first.org/cvss/calculator/3.1" rel="noopener noreferrer"&gt;https://www.first.org/cvss/calculator/3.1&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Potential Vulnerabilities/Number of Acceptable Vulnerabilities&lt;/li&gt;
&lt;li&gt;CVSS: (Base Score + Temporal Score + Environmental Score)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Access Control Effectiveness&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ability of the access control system to protect the system from unauthorized access&lt;/li&gt;
&lt;li&gt;(Authenticated Access Attempts - Unauthorized Access Attempts) / Authenticated Access Attempts&lt;/li&gt;
&lt;li&gt;Number of Access Control Rules/Number of Access Control Rules Enforced&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Authentication Effectiveness&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ability of the authentication system to accurately identify and authenticate users&lt;/li&gt;
&lt;li&gt;Authentication Effectiveness = (Authenticated Users - Unauthenticated Users) / Authenticated Users&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Authorization Effectiveness&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ability of the authorization system to accurately authorize users to access resources&lt;/li&gt;
&lt;li&gt;Number of Authorization Controls/Number of Authorization Controls Enforced&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Security Audit Log Analysis&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ability of the security audit system to detect, monitor, and analyze security events&lt;/li&gt;
&lt;li&gt;(Audited Events - Unaudited Events) / Audited Events&lt;/li&gt;
&lt;li&gt;Number of Security Events Detected/Number of Security Events Recorded&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Security Incident Rate&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rate of security incident per time interval&lt;/li&gt;
&lt;li&gt;Security incidents / time
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Security Compliance Score&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Score of how well the system complies with security policies and best practices&lt;/li&gt;
&lt;li&gt;Compliance score = (number of compliant components / total number of components) x 100&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Security Training Effectiveness&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of how well users understand and adhere to security policies&lt;/li&gt;
&lt;li&gt;Training effectiveness = (number of users who successfully complete security trainings / total number of users) x 100&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Vulnerability Scanning Frequency&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of how often the system is tested for security vulnerabilities&lt;/li&gt;
&lt;li&gt;Scanning frequency = (number of scans performed in a given time period / total time period)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Identity and Access Management (IAM) roles and permissions audit&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of the accuracy and security of IAM roles and permissions&lt;/li&gt;
&lt;li&gt;IAM audit = (number of correct roles and permissions / total number of roles and permissions) x 100&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Key Management Service (KMS) usage and audit&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of the accuracy and security of KMS usage&lt;/li&gt;
&lt;li&gt;KMS audit = (number of correct KMS usage / total number of KMS usage) x 100&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Security Information and Event Management (SIEM) alerts and monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of the accuracy and security of SIEM alerts&lt;/li&gt;
&lt;li&gt;SIEM monitoring = (number of correctly triggered alerts / total number of alerts) x 100&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Threat intelligence feeds integration and usage&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of how threat intelligence feeds are used to help identify and respond to security threats&lt;/li&gt;
&lt;li&gt;Number of threat intelligence feeds used / total number of threat intelligence feeds available&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Encryption key rotation frequency&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of how often cryptographic keys are changed&lt;/li&gt;
&lt;li&gt;Time interval between key changes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Compliance posture&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of how well the system complies with a security standard&lt;/li&gt;
&lt;li&gt;Number of security standards met / total number of security standards&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Network traffic monitoring and analysis&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of the ability to monitor and analyze network traffic for suspicious activity&lt;/li&gt;
&lt;li&gt;Amount of network traffic monitored / total network traffic&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;User behavior analytics (UBA) and anomaly detection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measurement of the ability to detect anomalous user behavior&lt;/li&gt;
&lt;li&gt;Number of anomalies detected / total user behavior events&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Data Loss Prevention (DLP)&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The practice of preventing sensitive data from leaving the organization &lt;/li&gt;
&lt;li&gt;DLP = implementation of policies and technologies + monitoring of user activity &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Data Encryption&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The practice of transforming sensitive data into an unreadable format &lt;/li&gt;
&lt;li&gt;Data encryption = implementation of encryption algorithms + encryption of data &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ Cost
&lt;/h3&gt;

&lt;p&gt;I am only going to give some brief metrics on Cost, because almost everything above can affect cost and it will vary a lot between providers. &lt;/p&gt;

&lt;p&gt;This is not to minimize cost, it's one of the most important factors!!! &lt;/p&gt;

&lt;p&gt;Just that cost should be considered on ALL the metrics above.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Total Cost of Ownership (TCO&lt;/strong&gt;) = (cost of acquisition + cost of operation + cost of maintenance) over the useful life of the asset&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost per transaction&lt;/strong&gt; = total cost / number of transactions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost per unit of time&lt;/strong&gt; = total cost / time period&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost per user&lt;/strong&gt; = total cost / number of users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return on Investment (ROI)&lt;/strong&gt; = (gain from investment - cost of investment) / cost of investment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost of Downtime (CoD)&lt;/strong&gt; = (lost revenue + recovery costs + damage to brand reputation) / total downtime hours&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost of Poor Quality (CoPQ)&lt;/strong&gt; = (internal failure costs + external failure costs + cost of appraisal + cost of prevention) / total number of units produced&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost of Delay (CoD)&lt;/strong&gt; = (value of time saved by earlier release - cost of delay) / time saved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a ton of cloud cost tools but these are some of the popular ones on the biggest platforms (there are many more if you search on their sites):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;AWS Cost Explorer&lt;/li&gt;
&lt;li&gt;AWS Budgets&lt;/li&gt;
&lt;li&gt;AWS Trusted Advisor&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Azure&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Azure Cost Management + Billing&lt;/li&gt;
&lt;li&gt;Azure Advisor&lt;/li&gt;
&lt;li&gt;Azure Service Health&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;GCP&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;GCP Billing&lt;/li&gt;
&lt;li&gt;GCP Pricing Calculator&lt;/li&gt;
&lt;li&gt;GCP Cost Management&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Third-party&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;CloudCheckr&lt;/li&gt;
&lt;li&gt;CloudHealth by VMware&lt;/li&gt;
&lt;li&gt;Apptio Cloudability&lt;/li&gt;
&lt;li&gt;CloudBolt&lt;/li&gt;
&lt;li&gt;CloudZero&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⭐️ References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/architecture/well-architected/" rel="noopener noreferrer"&gt;Amazon AWS Well Architected&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/architecture/framework/" rel="noopener noreferrer"&gt;Microsoft Azure Well Architected&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/architecture/framework" rel="noopener noreferrer"&gt;Google Cloud Architecture Framework&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://systemsarchitect.io/" rel="noopener noreferrer"&gt;SystemsArchitect.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sre.google/books/" rel="noopener noreferrer"&gt;The Site Reliability Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sre.google/books/" rel="noopener noreferrer"&gt;The Site Reliability Workbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/donnemartin/system-design-primer" rel="noopener noreferrer"&gt;System Design Primer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/checkcheckzz/system-design-interview" rel="noopener noreferrer"&gt;System Design Interview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for checking it out... if you have ideas for improvements, feel free to comment or make a PR on my github repo: &lt;a href="https://github.com/csjcode/solutions-architect-metrics-cheatsheet" rel="noopener noreferrer"&gt;https://github.com/csjcode/solutions-architect-metrics-cheatsheet&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Git shortcuts (alias)</title>
      <dc:creator>CSJcode</dc:creator>
      <pubDate>Sat, 01 Jan 2022 01:30:54 +0000</pubDate>
      <link>https://forem.com/csjcode/git-shortcuts-alias-4bnc</link>
      <guid>https://forem.com/csjcode/git-shortcuts-alias-4bnc</guid>
      <description>&lt;p&gt;Shortcuts and aliases I was compiling as I was setting up a new laptop, and thought I'd share them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lets get situated with where we are starting
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;$ cat ~/.gitconfig&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[user]
        name = Foo Bar
        email = example@example.com
[init]
        defaultBranch = main
[alias]
        co = checkout
        br = branch
        ci = commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Git Shortcuts: (1) Git alias or (2) Git+Shell alias
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Make git shortcuts in a git alias - pattern (note: --global is normally used for a dev's user account, but you could use --system for all accounts, --local for the local repo only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.&amp;lt;alias&amp;gt; &amp;lt;commands&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make git shortcuts in shell (bash/zsh etc.) alias - pattern&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;$ alias &amp;lt;alias&amp;gt;='&amp;lt;commands&amp;gt;'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example: use shortcut "gl" to list git user aliases, including adding, listing and removing the alias.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git config --global alias.gl 'config --global -l'

$ git gl

[...]
init.defaultbranch=main
alias.co=checkout
alias.br=branch
alias.ci=commit
[...]

$ alias gconf='git gl'

$ gconf

[...]
init.defaultbranch=main
alias.co=checkout
alias.br=branch
alias.ci=commit
[...]

$ alias -p

alias gconf='git gl'

$ unalias gconf

$ gconf
bash: gconf: command not found

$ alias -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use could also use this to see settings:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git config --list&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;file:/Users/foobar/.gitconfig  alias.com=checkout main
file:/Users/foobar/.gitconfig  alias.p=push
file:.git/config        core.repositoryformatversion=0
file:.git/config        core.filemode=true
file:.git/config        core.bare=false
file:.git/config        core.logallrefupdates=tru
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$ git config user.email&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;example@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$ git config user.name&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Foo bar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$ git config --global  user.email "myname@gmail.com"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global user.name "firstname lastname"&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Basics
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.co checkout&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.com "checkout main"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.br branch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.a add&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.cm 'commit -m'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.p push&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.mr merge&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.rb rebase&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.rbc rebase  --continue&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.st status&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$  git st

On branch main
Your branch is up to date with 'origin/main'.

Untracked files:
  (use "git add &amp;lt;file&amp;gt;..." to include in what will be committed)
        git-aliases.md

nothing added to commit but untracked files present (use "git add" to track)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Git Reset
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; do not use this config unless you are sure you know what you are doing, it could result in losing code permanently if you misuse this or make a mistake. &lt;/p&gt;

&lt;p&gt;Use a test repo first, until you are sure about what is going on.&lt;/p&gt;

&lt;p&gt;see: What's the difference between git reset --mixed, --soft, and --hard? &lt;a href="https://stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard"&gt;https://stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As stated in the link above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--soft: uncommit changes, changes are left staged (index).
--mixed (default): uncommit + unstage changes, changes are left in working tree.
--hard: uncommit + unstage + delete changes, nothing left.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Undo last local commmit, to HEAD (uncommit, keeps in stage)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.rs reset --soft HEAD~1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Undo last local commmit, to HEAD (uncommit unstage)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.rmx reset --mixed HEAD~1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Undo local edits to HEAD (DANGER, permanent, caution)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.rh reset --hard HEAD~1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;List of all commits - summary&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.l1 'log --oneline'&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;61eee34 (HEAD -&amp;gt; main, origin/main, origin/2-first-app-counter, 2-first-app-counter) Counter app
e9a23b9 (2-first-app) Hello world
bcc8bf2 Start fresh
abf9f0a (origin/1-hello-world, 1-hello-world) Basic hello world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last commit&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.last 'log -1 HEAD --stat'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git last&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Author: Foo bar &amp;lt;example@example.com&amp;gt;
Date:   Fri Dec 31 14:54:47 2021 -0800

    Counter app example

 counter.sol | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remote comfigured repos&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.rv 'remote -v'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git rv&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin  https://github.com/foobar/Hello-World.git (fetch)
origin  https://github.com/foobar/Hello-World.git (push)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search for specific strings (put string after -F)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.se '!git rev-list --all | xargs git grep -F'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Cherry-pick &lt;/p&gt;

&lt;p&gt;more info: &lt;a href="https://www.atlassian.com/git/tutorials/cherry-pick"&gt;https://www.atlassian.com/git/tutorials/cherry-pick&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git config --global alias.ch cherry-pick&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Change the commit message:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git config --global commit.template ~/.gitmessage.txt&lt;/code&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
    </item>
    <item>
      <title>Howto: Rosetta terminal (MacOS) in Visual Studio Code</title>
      <dc:creator>CSJcode</dc:creator>
      <pubDate>Tue, 28 Dec 2021 01:54:58 +0000</pubDate>
      <link>https://forem.com/csjcode/howto-rosetta-terminal-macos-in-visual-studio-code-3pck</link>
      <guid>https://forem.com/csjcode/howto-rosetta-terminal-macos-in-visual-studio-code-3pck</guid>
      <description>&lt;p&gt;&lt;strong&gt;Background:&lt;/strong&gt; "Rosetta" is the name of the Apple Mac application that can emulate x86 architecture even when on an Apple ARM (ie. Apple M1 chip). "Terminal" is the application on Mac that takes command line input (CLI), and is integrated with Visual Studio Code. Visual Studio Code is one of the most popular development IDE tools.&lt;/p&gt;

&lt;p&gt;A Rosetta terminal (on MacOS) means you are loading and running the Terminal app using the x86 emulation. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I'll share a few tips on how to set the default terminal in Visual Studio Code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is useful for example when developing with Rust and Solana on an Mac with M1 chip. As of December 2021, there were some issues, so developers often use a Rosetta terminal which resolves the issues. (see links at bottom of article for more on that)&lt;/p&gt;

&lt;p&gt;Since I am doing some Solana/Rust development currently, I needed Visual Studio Code (VSC) to open the Rosetta terminal by default.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Howto for Visual Studio Code&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the VSC Command Palette (Ctrl/Command + Shift + P)&lt;/li&gt;
&lt;li&gt;Type "settings.json" to find related commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a couple variations of how you could do this, such as in User or Workspace settings.&lt;/p&gt;

&lt;p&gt;I'm going to show how to do it for the Workspace settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(option 1) Change VSC Workspace settings&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This method is useful because it's project-specific and you may not want all your projects to default to Rosetta terminal (x86). It saves a settings file in your current project. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After typing "settings.json" into Command Palette you should see some selections like this, I chose the Workspace one. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7pgrzvil8cue81u716j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7pgrzvil8cue81u716j.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This brought up an empty file. If you already have Workspace preferences it may show some JSON. Either way, just add the JSON below.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    "terminal.integrated.profiles.osx": {
        "x86 bash": {
            "path": "/usr/bin/arch",
            "args": ["-arch", "x86_64", "/bin/bash"]
        }
    },
    "terminal.integrated.defaultProfile.osx": "x86 bash"



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;note: you can change this to zsh (/bin/zsh) or another shell, just change the corresponding values as above.&lt;/p&gt;

&lt;p&gt;You can also identify if you are using Rosetta terminal (or not) with the command &lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ arch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;output (validating Rosetta): i386&lt;/p&gt;

&lt;p&gt;or &lt;/p&gt;

&lt;p&gt;output (validating NOT Rosetta): arm64&lt;/p&gt;

&lt;p&gt;After I closed my VSC terminal and initiated a new one it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vcqyq0vdwnqzlk7s3r7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vcqyq0vdwnqzlk7s3r7.png" alt="VSC Workspace settings - Rosetta terminal CLI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(alternate option) Change VSC User settings&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can also change your Visual Studio Code global User settings to do the same. &lt;/p&gt;

&lt;p&gt;It's slightly trickier because you have to find the correct part of the JSON, load that up, add a comma and append it.&lt;/p&gt;

&lt;p&gt;I first went to Settings in the regular app Preferences:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufm02sg44dbx9h9lkfc0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufm02sg44dbx9h9lkfc0.png" alt="Visual Studio Code settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I typed in "defaultProfile". That brings up this menu:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3lsisy2cbybn0mtg2ltb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3lsisy2cbybn0mtg2ltb.png" alt="Default profile"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After setting my default terminal, I closed my previous terminal and started a new one. And this is the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa44havumtj2o6bllfkm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa44havumtj2o6bllfkm0.png" alt="Visual Studio Code settings User default terminal json"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I mentioned using Rosetta terminal for Rust/Solana dev, you can find out more on that config here: &lt;a href="https://dev.to/nickgarfield/how-to-install-solana-dev-tools-on-an-m1-mac-kfn"&gt;https://dev.to/nickgarfield/how-to-install-solana-dev-tools-on-an-m1-mac-kfn&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Once you are set up for that, you can follow Nader Dabit's  Solana/Rust and Phantom tutorial: &lt;a href="https://dev.to/dabit3/the-complete-guide-to-full-stack-solana-development-with-react-anchor-rust-and-phantom-3291"&gt;https://dev.to/dabit3/the-complete-guide-to-full-stack-solana-development-with-react-anchor-rust-and-phantom-3291&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also for citation, note that I originally found the terminal settings info at the following url, expanded on it with screenshots and different methods, and adapted for bash profile: &lt;a href="https://stackoverflow.com/questions/70217885/configure-m1-vscode-arm-but-with-a-rosetta-terminal" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/70217885/configure-m1-vscode-arm-but-with-a-rosetta-terminal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this was helpful, thanks for checking this article out.&lt;/p&gt;

&lt;p&gt;Feel free to comment on any other related helpful suggestions.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>macos</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
