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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="venkatd" data-post="11" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/venkatd/48/9419_2.png" class="avatar"> venkatd:</div>
<blockquote>
<p>Is it right to think that benchmarking can be a waste of time vs. actually running a production workload and inspecting?</p>
</blockquote>
</aside>
<p>If you are solving business problems with your product, I would say in most cases yeah.</p>
<p>I interviewed a few years back for a company that was claiming to run benchmark tests on one of their telecom products written in golang, claiming it made their clients happy. Then afterwards they said that they usually have incidents and you need to carry the work laptop with you, I guess it’s all about setting the right priorities and raw performance is never in the top ones for such products. I obviously declined that offer after hearing that, as that is a simple example of a dysfunctional product.</p>
<aside class="quote no-group" data-username="venkatd" data-post="11" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/venkatd/48/9419_2.png" class="avatar"> venkatd:</div>
<blockquote>
<p>What does your workflow tend to be? You produce a flame graph, identify the hot spots, then try rewriting those to be faster?</p>
</blockquote>
</aside>
<p>It’s all about understanding and measuring correctly the performance of parts of your system. The easiest way these days is to send telemetry from the parts of the application that interests you. The tricky thing is that there is no rule of thumb on how to do it optimally, so depending on how you implement it, that will determine the quality of insights you will get.</p>
<aside class="quote no-group" data-username="venkatd" data-post="11" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/venkatd/48/9419_2.png" class="avatar"> venkatd:</div>
<blockquote>
<p>What does your workflow tend to be? You produce a flame graph, identify the hot spots, then try rewriting those to be faster?</p>
</blockquote>
</aside>
<p>I want to enforce the same point as <a class="mention" href="/u/dimitarvp" rel="nofollow">@dimitarvp</a> above. If your processing is already as concurrent as it can be, trying to optimize single-threaded raw speed is a fool’s errand in most cases.</p>
<p>If that is critical for the product, then the most optimal way is to offload it to a low-level language like c/rust/golang, otherwise you might get into the situation where you have a horrible codebase that nobody can understand and maintain, while providing some mediocre optimizations.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="352504" data-batch-url="/posts/batch_likers">
                        0
                      </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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-352504" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352504"
                     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="352508" data-post-id="352508">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for the tips!</p>
<p>To be honest, there is not a specific performance goal we have in mind.</p>
<p>What we learned is that, in our industry, nobody is explicitly asking for performance. Most of the products are so slow, there is a bit of learned helplessness. They just accept products are slow.</p>
<p>But we spent a few days optimizing the frontend rendering performance of one of the main pages in our app and we got a lot of very happy customers. Nobody asked for it–but we believe they didn’t ask because they didn’t think fast software was possible <img src="https://forum.elixirforum.com/images/emoji/apple/cry.png?v=15" title=":cry:" class="emoji" alt=":cry:" loading="lazy" width="20" height="20"></p>
<p>Now we are thinking to invest some percentage of our time making features they use heavily run faster.</p>
<p>It does seem, though, the first step to any of this is improving the skill of diagnosing why something is slow. Otherwise, as you suggest, I risk going off in a rabbit hole and complicating code for no reason. Or optimizing the wrong thing entirely.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="352508" 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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-352508" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352508"
                     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="352509" data-post-id="352509">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="venkatd" data-post="11" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/venkatd/48/9419_2.png" class="avatar"> venkatd:</div>
<blockquote>
<p>Is it right to think that benchmarking can be a waste of time vs. actually running a production workload and inspecting?</p>
</blockquote>
</aside>
<p>As always … depends on case. Most people don’t count each 1s loss even if they would coun all software “lags” then they would have a very huge amount of lost time. So it’s usually about if the <strong>product</strong> is ready for it (not you or your team). <img src="https://forum.elixirforum.com/images/emoji/apple/bulb.png?v=15" title=":bulb:" class="emoji" alt=":bulb:" loading="lazy" width="20" height="20"></p>
<p>Again usually people want to have things that “just works” and therefore it’s not wrong to think that <strong>MVP</strong> does not really need optimisations. That’s said … it also depends on the speed of current software and how the project would scale. In first case too slow speed may be considered a bug and in second one it may be just a matter of time when you would run into possible scale problems. <img src="https://forum.elixirforum.com/images/emoji/apple/thinking.png?v=15" title=":thinking:" class="emoji" alt=":thinking:" loading="lazy" width="20" height="20"></p>
<p>In terms of learning I recommend this way of improving yourself (and therefore your software):</p>
<ol>
<li>
<p>Train your <strong>instinct</strong> - a good one is worth much more than experience (for sure experience does not lose it’s value - it’s just how much instinct is worth) <img src="https://forum.elixirforum.com/images/emoji/apple/brain.png?v=15" title=":brain:" class="emoji" alt=":brain:" loading="lazy" width="20" height="20"></p>
</li>
<li>
<p>Practice - no matter on how small or big projects - you just gain experience <img src="https://forum.elixirforum.com/images/emoji/apple/muscle.png?v=15" title=":muscle:" class="emoji" alt=":muscle:" loading="lazy" width="20" height="20"></p>
</li>
<li>
<p>Feed your instinct with your experience - the instinct is usually unclear and to “decrypt” it properly you have to learn, improve skills and so on … <img src="https://forum.elixirforum.com/images/emoji/apple/chart_with_upwards_trend.png?v=15" title=":chart_with_upwards_trend:" class="emoji" alt=":chart_with_upwards_trend:" loading="lazy" width="20" height="20"></p>
</li>
<li>
<p>Go back to projects you worked at least 6-12 months ago - you should be able to tell what part could be improved by just seeing the code (i.e. without analysing it) <img src="https://forum.elixirforum.com/images/emoji/apple/eyes.png?v=15" title=":eyes:" class="emoji" alt=":eyes:" loading="lazy" width="20" height="20"></p>
</li>
</ol>
<p>If you have completed this list I have one <strong>good</strong> and one <strong>bad</strong> news for you:</p>
<ul>
<li>
<p><strong>Good</strong>: Optimising code should be much easier if not just easy <img src="https://forum.elixirforum.com/images/emoji/apple/smiling_face.png?v=15" title=":smiling_face:" class="emoji" alt=":smiling_face:" loading="lazy" width="20" height="20"></p>
</li>
<li>
<p><strong>Bad</strong>: People learn the whole life, go back to point number <code>1</code> <img src="https://forum.elixirforum.com/images/emoji/apple/smiling_imp.png?v=15" title=":smiling_imp:" class="emoji" alt=":smiling_imp:" loading="lazy" width="20" height="20"></p>
</li>
</ul>
<p>When to rewrite project? Regardless of what other people say things are going forward. If you would not update the code relatively often you would need to rewrite or drop it. It’s good to be up-to-date with most popular hex packages like <code>phoenix</code>. Update to next version is usually not really painful. <img src="https://forum.elixirforum.com/images/emoji/apple/see_no_evil.png?v=15" title=":see_no_evil:" class="emoji" alt=":see_no_evil:" loading="lazy" width="20" height="20"></p>
<p>That’s said you improve, sometimes less and sometimes more, so no matter how up-to-date your code is sometimes you have to rewrite at least one feature. I would suggest to not doing this more often than once per year. <img src="https://forum.elixirforum.com/images/emoji/apple/calendar.png?v=15" title=":calendar:" class="emoji" alt=":calendar:" loading="lazy" width="20" height="20"></p>
<p>Regardless of how much you improve per month it’s still just a month. If you would rewrite even one feature every month then it would make a huge impact on the overall project. On the other side there is always at least one time in each year you usually have more time or just feel better than usually. That “flow” can be used in various ways and I believe that an yearly code review when you have the most strength is just a pleasure. <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" 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="352509" 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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-352509" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352509"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="352510" data-post-id="352510">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think the biggest reasons why Elixir apps that are slow are the following:</p>
<ol>
<li>
<p>No one bothered to capture the non-functional requirements from the client. Therefore there’s no definition of acceptable performance until it’s so bad people complain. And then it’s often too late. If you define these up front and actually create scripts to measure these values AS YOU DEVELOP THEM you will identify and fix perf &amp; scalability issues before they become a problem.</p>
</li>
<li>
<p>A corollary of <span class="hashtag-raw">#1</span>, people didn’t capture the non-functional requirements is because the “initial prototype” often gets upgraded to be the production system. All smart dev groups plan on building it twice. First to (presumably quickly) understand the problem and identify a viable solution path. Second to do it right and make that viable solution sustainable. Alas, more often than not the second effort is never allowed leading to the issues identified in <span class="hashtag-raw">#1</span>. Of course if you’re doing a prototype you shouldn’t focus on premature optimizations. But make sure you’re not kidding yourself about getting that chance to “do it right”.</p>
</li>
<li>
<p>In Elixir-land (inherited from Ruby/Rails land) - making every user interaction hit a database. This is why I try to teach my team Erlang and the actor model before I let them jump into Elixir. Most user interactions for most applications have no business hitting a central point of failure and performance bottleneck that we call a database. 3 tiered architectures are so 1990’s yet they keep coming back over and over. Learn about the wonders of the BEAM concurrency model and OTP behaviors and use them! Databases should be small, specialized, and hidden behind the single actor that needs to manage that persistent state at scale. Everything else should be in in-memory actor processes already in state structured to address your user needs.</p>
</li>
<li>
<p>Trying to do something that really requires full use of the CPU resources in an interpreted language. This is when you need to invoke NIFs and send out to code/apps written in languages like C++. Check and make sure you haven’t just created a naive algorithm that is easily fixed by a more appropriate design. Breaking the problem down into a distributed/parallel solution is pretty easy in Elixir/BEAM and can achieve near linear scalability across multiple CPUs if applicable. If you’ve exhausted this option then you may need to look outside of BEAM-based solutions.</p>
</li>
</ol>
<p>So measurement-wise, you’re indeed correct, it is a dark art. We’ve developed lots of custom tools/scripts to help us do this. We do this at such scales that we have recurring clients who annually hire us to perform large scale capacity and performance tests which we inevitable identify major issues and help them mitigate. For web-based stuff we really like Tsung but it’s really hard to use against LiveView apps so we’re working on options for that. Otherwise I’d say most our tooling and effort is custom for the apps and not very complex. We do a LOT of scripts in Erlang and Python and sometimes Typescript supported by other tools like Varnish and various event reporting tools. It’s definitely an art and, for any complex system we hit, the critical path is never the thing we thought it would be initially. Fun stuff actually. Hard to make a living doing it, alas.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="352510" 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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-352510" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352510"
                     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="352513" data-post-id="352513">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I would turn your ask for having a slow app being gradually reworked to a faster one on its head – IMO you should tell us which slow parts of the code you accelerated and how. Because there’s too much generic advice out there (here on this forum included) that would not be useful to you since it’s so outside your context.</p>
<p>F.ex. many people reach for DB caching but that’s often misguided and a band-aid. Avoiding N+1 queries was actually mind-blowing to some teams I consulted for years ago. “Solution”? Russian doll caching and so many bugs that Salesforce could meet their quarterly profits target fixing only that project.</p>
<p>Another example: waiting, <em>synchronously</em>, for a 3rd party API network call to finish, inside a request-response Phoenix process. And then “Elixir is slow, let’s go back to Python!”. <img src="https://forum.elixirforum.com/images/emoji/apple/person_facepalming.png?v=15" title=":person_facepalming:" class="emoji" alt=":person_facepalming:" loading="lazy" width="20" height="20"></p>
<p>3rd example: replace a semi-complex transactional operation with multi-step Oban job workflow. This is actually quite a good pattern very often, mind you, but in 3 separate projects I consulted for they basically misapplied it severely. All they had to do was have an <code>Ecto.Multi</code> chain, really. I helped them do that, their average workflow execution dropped from 40 seconds to 2-5. Oban is fantastic but you don’t reach for it when you need a single task done synchronously. That team’s old code was scheduling Oban jobs and was synchronously awaiting their finish. Yep, you read that right.</p>
<p>Right tool for the job and all that.</p>
<hr>
<p>To circle back to my main point: it would be beneficial to the community if you helped us understand what was actually slow and how did you fix it. Then, as I said in my older comment, we can give you a more concrete advice.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="352513" 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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-352513" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352513"
                     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="352521" data-post-id="352521">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="venkatd" data-post="11" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/venkatd/48/9419_2.png" class="avatar"> venkatd:</div>
<blockquote>
<p>What does your workflow tend to be? You produce a flame graph, identify the hot spots, then try rewriting those to be faster?</p>
</blockquote>
</aside>
<p>Exactly that. Without knowing what your hotspots are, you are flying blind. You may start optimise some part of the code, that indeed is slow, but it overall impact is negligible, because, for example, it is called only once. On the other hand there may be small and fast function, that can be made faster, that is called all the time, and that small improvement may have tremendous overall impact. For example in our case changing metrics gathering library to Peep gave us like an order of magnitude perf boost (I would need to check how much it was exactly, but for sure results were mindblowing).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="352521" 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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-352521" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352521"
                     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="352522" data-post-id="352522">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lawik" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lawik/120/32028_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lawik
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Nerves Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Michal Muskala who built Jason and the new Erlang :json gave a talk about a lot of how he made it fast. It was given at Code BEAM Berlin last year and should show up online in January or February I believe.</p>
<p>I was there, heard it. Found it quite interesting <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> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="352522" 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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-352522" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352522"
                     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="352532" data-post-id="352532">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Man, I feel like your third point was written by me. I’m sick of seeing projects where every user interaction hits the database. All the projects I worked on in the last three years (I wasn’t doing Elixir before), have been like this. Database queries while “iterating” is something completely normal. Ecto schemas bubbling up to the views - completely normal. Dependency inversion, what’s that? Unit tests, not integration tests (because everything we do hits the database), what’s that? Okay, I’m going on a tangent and a rant here.</p>
<p>There are already some very valuable tips and I’m going to add only one. Separate pure from impure code. Pure code receives data and processes it. One part of the returned value can be a representation of the impure actions that need to be performed. You have to perform a few DB inserts? You might be able to batch them. You might need some set of actions to be “all or nothing”? Put them in a transaction. You have complete freedom to organise your impure actions however you like. As a side effect, pun intended, your pure code is super easy to test,</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="352532" data-batch-url="/posts/batch_likers">
                        5
                      </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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-352532" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352532"
                     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="352545" data-post-id="352545">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="JEG2" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/JEG2/120/936_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  JEG2
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Designing Elixir Systems with OTP</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="krasenyp" data-post="19" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/krasenyp/48/39733_2.png" class="avatar"> krasenyp:</div>
<blockquote>
<p>There are already some very valuable tips and I’m going to add only one. Separate pure from impure code. Pure code receives data and processes it. One part of the returned value can be a representation of the impure actions that need to be performed. You have to perform a few DB inserts? You might be able to batch them. You might need some set of actions to be “all or nothing”? Put them in a transaction. You have complete freedom to organise your impure actions however you like. As a side effect, pun intended, your pure code is super easy to test,</p>
</blockquote>
</aside>
<p>That moment when I regret that I have but one heart to give.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="352545" 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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-352545" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352545"
                     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="352633" data-post-id="352633">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Some great advice in this thread!</p>
<aside class="quote no-group" data-username="Eiji" data-post="14" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/eiji/48/36743_2.png" class="avatar"> Eiji:</div>
<blockquote>
<ul>
<li>Practice - no matter on how small or big projects - you just gain experience <img src="https://forum.elixirforum.com/images/emoji/apple/muscle.png?v=15" title=":muscle:" class="emoji" alt=":muscle:" loading="lazy" width="20" height="20"></li>
</ul>
</blockquote>
</aside>
<p>I agree here I need to start optimizing slow parts of the app where performance has business value.</p>
<aside class="quote no-group" data-username="scherrey" data-post="15" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/scherrey/48/1879_2.png" class="avatar"> scherrey:</div>
<blockquote>
<p>Learn about the wonders of the BEAM concurrency model and OTP behaviors and use them!</p>
</blockquote>
</aside>
<p>We have a service that runs entirely in memory (except writing to an event log) and it runs very quickly. I’m sold on the approach <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="scherrey" data-post="15" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/scherrey/48/1879_2.png" class="avatar"> scherrey:</div>
<blockquote>
<p>This is when you need to invoke NIFs and send out to code/apps written in languages like C++</p>
</blockquote>
</aside>
<p>I think you’re saying yourself, but it feels like Plan A should be to try to make things run as fast as possible before resorting to NIFs because NIFs add complexity and you lose some advantages of the BEAM.</p>
<aside class="quote no-group" data-username="dimitarvp" data-post="16" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>To circle back to my main point: it would be beneficial to the community if you helped us understand what was actually slow and how did you fix it. Then, as I said in my older comment, we can give you a more concrete advice.</p>
</blockquote>
</aside>
<p>For the next thing I need to optimize, i will do just this. I am honestly looking for general advice at this point because performance is an area of more interest to me now.</p>
<aside class="quote no-group" data-username="hauleth" data-post="17" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hauleth/48/18942_2.png" class="avatar"> hauleth:</div>
<blockquote>
<p>Exactly that. Without knowing what your hotspots are, you are flying blind. You may start optimise some part of the code, that indeed is slow, but it overall impact is negligible, because, for example, it is called only once.</p>
</blockquote>
</aside>
<p>It feels like as I am improving this skill, I should first focus on becoming better at diagnosing pref bottlenecks rather before getting too involved in solutions to improve performance. Optimizing seems like two skills - identifying what is slow, then a good mental model of knowing what changes are likely to speed up a particular chunk of code.</p>
<aside class="quote group-Nerves-Core-Team" data-username="lawik" data-post="18" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lawik/48/32028_2.png" class="avatar"> lawik:</div>
<blockquote>
<p>Michal Muskala who built Jason and the new Erlang :json gave a talk about a lot of how he made it fast.</p>
</blockquote>
</aside>
<p>I will try to be patient here!</p>
<aside class="quote no-group" data-username="krasenyp" data-post="19" data-topic="66749">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/krasenyp/48/39733_2.png" class="avatar"> krasenyp:</div>
<blockquote>
<p>You might be able to batch them. You might need some set of actions to be “all or nothing”? Put them in a transaction.</p>
</blockquote>
</aside>
<p>You will be happy to hear that I have been doing this recently. I was inspired by a talk on YouTube called “Moving IO to the edges of your app”. I think patterns like <code>Ecto.Multi</code> are intended to encourage this pattern right?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="352633" 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/any-tips-or-learning-resources-for-writing-highly-performant-elixir-code/66749/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-352633" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="352633"
                     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>