Configuration and performance of the AsyncAppender in Logback framework

Answering the second question first ...

Which is better normal appender or Async Appender?

The answer here is: it depends. To clarify that here the the pros and cons of using an AsyncAppender:

  • Pros:

    • Lower log event latency i.e. the time it takes for any given Logger.debug|info|warn|error call to complete will be lower for an asynchronous logger than it will be for a synchronous logger.
    • Higher throughput. This is particular useful for applications which have bursty logs i.e. occasional, large bursts of log events. Asynchronous logging - especially if the configured queue size is large enough to cater for these spikes - will prevent slowness in the logging invocations which might arise in the face of these spikes.
  • Cons:

    • If your application is already CPU bound then starting up another thread to handle async log events won't offer much benefit
    • If your application is emitting log events faster than the appender inside the async appender can handle them then the async appender will start queing up log events and if this continues then your applicaiotn will likely face a decision between slow emission and discarding events
    • It is much trickier to propagate an error during a log write back to the emitting program from an asynchronous logger than it is from a synchronous logger

Depending on your use case you might find that some of these pros and cons have more weight than others. I'd suggest starting without an AsyncAppender and only using one if you have a demonstrable need to do so.

Back to your first question ...

Can someone suggest me some tweaks in order to gain performance?

This is why I answered the second question first. Without knowing the specifics of your application and it's runtime configuration (memory and CPU on its hosts, the type of appender to be wrapped by the AsyncAppender and your tolerance for discarding log events) it is impossible to say how you shoud configure it. However, you'll know all these things about your own application so with that knowledge in mind I'd suggest considering the following when deciding if-and-how to configure an AsyncAppender:

  • queueSize: the bigger this is the less blocking there will be on the application threads. If the async appender's queue fills up, then application threads will be blocked from logging new events until the worker thread has had a chance to remove items from the queue. So, increasing the queueSize will improve throughput if the application tends to produce enough near concurrent log events to fill up the queue. But bear in mind that this gain in throughput is only relevant if the application is capable of swamping the existing queue size and it comes at the cost of heap usage.
  • includeCallerData: reading caller supplied data from log events can be expensive, you'll typically find that setting this to false improves performance and unless you have some bespoke caller supplied data in your log events you won't actually lose any data
  • neverBlock: setting this to true will prevent any blocking on your application threads but it comes at the cost of lost log events if the async appender's internal buffer fills up.

So ...

  • If maximising throughput is essential to you and you don't care about losing some events then use neverBlock=true

  • If maximising throughput is important to you and you have plenty of headroom in your heap and you have no tolerance for losing log events then use: queueSize=_some_number_which exceeds_ the_maximum_queue_size_observed_in_testing_plus_25_percent_

Plenty more details here:

  • The Logback docs
  • Log4J Performance Stats (which covers Logbacks async appender's perforance too).