{"id":20636,"date":"2023-04-11T10:21:54","date_gmt":"2023-04-11T08:21:54","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/?p=20636"},"modified":"2023-04-11T10:50:19","modified_gmt":"2023-04-11T08:50:19","slug":"distributed-cache","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/","title":{"rendered":"Distributed Cache: How to Boost System Responsiveness"},"content":{"rendered":"\n<p>Distributed cache can improve the responsiveness of today&#8217;s <strong>high-performance web and mobile apps<\/strong>. At heart it&#8217;s a simple concept, but, when used well, it can bring improved capacity and flexibility to networked systems. As well as classic caching scenarios, distributed cache systems like Redis offer an alternative to standard databases when handling working data.<\/p>\n\n\n\n<p>In this article we&#8217;ll look more closely at distributed cache and how it can be used. And we&#8217;ll share some insights from<a href=\"https:\/\/insoore.com\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\"> Insoore<\/a> to help you optimise your own apps and services.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-abc-of-distributed-cache\"><strong>The ABC of distributed cache<\/strong><\/h2>\n\n\n\n<p>The use of<a href=\"https:\/\/www.codemotion.com\/magazine\/backend\/how-to-guide-asynchronous-batching-for-stampede-prevention\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\"> caching<\/a> is well-known to preserve the stability and performance of web apps and websites. Resources that are served regularly are stored in pre-generated forms to reduce database hits and loads on internal networks. Whether served from the filesystem or memory, such mechanisms can significantly improve the capacity and speed of data-intensive applications. Distributed caching is basically an extension of this principle.<\/p>\n\n\n\n<p>Where standard caching stores resources locally, a distributed cache pools the RAM of multiple connected devices. <strong>This overcomes the inherent limitations of single-machine-based caching strategies<\/strong>. Distributed cache is typically used for data-driven apps where performance and scale are significant factors.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-distributed-cache-vs-database\"><strong>Distributed cache vs. database<\/strong><\/h2>\n\n\n\n<p>Without caching, data access typically requires a structured database of some form. Databases allow data to be stored securely and reliably, <strong>using the<a aria-label=\" (opens in a new tab)\" href=\"https:\/\/towardsdatascience.com\/database-basics-acid-transactions-bf4d38bd8e26\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\"> ACID<\/a> principles to ensure data consistency<\/strong>. However, database reads and writes require disk operations, with associated network and hardware overheads. Distributed cache allows quick reads of commonly used data directly from memory, avoiding this I\/O latency.<\/p>\n\n\n\n<p>Distributed cache also achieves efficiency savings in other ways. It doesn&#8217;t require query parsing and syntax validation. Checks on database authorisation and permissions can be bypassed. What&#8217;s more, distributed cache data can be optimised by data access plans developed to meet predicted usage patterns. Caching also allows greater concurrency for read-only operations as locks or integrity checks are not needed.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"670\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/database-g8c62a16dd_1280-1024x670.jpg\" alt=\"\" class=\"wp-image-20643\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/database-g8c62a16dd_1280-1024x670.jpg 1024w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/database-g8c62a16dd_1280-300x196.jpg 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/database-g8c62a16dd_1280-768x502.jpg 768w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/database-g8c62a16dd_1280.jpg 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Distributed cache offers benefits compared to traditional database.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-is-redis\"><strong>What is Redis?<\/strong><\/h2>\n\n\n\n<p>Redis is an in-memory data store that can serve as the basis for distributed cache operations. <strong>For applications where fast performance, scalability and network optimisation are key, Redis is ideal<\/strong>. The in-memory nature of its data operations makes it much faster than conventional databases&#8217; read-write processes and by making use of distributed architectures, it can cut out disk-based persistence for real-time functionality. <strong>However, that doesn&#8217;t mean your data is precarious. <\/strong>Redis features a number of persistence options, including a Redis database that performs periodic snapshots in case of system failure.<\/p>\n\n\n\n<p>Redis is also highly versatile and is used for functionality like streaming and message brokers. It allows the use of native datatypes without the need for conversion. Strings, hashes, lists, sets, streams and much more are all supported. Redis has its own DSL,<a href=\"https:\/\/redis.io\/docs\/manual\/programmability\/lua-api\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\"> Lua<\/a>, for server-side scripting, making it highly programmable and flexible. It is modular and extensive, and you can write your own modules in C, or with<a href=\"https:\/\/www.codemotion.com\/magazine\/backend\/languages\/modern-tips-and-tricks-with-c\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\"> C++<\/a> and any other language that supports C binding functionalities.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-applying-distributed-cache-use-cases-and-examples\"><strong>Applying distributed cache: use cases and examples<\/strong><\/h2>\n\n\n\n<p>A few example use cases give a window into just how powerful Redis can be:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Application acceleration.<\/strong> By maintaining data in memory, Redis reduces the need for disk-based operations. This significantly lowers the latency bottleneck caused by I\/O operations.<\/li>\n\n\n\n<li><strong>Decreasing network usage.<\/strong> Cached data can be stored in cloud locations proximate to requesting clients. Recourses to master databases are massively reduced, lowering network load and lightening service providers&#8217; bandwidth charges.<\/li>\n\n\n\n<li><strong>Web session data.<\/strong> Redis can store large amounts of concurrent web session data &#8211; again without recourse to databases. This improves performance and makes load balancing more straight-forward.<\/li>\n\n\n\n<li><strong>Scaling.<\/strong> Data-intensive applications don&#8217;t always scale easily. However, Redis makes scaling easier by enabling resources across multiple servers.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-embed alignfull is-type-wp-embed is-provider-codemotion-magazine wp-block-embed-codemotion-magazine\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"0LU6IpE8Ij\"><a href=\"https:\/\/www.codemotion.com\/magazine\/ai-ml\/anonymous-survey-is-ai-changing-how-developers-work\/\">Anonymous Survey: Is AI Changing How Developers Work?<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Anonymous Survey: Is AI Changing How Developers Work?&#8221; &#8212; Codemotion Magazine\" src=\"https:\/\/www.codemotion.com\/magazine\/ai-ml\/anonymous-survey-is-ai-changing-how-developers-work\/embed\/#?secret=BhvE5tFBZg#?secret=0LU6IpE8Ij\" data-secret=\"0LU6IpE8Ij\" width=\"500\" height=\"282\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-real-world-use-case-scenarios\"><strong>Real-world use case scenarios<\/strong><\/h2>\n\n\n\n<p>To get some deeper insights, let&#8217;s dig down into the specifics of some use cases from Insoore.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Time-limited process<\/strong><\/h3>\n\n\n\n<p>The engineers at Insoore use Redis to manage the temporal validity of user operations. For example, a user may be required to perform a particular operation within 24 hours of a request. To trigger this, a link is generated and sent via email or SMS:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">var<\/span> link = $<span class=\"hljs-string\">\"{_externalCaiPageConfiguration.Url}?id{resultSinistro.Entity.Id}\"<\/span>;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This data is stored in the Redis cache using the <strong>TimeValidity<\/strong> feature:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">await<\/span> _outputCacheStore.SetAsync(key, cd.ToByteArray(), <span class=\"hljs-literal\">null<\/span>, linkTimeValidity, cancellationToken);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>When the user responds to post the requested information, the Redis cache is checked for the given key:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">var<\/span> cached = <span class=\"hljs-keyword\">await<\/span> _outputCacheStore.GetAsync($<span class=\"hljs-string\">\"IXB_{request.Key}\"<\/span>, cancellationToken);\nArgumentNullException.ThrowIfNull(cached);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If the key has expired, the operation is blocked.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Api OutputCache<\/strong><\/h3>\n\n\n\n<p>Insoore use cache management to streamline api calls using the<a href=\"https:\/\/www.codemotion.com\/magazine\/backend\/net-async-await-and-its-catches\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\"> .NET<\/a> 7 framework. This introduces a new feature that allows API caching using a <strong>MemoryOutputCacheStore<\/strong>. To activate it, services are configured with <strong>services.AddOutputCache();<\/strong> on registration and then enabled with app.<strong>UseOutputCache();<\/strong><\/p>\n\n\n\n<p>From thereon, .CacheOutput() can be specified in the API Get methods:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">app.MapGet($<span class=\"hljs-string\">\"{Name}\/{{id}}\"<\/span>,\n&#91;Authorize(Roles = Rule)]\n&#91;SwaggerOperation(Summary = $<span class=\"hljs-string\">\"Get the entity by the id\"<\/span>)]\n<span class=\"hljs-keyword\">async<\/span> (&#91;FromRoute] int id, ISender sender, HttpContext context)\n=&gt; <span class=\"hljs-keyword\">await<\/span> sender.Send(<span class=\"hljs-keyword\">new<\/span> GetRequest&lt;TInterface&gt; { Id = id, RequesterId = context.GetId() })\n).WithTags(Name)\n.CacheOutput(<span class=\"hljs-function\"><span class=\"hljs-params\">x<\/span> =&gt;<\/span> x.Tag($<span class=\"hljs-string\">\"{Name}Get\"<\/span>));\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To invalidate the cache, they use <strong>await cache.EvictByTagAsync(cacheKey, cToken)<\/strong>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">app.MapDelete($<span class=\"hljs-string\">\"{Name}\/{{id}}\"<\/span>,\n&#91;Authorize(Roles = Rule)]\n&#91;SwaggerOperation(Summary = $<span class=\"hljs-string\">\"Delete\"<\/span>, Description = <span class=\"hljs-string\">\"Allow to delete the entity\"<\/span>)]\n<span class=\"hljs-keyword\">async<\/span> (int id, IOutputCacheStore cache, CancellationToken cToken, ISender sender, HttpContext context) =&gt;\n{\n<span class=\"hljs-keyword\">await<\/span> cache.EvictByTagAsync(cacheKey, cToken);\n<span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">await<\/span> sender.Send(<span class=\"hljs-keyword\">new<\/span> DeleteRequest&lt;TInterface&gt; { Id = id, RequesterId = context.GetId() });\n}).WithTags(Name);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>However, while this works, there is a problem. To store its entries, <strong>MemoryOutputCacheStore<\/strong> uses a <strong>MemoryCache <\/strong>which is &#8220;basically a dictionary&#8221;. This can lead to problems when scaling. For example, consider 2 instances of the same API, A and B. Instance A caches an entity. Instance B invalidates the cached entity, updates it and caches it again. But now A and B have different versions of the cached entity. To solve this, Insoore used Redis to create a customised OutputCachestore that synchronises cache updates with just a few lines of code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">public class RedisOutputCacheStore : IOutputCacheStore\n{\nprivate readonly IConnectionMultiplexer _connectionMultyplexer;\npublic RedisOutputCacheStore(IConnectionMultiplexer connectionMultiplexer)\n{\n_connectionMultyplexer = connectionMultiplexer;\n}\n\npublic static class RediOutputCacheServiceCollectionExtensions\n{\npublic static IServiceCollection AddRedisOutputCache(this IServiceCollection services)\n{\nservices.AddOutputCache();\nservices.RemoveAll<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">IOutputCacheStore<\/span>&gt;<\/span>();\nservices.AddSingleton<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">IOutputCacheStore,<\/span> <span class=\"hljs-attr\">RedisOutputCacheStore<\/span>&gt;<\/span>();\nreturn services;\n}\n}\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The interface method is then implemented with Redis cache:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> ValueTask EvictByTagAsync(string tag, CancellationToken cancellationToken)\n\n<span class=\"hljs-keyword\">public<\/span> ValueTask&lt;byte&#91;]<span class=\"hljs-meta\">?&gt;<\/span> GetAsync(string key, CancellationToken cancellationToken)\n\n<span class=\"hljs-keyword\">public<\/span> ValueTask SetAsync(string key, byte&#91;] value, string&#91;]? tags, TimeSpan validFor, CancellationToken cancellationToken)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\"><strong>Api Auth Policies<\/strong><\/h3>\n\n\n\n<p>Sometimes it&#8217;s necessary to control access to API methods. <strong>Access rules are stored in a database, but if these need to be queried to validate each API call<\/strong>, the benefits of caching are lost. To maintain consistency, Insoore stores these rules in a Redis cache:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">var<\/span> ruleSet = <span class=\"hljs-keyword\">await<\/span> _context.BloccoAccesso.Where(<span class=\"hljs-function\"><span class=\"hljs-params\">x<\/span> =&gt;<\/span> x.UtenteId == utente.Id).Select(<span class=\"hljs-function\"><span class=\"hljs-params\">x<\/span> =&gt;<\/span> x.MapTo&lt;BloccoAccessoDto, BloccoAccessoDao&gt;(x)).ToListAsync();\n\n<span class=\"hljs-keyword\">var<\/span> key = $<span class=\"hljs-string\">\"IXB_Auth_{utente.Id}\"<\/span>;\n<span class=\"hljs-keyword\">await<\/span> _cache.SetAsync(key, ruleSet.ToByteArray(), <span class=\"hljs-literal\">null<\/span>, TimeSpan.FromMinutes(TimeValidity), cancellationToken);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>They have also created custom Middleware to process the authorisation request: <strong>app.UseMiddleware&lt;UtenzeAuthorizationMiddleware&gt;();<\/strong>. This method retrieves rules relating to the current user from Redis, and if there are any blocking rules for the requested API method, the request is denied:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">\n<span class=\"hljs-keyword\">var<\/span> key = $<span class=\"hljs-string\">\"IXB_Auth_{userId}\"<\/span>;\n<span class=\"hljs-keyword\">var<\/span> path = httpContextAccessor.HttpContext?.Request?.Path.Value;\n<span class=\"hljs-keyword\">var<\/span> method = httpContextAccessor.HttpContext?.Request?.Method;\n\n<span class=\"hljs-keyword\">var<\/span> cachedRules = <span class=\"hljs-keyword\">await<\/span> cache.GetAsync(key, <span class=\"hljs-keyword\">new<\/span> CancellationToken());\n\n<span class=\"hljs-keyword\">var<\/span> rules = cachedRules?.Deserialize&lt;List&lt;BloccoAccessoDto&gt;&gt;();\n\n<span class=\"hljs-keyword\">if<\/span> (rules?.Any(<span class=\"hljs-function\"><span class=\"hljs-params\">x<\/span> =&gt;<\/span> x.Match(method, path)) ?? <span class=\"hljs-literal\">false<\/span>)\n{\n<span class=\"hljs-keyword\">await<\/span> <span class=\"hljs-keyword\">new<\/span> UnauthorizedAccessException($<span class=\"hljs-string\">\"User:{userId} Method:{method} Path:{path}\"<\/span>).ManageHttpException(_logger, context);\n<span class=\"hljs-keyword\">return<\/span>;\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\"><strong>Best practices and tips for distributed cache<\/strong><\/h2>\n\n\n\n<p>To finish, let&#8217;s take a look at some best practices for Redis and distributed cache management.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Leverage indexes.<\/strong> The key-value paradigm is central to Redis, but it&#8217;s important to use indexing and sorting strategies that match your data types to get the best performance. For example, you may choose sorted sets as indexes, geospatial entities, IP addresses, lexicographic encoding or full-text indexes.<\/li>\n\n\n\n<li><strong>Manage data storage<\/strong>. Not all data is simple to put in and pull out of structures. In such cases, you can serialise your data and represent it using JSON, but this can be inefficient. A faster alternative is to RedisJSON to manipulate complex datatypes.<\/li>\n\n\n\n<li><strong>Store images and large files in memory<\/strong>. While you may be tempted to reference images by file paths, this is inefficient and doesn&#8217;t make the best of distributed cache&#8217;s potential. However, Redis allows you to use binary formats directly without conversion, which will be much more efficient.<\/li>\n\n\n\n<li><strong>Use the right modelling for time series data<\/strong>. Depending on your application, you can use different access patterns to order data temporally. Choose sorted sets, lexicographic sorted sets or bitfields as appropriate.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.insoore.com\/Home\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"976\" height=\"250\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/BANNER_FOOTER_-APR23_insoore_1.png\" alt=\"distributed cache, Insoore.\" class=\"wp-image-20637\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/BANNER_FOOTER_-APR23_insoore_1.png 976w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/BANNER_FOOTER_-APR23_insoore_1-300x77.png 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/BANNER_FOOTER_-APR23_insoore_1-768x197.png 768w\" sizes=\"auto, (max-width: 976px) 100vw, 976px\" \/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Distributed cache can improve the responsiveness of today&#8217;s high-performance web and mobile apps. At heart it&#8217;s a simple concept, but, when used well, it can bring improved capacity and flexibility to networked systems. As well as classic caching scenarios, distributed cache systems like Redis offer an alternative to standard databases when handling working data. In&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/\">Read more<\/a><\/p>\n","protected":false},"author":64,"featured_media":20639,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[36],"tags":[10010,3360],"collections":[],"class_list":{"0":"post-20636","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-backend","8":"tag-cache","9":"tag-database","10":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Distributed Cache: How to Boost System Responsiveness - Codemotion Magazine<\/title>\n<meta name=\"description\" content=\"Read this article to learn how Redis can help optimize response times when working with third parties, mobile and web apps.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Distributed Cache: How to Boost System Responsiveness\" \/>\n<meta property=\"og:description\" content=\"Read this article to learn how Redis can help optimize response times when working with third parties, mobile and web apps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-04-11T08:21:54+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-04-11T08:50:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"853\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Codemotion\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Codemotion\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/\"},\"author\":{\"name\":\"Codemotion\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/201bb98b02412383686cced7521b861c\"},\"headline\":\"Distributed Cache: How to Boost System Responsiveness\",\"datePublished\":\"2023-04-11T08:21:54+00:00\",\"dateModified\":\"2023-04-11T08:50:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/\"},\"wordCount\":1190,\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg\",\"keywords\":[\"cache\",\"Database\"],\"articleSection\":[\"Backend\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/\",\"name\":\"Distributed Cache: How to Boost System Responsiveness - Codemotion Magazine\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg\",\"datePublished\":\"2023-04-11T08:21:54+00:00\",\"dateModified\":\"2023-04-11T08:50:19+00:00\",\"description\":\"Read this article to learn how Redis can help optimize response times when working with third parties, mobile and web apps.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#primaryimage\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg\",\"width\":1280,\"height\":853,\"caption\":\"distributed cache, how to boost system responsiveness\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Backend\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/backend\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Distributed Cache: How to Boost System Responsiveness\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Codemotion.Italy\/\",\"https:\/\/x.com\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/201bb98b02412383686cced7521b861c\",\"name\":\"Codemotion\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/cropped-codemotionlogo-150x150.png\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/cropped-codemotionlogo-150x150.png\",\"caption\":\"Codemotion\"},\"description\":\"Articles wirtten by the Codemotion staff. Tech news, inspiration, latest treends in software development and more.\",\"sameAs\":[\"https:\/\/x.com\/CodemotionIT\"],\"url\":\"https:\/\/www.codemotion.com\/magazine\/author\/codemotion-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Distributed Cache: How to Boost System Responsiveness - Codemotion Magazine","description":"Read this article to learn how Redis can help optimize response times when working with third parties, mobile and web apps.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/","og_locale":"en_US","og_type":"article","og_title":"Distributed Cache: How to Boost System Responsiveness","og_description":"Read this article to learn how Redis can help optimize response times when working with third parties, mobile and web apps.","og_url":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2023-04-11T08:21:54+00:00","article_modified_time":"2023-04-11T08:50:19+00:00","og_image":[{"width":1280,"height":853,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg","type":"image\/jpeg"}],"author":"Codemotion","twitter_card":"summary_large_image","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"Codemotion","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/"},"author":{"name":"Codemotion","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/201bb98b02412383686cced7521b861c"},"headline":"Distributed Cache: How to Boost System Responsiveness","datePublished":"2023-04-11T08:21:54+00:00","dateModified":"2023-04-11T08:50:19+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/"},"wordCount":1190,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg","keywords":["cache","Database"],"articleSection":["Backend"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/","url":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/","name":"Distributed Cache: How to Boost System Responsiveness - Codemotion Magazine","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg","datePublished":"2023-04-11T08:21:54+00:00","dateModified":"2023-04-11T08:50:19+00:00","description":"Read this article to learn how Redis can help optimize response times when working with third parties, mobile and web apps.","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg","width":1280,"height":853,"caption":"distributed cache, how to boost system responsiveness"},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/backend\/distributed-cache\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Backend","item":"https:\/\/www.codemotion.com\/magazine\/backend\/"},{"@type":"ListItem","position":3,"name":"Distributed Cache: How to Boost System Responsiveness"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/201bb98b02412383686cced7521b861c","name":"Codemotion","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/cropped-codemotionlogo-150x150.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/cropped-codemotionlogo-150x150.png","caption":"Codemotion"},"description":"Articles wirtten by the Codemotion staff. Tech news, inspiration, latest treends in software development and more.","sameAs":["https:\/\/x.com\/CodemotionIT"],"url":"https:\/\/www.codemotion.com\/magazine\/author\/codemotion-2\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-600x400.jpg","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-600x600.jpg","author_info":{"display_name":"Codemotion","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/codemotion-2\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg",1280,853,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-150x150.jpg",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-300x200.jpg",300,200,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-768x512.jpg",768,512,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-1024x682.jpg",1024,682,true],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg",1280,853,false],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg",1280,853,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280.jpg",100,67,false],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-180x128.jpg",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-896x504.jpg",896,504,true],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-400x225.jpg",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-600x400.jpg",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/04\/technology-gc32049edc_1280-600x600.jpg",600,600,true]},"uagb_author_info":{"display_name":"Codemotion","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/codemotion-2\/"},"uagb_comment_info":0,"uagb_excerpt":"Distributed cache can improve the responsiveness of today&#8217;s high-performance web and mobile apps. At heart it&#8217;s a simple concept, but, when used well, it can bring improved capacity and flexibility to networked systems. As well as classic caching scenarios, distributed cache systems like Redis offer an alternative to standard databases when handling working data. In&#8230;&hellip;","lang":"en","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/20636","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/64"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=20636"}],"version-history":[{"count":6,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/20636\/revisions"}],"predecessor-version":[{"id":20649,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/20636\/revisions\/20649"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/20639"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=20636"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=20636"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=20636"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=20636"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}