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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Maybe I should backtract to the original question here.</p>
<p>One reason why I introduced the pool in Elixir in Action was precisely to warn the readers about a potential overload when unlimited concurrency is used. So the message you should take from the book is that it’s definitely good to think about overload scenarios. However, I don’t mean to imply that pooling is the only, or the best option in all such cases.</p>
<p>Which brings me to my comment about batching. I made that comment from the standpoint of load control (which is what IMO pooling is also about). The reason why I introduced this approach to the discussion was to show that there are other ways of controlling the load.</p>
<p>I agree with others here that both approaches are effectively stateful. If BEAM or the underlying machine goes down, whatever you’re doing in-flight will be lost.</p>
<p>It is, however, true that with batching you end up with possibly larger crash effects. If the queueing process crashes, you might lose more in-flight data, compared to a single task. Likewise, if the processing of the batched items fails on the consumer side, you might end up with more failed requests. This is a trade-off of the batching approach, and something you need to account for when considering it.</p>
<p>Either way, I don’t see any general reasons why each technique (or any other load control technique) would prevent scaling (particular reasons might of course exist in concrete scenarios). The statefulness of the queue is local, so you can e.g. still have multiple batching queues spread across multiple machines, just like you can have multiple pools spread across multiple machines.</p>
<p>In any case, all my comments were made from the standpoint of the load control, not scaling. So pooling in the book is used to control the load (it’s also used for teaching purposes, as a fairly simple but realistic concurrent challenge). The batching is mentioned in this thread for the same reason.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="115578" data-batch-url="/posts/batch_likers">
                        7
                      </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/when-to-use-pools-vs-tasks/19818/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-115578" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="115578"
                     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="115579" data-post-id="115579">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sasajuric" data-post="12" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>The statefulness of the queue is local, so you can e.g. still have multiple batching queues spread across multiple machines, just like you can have multiple pools spread across multiple machines.</p>
</blockquote>
</aside>
<p>Best example might be ecto, which I’ve never heard to make problems with scaling, but is using pooling for it’s db connections.</p>
<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="10" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>Requests occurring now are request currently being made by any number of processes. A queue, by default, only has 1 active request while the others wait their turn. It is the difference between making 1 request per second and having 9 waiting their turn and making 10 simultaneous requests with no wait in between them.</p>
</blockquote>
</aside>
<p>No matter how much you want to request things at the same time you’ll always be bound to the number of processing units doing work in parallel. Otherwise you will queue requests at one place or another. If it’s a global queue or a pooled solution, somewhere your request will need to wait if there are not more parallel resources available to handle the request.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="115579" 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/when-to-use-pools-vs-tasks/19818/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-115579" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="115579"
                     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="115583" data-post-id="115583">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="11" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>Another point in which we disagree. Systems with state are notoriously harder to scale. But please, don’t buy my word, have a look at the 12 factor app standard:</p>
</blockquote>
</aside>
<p>I’m very familiar the 12 factor app and the tradeoffs of stateful and stateless services. But you’re misunderstanding me here (or I’m not conveying my point well). You have state whether you want to use a queue or a bunch of tasks. That state is ephemeral in both cases. But it exists in both cases. Using a pool does not make your service any more or less “stateful” than it was before.</p>
<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="11" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>If I was concerned with the response time of the receiving system, I would probably be using Flow with backpressure. However, for the purposes of this discussion, I am not <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>
</blockquote>
</aside>
<p>None of my points care at all about response times. It’s about fault tolerance and not overwhelming your downstream system.</p>
<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="10" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>A queue, by default, only has 1 active request while the others wait their turn. It is the difference between making 1 request per second and having 9 waiting their turn and making 10 simultaneous requests with no wait in between them.</p>
</blockquote>
</aside>
<p>I think you may be conflating worker queues with a more general usage of the term queue. It turns out that <em>all</em> computer systems can be modeled as queues. The BEAM uses a bunch of them for scheduling work. So regardless of whether or not you’re using a queue to manage your work directly, the problem you’re describing is a queueing problem. You just have several queues being processed concurrently. Think of it like tellers at a bank.</p>
<p>The consequence of this statement is that you can model your entire system (the two services communicating) as one giant queue and any increase in wait time or processing time in the downstream service will be felt all the way back at the upstream service.</p>
<aside class="quote no-group quote-modified" data-username="Fl4m3Ph03n1x" data-post="10" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>As for how cowboy it isn’t important for this discussion as no one uses it…</p>
</blockquote>
</aside>
<p>I’m not sure I understand this but if you’re using plug or phoenix you’re probably using cowboy under the hood. Either way the larger point still stands. It’s queues all the way down.</p>
<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="11" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>You make good points, but I am still not convinced that adding state to this specific system would result in a system easier to scale.</p>
</blockquote>
</aside>
<p>You have the same amount of state (in-flight requests) in either scenario.</p>
<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="11" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>But this is not something I care because the downstream service, for all purposes and effects, when compared to the system I am developing, has infinite resources.</p>
</blockquote>
</aside>
<p>Must be nice <img src="https://forum.elixirforum.com/images/emoji/apple/grinning_face_with_smiling_eyes.png?v=15" title=":grinning_face_with_smiling_eyes:" class="emoji" alt=":grinning_face_with_smiling_eyes:" 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="115583" 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/when-to-use-pools-vs-tasks/19818/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-115583" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="115583"
                     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="115603" data-post-id="115603">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="7" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>The problem with batching/queuing is that when implemented it automatically means your application is statefull. What happens to all those queued up requests if the node they are on breaks? Well, you loose them.</p>
<p>By not using them, you <em>only</em> lose the requests that are occurring <em>now</em> meaning your application is stateless, which means it is easier to scale (which is the hidden objective here).</p>
</blockquote>
</aside>
<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="10" data-topic="19818">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>you only want to lose the information you are currently processing, or the information you are currently processing + the information you got 10 minutes ago (which happens with queues)</p>
</blockquote>
</aside>
<p>Have you considered adding batching at a finer granularity than 10 minutes? I would think that if you batched the requests you get every second together you could drastically reduce the required resources on your elixir service and the network from your elixir service to your upstream service. It sounds like you have enough scale that batching by ever second (or even every 500ms) you could scale your elixir service more effectively without significantly increasing the amount of information that would be lost if the node crashes.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="115603" 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/when-to-use-pools-vs-tasks/19818/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-115603" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="115603"
                     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>