title: Performance comparison of RetryTemplate vs ErrorHandler
body: <p>I have two ways of recovering from KafkaListener errors with using</p>
  <ol>
  <li>RetryTemplate in the <code>KafkaListener</code> method:</li>
  </ol>
  <pre class="lang-java prettyprint-override"><code>@KafkaListener(topics: &quot;topic1&quot;)
  public void handle(command) {
      retryTemplate.execute(ctx -&gt; {
          processCommand(command);
      });
      // Retries exhausted, execute the recoverer logic
      recover(command);
  }
  </code></pre>
  <ol start="2">
  <li>Set ErrorHandler to MessageListenerContainer via ContainerCustomizer:</li>
  </ol>
  <pre class="lang-java prettyprint-override"><code>@Component
      public class ContainerCustomizer {
          public ContainerCustomizer(CustomConcurrentContainerListenerFactory factory) {
              factory.setContainerCustomizer(container -&gt; {
                      container.setErrorHandler(new SeekToCurrentErrorHandler((ConsumerRecord&lt;?, ?&gt; record, Exception e) -&gt; {
                          //logic for recoverer after retries exhausted
                          recover(convertRecord(record));
                      }, new ExponentialBackOffWithMaxRetries(2)));
              });
          }
      }
  </code></pre>
  <p>When it comes to performance and blocking the consumer thread, how these two options compare? Is it true to say that with <code>RetryTemplate.execute</code>, retries are handled in a separate thread while with <code>containerListener.setErrorHandler</code> it blocks the main consumer's thread?</p>