<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.socialstack.dev/index.php?action=history&amp;feed=atom&amp;title=API_Caching</id>
	<title>API Caching - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.socialstack.dev/index.php?action=history&amp;feed=atom&amp;title=API_Caching"/>
	<link rel="alternate" type="text/html" href="https://wiki.socialstack.dev/index.php?title=API_Caching&amp;action=history"/>
	<updated>2026-10-16T01:43:49Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.36.2</generator>
	<entry>
		<id>https://wiki.socialstack.dev/index.php?title=API_Caching&amp;diff=567&amp;oldid=prev</id>
		<title>Luke at 19:35, 30 August 2023</title>
		<link rel="alternate" type="text/html" href="https://wiki.socialstack.dev/index.php?title=API_Caching&amp;diff=567&amp;oldid=prev"/>
		<updated>2023-08-30T19:35:57Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en-GB&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:35, 30 August 2023&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;It&amp;#039;s often the case that you have at least a few [[entities]] which are accessed much more often than they are updated. Typically a site&amp;#039;s throughput is limited by the database so the less database traffic that happens the higher that throughput will be. SocialStack has a built in caching mechanism which allows you to mark an entity as cached. This means the list of all entities of that type is obtained once during server startup and then kept up to date through the [[ContentSync|internal server mesh network]].&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;It&amp;#039;s often the case that you have at least a few [[entities]] which are accessed much more often than they are updated. Typically a site&amp;#039;s throughput is limited by the database so the less database traffic that happens the higher that throughput will be. SocialStack has a built in caching mechanism which allows you to mark an entity as cached. This means the list of all entities of that type is obtained once during server startup and then kept up to date through the [[ContentSync|internal server mesh network]].&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Caching therefore works best if you cache things accessed frequently but changed rarely. Some built in examples are site configuration, locales and the pages of your site. These are all cached by default.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Caching therefore works best if you cache things accessed frequently but changed rarely&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;. As cached objects are stored in your web servers memory, be careful not to cache something huge such as a type with 10M+ rows unless you have the RAM to spare&lt;/ins&gt;. Some built in examples are site configuration, locales and the pages of your site. These are all cached by default.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= Usage =&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= Usage =&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Luke</name></author>
	</entry>
	<entry>
		<id>https://wiki.socialstack.dev/index.php?title=API_Caching&amp;diff=560&amp;oldid=prev</id>
		<title>Luke: /* Functionality */</title>
		<link rel="alternate" type="text/html" href="https://wiki.socialstack.dev/index.php?title=API_Caching&amp;diff=560&amp;oldid=prev"/>
		<updated>2023-08-30T18:36:41Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Functionality&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en-GB&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 18:36, 30 August 2023&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l24&quot;&gt;Line 24:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 24:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The cache reuses objects whenever possible so when you ask a caching service to get or list objects then little to no allocations actually happen. These calls also return instantaneously as the object is coming from an already loaded in-memory data structure. In the example above, if you ask &amp;quot;ThingService&amp;quot; to get object with ID #14, that returned object is returned immediately, comes from the cache and is also reused.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The cache reuses objects whenever possible so when you ask a caching service to get or list objects then little to no allocations actually happen. These calls also return instantaneously as the object is coming from an already loaded in-memory data structure. In the example above, if you ask &amp;quot;ThingService&amp;quot; to get object with ID #14, that returned object is returned immediately, comes from the cache and is also reused.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;***&lt;/del&gt;Because the object is reused, avoid changing its fields anywhere other than via Update&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;***&lt;/del&gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;#039;&amp;#039;&amp;#039;&lt;/ins&gt;Because the object is reused, avoid changing its fields anywhere other than via Update&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;#039;&amp;#039;&amp;#039;&lt;/ins&gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Luke</name></author>
	</entry>
	<entry>
		<id>https://wiki.socialstack.dev/index.php?title=API_Caching&amp;diff=559&amp;oldid=prev</id>
		<title>Luke: Created page with &quot;It&#039;s often the case that you have at least a few entities which are accessed much more often than they are updated. Typically a site&#039;s throughput is limited by the databas...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.socialstack.dev/index.php?title=API_Caching&amp;diff=559&amp;oldid=prev"/>
		<updated>2023-08-30T18:35:36Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;It&amp;#039;s often the case that you have at least a few &lt;a href=&quot;/index.php?title=Entities&quot; title=&quot;Entities&quot;&gt;entities&lt;/a&gt; which are accessed much more often than they are updated. Typically a site&amp;#039;s throughput is limited by the databas...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;It&amp;#039;s often the case that you have at least a few [[entities]] which are accessed much more often than they are updated. Typically a site&amp;#039;s throughput is limited by the database so the less database traffic that happens the higher that throughput will be. SocialStack has a built in caching mechanism which allows you to mark an entity as cached. This means the list of all entities of that type is obtained once during server startup and then kept up to date through the [[ContentSync|internal server mesh network]].&lt;br /&gt;
&lt;br /&gt;
Caching therefore works best if you cache things accessed frequently but changed rarely. Some built in examples are site configuration, locales and the pages of your site. These are all cached by default.&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&lt;br /&gt;
To make an entity use the cache, simply call Cache(); from within the service constructor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public ThingService() {&lt;br /&gt;
&lt;br /&gt;
    // &amp;quot;Thing&amp;quot; entities will be cached.&lt;br /&gt;
    Cache();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If it is a thirdparty service and you would like to avoid editing its source to allow for easier updates, you can also call Cache(); via the Events.Service.AfterStart event.&lt;br /&gt;
&lt;br /&gt;
= Functionality =&lt;br /&gt;
&lt;br /&gt;
The cache reuses objects whenever possible so when you ask a caching service to get or list objects then little to no allocations actually happen. These calls also return instantaneously as the object is coming from an already loaded in-memory data structure. In the example above, if you ask &amp;quot;ThingService&amp;quot; to get object with ID #14, that returned object is returned immediately, comes from the cache and is also reused.&lt;br /&gt;
&lt;br /&gt;
***Because the object is reused, avoid changing its fields anywhere other than via Update***.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// private ThingService _thingService;&lt;br /&gt;
&lt;br /&gt;
// This returns instantly with a reused object.&lt;br /&gt;
var thing14 = await _thingService.Get(context, 14);&lt;br /&gt;
&lt;br /&gt;
// Because it&amp;#039;s reused, do not edit fields!&lt;br /&gt;
// thing14.Name = &amp;quot;do not do this&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// The only correct way to update fields is via the usual update call:&lt;br /&gt;
thing14 = await _thingService.Update(context, thing14, (Context c, Thing updateable) =&amp;gt; {&lt;br /&gt;
    updateable.Name = &amp;quot;Updated Name&amp;quot;;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Performance =&lt;br /&gt;
&lt;br /&gt;
Because cached services are not depending on the database and do not allocate, they have extremely high throughput. You can use service Get hundreds of millions of times per second without risking long GC pauses (not that you would ever put this much traffic on one server though!). The JSON serialisation process also avoids as many allocations as possible and can also return more than 10 million results per second via a websocket. The limiting factor is usually the network bandwidth.&lt;br /&gt;
&lt;br /&gt;
Note that the use of the websocket is important if you are expecting this level of throughput being necessary. That is because the context needs to collect the user information which usually involves the database (the user service is rarely set to being cached, but you can do that too) and this context load only occurs once on a websocket.&lt;br /&gt;
&lt;br /&gt;
= ID Assignment =&lt;br /&gt;
&lt;br /&gt;
Because caching a service is primarily done for performance, enabling the cache also makes a service switch ID assignment model. This is covered in more detail on the [[ContentSync|clustering mechanics page]].&lt;/div&gt;</summary>
		<author><name>Luke</name></author>
	</entry>
</feed>