<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="59495" data-post-id="59495">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dom" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dom/120/9313_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dom
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Have you tried processing the request in the agent process rather than the user handler process? If the request is small but the rules are large, it would require a lot less data transfer between processes. The downside is the agent becomes a bottleneck, but it’s very easy to create a pool of them as suggested above.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59495" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-59495" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59495"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="59501" data-post-id="59501">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="tap349" data-post="1" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tap349/48/9336_2.png" class="avatar"> tap349:</div>
<blockquote>
<p>And if I have 1000 users</p>
</blockquote>
</aside>
<p>You may have your reasons for not divulging any details about your processing requirements - so it is possible that you are absolutely correct that you need a separate copy of the data for each user - and then again that may simply be a superficially <em>convenient</em> choice.</p>
<p>How many <em>simultaneous</em> requests do you <em>reasonably</em> expect to be running against the data set? How large is the result that the requestor is going to get back?</p>
<p>In the BEAM environment it may make more sense to separate the “request” logic from the user’s client code and instead use that logic to build a short lived process that runs the logic against it’s own copy to produce the result. While that may lead to more copying it may actually require far fewer <em>simultaneous</em> copies of the data in memory and process termination makes GC extremely simple.</p>
<p>To cut down on the copying, processes could be reused a finite number of times or indefinitely (i.e. process pools as already suggested).</p>
<p>Copying could also be reduced/eliminated by partitioning the data in some logical way so that it could be efficiently accessed and shared (as already mentioned via ETS and/or distributing data dependent processing among multiple processes).</p>
<aside class="quote no-group">
<blockquote>
<p>but I’m still a little bit surprised that Elixir/BEAM copies all the data on each read from Agent process, that there are no optimizations in this regard since it must be a common case.</p>
</blockquote>
</aside>
<p>Shouldn’t be a surprise:</p>
<p><a href="https://forum.elixirforum.com/t/erlang-programming-erlang-pragprog/6085" rel="nofollow">Erlang Programming 2e: Introduction: p. xiii:</a></p>
<blockquote>
<p>Erlang belongs to the family of <em>functional programming languages</em>. Functional programming forbids code with side effects. Side effects and concurrency don’t mix. In Erlang it’s OK to mutate state within an individual process but not for one process to tinker with the state of another process. Erlang has no mutexes, no synchronized methods, and <strong>none of the paraphernalia of shared memory programming</strong>.</p>
</blockquote>
<blockquote>
<p>Processes interact by one method, and one method only, by exchanging messages. <strong>Processes share no data with other processes</strong>. This is the reason why we can easily distribute Erlang programs over multicores or networks.<br>
When we write an Erlang program, we do not implement it as a single process that does everything; <strong>we implement it as large numbers of small processes that do simple things and communicate with each other</strong>.</p>
</blockquote>
<p>The same essentially applies to Elixir. Sharing is convenient but that convenience comes at a cost - it’s all about tradeoffs. Furthermore some find the utility of Agents questionable while most see them as limited, see <a href="https://forum.elixirforum.com/t/discussion-about-uses-for-agent-processes/4214" rel="nofollow">this recent topic</a>.</p>
<aside class="quote no-group" data-username="tap349" data-post="9" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tap349/48/9336_2.png" class="avatar"> tap349:</div>
<blockquote>
<p>As far as I understand, Agent is GenServer as well. So I must be already using it )</p>
</blockquote>
</aside>
<p>Agent is a specialization that focuses entirely on state. GenServer embodies the more general notion of a process minding it’s own state and maintaining full control over access (via messaging) and mutation of that state.<br>
In Elixir the <a href="https://hexdocs.pm/elixir/Task.html" rel="noopener nofollow ugc">Task</a> is often used for short-lived processes but GenServers will still be used for one-off processing when multiple processes have to coordinate processing in the pursuit of a common objective.</p>
<p>GenServer is the fundamental building block, Task and Agent are mere convenience specializations that are typically only useful under the most trivial of circumstances.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59501" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-59501" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59501"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="59814" data-post-id="59814">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="rvirding" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/rvirding/120/1409_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  rvirding
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Erlang</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="cdegroot" data-post="4" data-topic="10328" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cdegroot/48/4644_2.png" class="avatar"> cdegroot:</div>
<blockquote>
<aside class="quote no-group" data-username="tap349" data-post="1" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tap349/48/9336_2.png" class="avatar"> tap349:</div>
<blockquote>
<p>Using ETS doesn’t seem to solve the problem.</p>
</blockquote>
</aside>
<p>I don’t understand that, because storing lots of in-memory state in ETS usually works fine. Unless of course, you still copy the data out of ETS for every request…</p>
</blockquote>
</aside>
<p>ETS keeps its data entirely separate from all processes so when you access an ETS you copy the between the table and the process. <strong>HOWEVER</strong> you do not copy the whole table each time only the elements you actually access. This does mean you should not store all the data in one element but in multiple elements and you the key to select which element.</p>
<p>Actually there is no way to avoid copying data if you are sharing data between processes, keeping it in an ETS table or storing it somewhere “outside” the erlang/elixir system. It’s a fact of life. Just make sure you can access it in small chunks.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59814" data-batch-url="/posts/batch_likers">
                        8
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-59814" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59814"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="59941" data-post-id="59941">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tap349" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tap349/120/9336_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tap349
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="cdegroot" data-post="10" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cdegroot/48/4644_2.png" class="avatar"> cdegroot:</div>
<blockquote>
<p>Compile the set of rules. Clearly it’s code, not data. Problem solved.</p>
</blockquote>
</aside>
<p>Set of rules are loaded when applications starts - they are stored in YML because they are meant to be edited by ordinary users.</p>
<p>Correct me, please, if I’m wrong - by compilation you mean hard-coding this data somewhere in config file? In this case it wouldn’t work because rules should be stored in user-friendly format (YML is user-friendly enough IMO <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> ).</p>
<aside class="quote no-group" data-username="cdegroot" data-post="10" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cdegroot/48/4644_2.png" class="avatar"> cdegroot:</div>
<blockquote>
<p>Another way - depending on the problem - would be to have a pool of workers that each have a copy of the ruleset as state and something like poolboy to route requests; that would also get rid of the copying.</p>
</blockquote>
</aside>
<p>So a limited number of processes (workers) have their own copies of data while user processes just pass request payload into workers to calculate the result? Well, that sounds reasonable - I’ll need to move all calculations from user processes into workers but that should not be a problem.</p>
<p>The only downside I see here is that I’ll be able to process max <code>&lt;pool_size&gt;</code> requests concurrently - but it must be okay for me too.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59941" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-59941" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59941"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="59942" data-post-id="59942">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tap349" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tap349/120/9336_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tap349
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="dom" data-post="12" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dom/48/9313_2.png" class="avatar"> dom:</div>
<blockquote>
<p>Have you tried processing the request in the agent process rather than the user handler process?</p>
</blockquote>
</aside>
<p>AFAIK agents are used for storing state only - and putting business logic inside them would break this contract. But moving logic and data access into dedicated processes (not necessarily agents) looks promising.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59942" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-59942" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59942"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="59946" data-post-id="59946">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tap349" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tap349/120/9336_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tap349
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="peerreynders" data-post="13" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/48/5826_2.png" class="avatar"> peerreynders:</div>
<blockquote>
<p>You may have your reasons for not divulging any details about your processing requirements - so it is possible that you are absolutely correct that you need a separate copy of the data for each user - and then again that may simply be a superficially convenient choice.</p>
</blockquote>
</aside>
<p>Thanks for detailed answer.</p>
<p>I don’t have strict requirements. I can’t say that I need a separate copy for each user - this is just how it’s currently implemented (maybe because it’s a ‘convenient choice’ or due to lack of knowledge of how to do it efficiently).</p>
<p>My application is kind of microservice that receives request (each having <code>user_id</code> and some payload) and calculates the result using this payload and the whole set of rules (the very data).<br>
When request for new <code>user_id</code> is received, a separate user handler process (<code>GenServer</code>) is created for this user - this process reads data from agent and calculates the result. While there are no many simultaneous requests, there might be lots of long-running user handler processes (1k-10k). Result the requestor is going to get back is not large (about 1kb).</p>
<p>To summarize (for myself and for future readers) I have the following options:</p>
<ol>
<li>spawn a short-lived process (say, <code>Task</code>) from inside user handler process - this task reads data from agent, calculates the result, returns it to user process and dies</li>
</ol>
<p>(+) when the task is terminated, it’s easy for GC to clean the copy of data read from agent inside terminated task<br>
(-) data is still copied a lot which has its own impact on performance (copying 10-20 MB in memory is cheap but still not free)</p>
<ol start="2">
<li>use a limited set (pool) of long-running processes (workers) each having their own copy of data (just like <a class="mention" href="/u/cdegroot" rel="nofollow">@cdegroot</a> suggested) in their states</li>
</ol>
<p>(+) data is copied (and duplicated in memory) N times only (where N is a pool size)</p>
<p>This resembles solution suggested by <a class="mention" href="/u/dom" rel="nofollow">@dom</a> but here another abstraction (worker) is introduced between user handler process and agent.</p>
<ol start="3">
<li>partition data so that it’s accessed ‘in small chunks’ (either from agent or ETS)</li>
</ol>
<p>(+) amount of copied data is reduced - this alleviates the problem but doesn’t remove it completely<br>
(-) in my case that wouldn’t work since I cannot partition data - I need to access it fully in each request</p>
<ol start="4">
<li>use <code>fastglobal</code> package</li>
</ol>
<p>(+) viable alternative if the problem can’t be solved using standard OTP tools<br>
(-) it’s an external dependency</p>
<p>Taking all pros and cons into consideration, the 2nd solution looks like the best one for me now.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59946" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-59946" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59946"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="59949" data-post-id="59949">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="tap349" data-post="17" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tap349/48/9336_2.png" class="avatar"> tap349:</div>
<blockquote>
<ol start="2">
<li>use a limited set (pool) of long-running processes (workers) each having their own copy of data (just like <a class="mention" href="/u/cdegroot" rel="nofollow">@cdegroot</a> suggested) in their states</li>
</ol>
<p>(+) data is copied (and duplicated in memory) N times only (where N is a pool size)</p>
<p>This resembles solution suggested by <a class="mention" href="/u/dom" rel="nofollow">@dom</a> but here another abstraction (worker) is introduced between user handler process and agent.</p>
</blockquote>
</aside>
<p>This seems to be the most reasonable approach (in my opinion). Ditch the agent and just initialize each worker with it’s own copy of the data. Have a look at <a href="https://github.com/thestonefox/elixir_poolboy_example" rel="noopener nofollow ugc">elixir_poolboy_example</a>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59949" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-59949" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59949"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="59957" data-post-id="59957">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dom" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dom/120/9313_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dom
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="tap349" data-post="17" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tap349/48/9336_2.png" class="avatar"> tap349:</div>
<blockquote>
<p>This resembles solution suggested by <a class="mention" href="/u/dom" rel="nofollow">@dom</a> but here another abstraction (worker) is introduced between user handler process and agent.</p>
</blockquote>
</aside>
<p>I was suggesting that you can prototype that approach with very little change to your code, by doing the processing directly in the agent. Then if you’re happy with the performance you can ditch the agent and replace it with a (pool of) GenServer workers. You don’t need both agent and worker.</p>
<p>After that you can make all your workers join a process group (with pg2 for instance) and broadcast a message to that group when the config is updated.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59957" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-59957" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59957"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #18"></div>
  </section>
</div>
    <div class="postbit" id="59962" data-post-id="59962">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="cdegroot" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cdegroot/120/4644_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  cdegroot
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="tap349" data-post="15" data-topic="10328">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tap349/48/9336_2.png" class="avatar"> tap349:</div>
<blockquote>
<p>Set of rules are loaded when applications starts - they are stored in YML because they are meant to be edited by ordinary users.</p>
<p>Correct me, please, if I’m wrong - by compilation you mean hard-coding this data somewhere in config file? In this case it wouldn’t work because rules should be stored in user-friendly format (YML is user-friendly enough IMO <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> ).</p>
</blockquote>
</aside>
<p>Compilation means transforming stuff from user-friendly to machine-executable format. Read the Yaml, convert it to Erlang/Elixir/LFE code, then compile that source, and you have executable code - which seems to be what you want.</p>
<p>Usually, when you find you’re writing an interpreter, you’re doing it wrong. See also: Ruby <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59962" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-59962" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59962"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="60216" data-post-id="60216">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="rvirding" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/rvirding/120/1409_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  rvirding
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Erlang</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This has been done in some packages, mochiweb iirc. The trade off is working out if I need/want to modify this data while the system is running, if so I would have to regenerate and recompile this file at runtime. Not difficult but may not be acceptable.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="60216" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/how-to-store-lots-of-data-in-memory/10328/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-60216" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="60216"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>