[id='performance-tuning_{context}']
= Performance tuning guidelines

This topic gives you information and tweaks for tuning {brandname} performance.

== Java Virtual Machine settings

Java Virtual Machine tuning can be divided into sections like memory or GC.
Below is a list of helpful configuration parameters and a guide how to adjust them.

[discrete]
=== Memory settings

Adjusting memory size is one of the most crucial step in {brandname} tuning. The most commonly used JVM flags are:

* `-Xms` - Defines the minimum heap size allowed.
* `-Xmx` - Defines the maximum heap size allowed.
* `-Xmn` - Defines the minimum and maximum value for the young generation.
* `-XX:NewRatio` - Define the ratio between young and old generations. Should not be used if -Xmn is enabled.

Using `Xms` equal to `Xmx` will prevent JVM from dynamically sizing memory and might decrease GC pauses caused by resizing.
It is a good practice to specify `Xmn` parameter. This guaranteed proper behavior during load peak (in such case {brandname} generates lots of small, short living objects).

[discrete]
=== Garbage collection

The main goal is to minimize the amount of time when JVM is paused. Having said that, CMS is a suggested GC for {brandname} applications.

The most frequently used JVM flags are:

* `-XX:MaxGCPauseMillis` - Sets a target for the maximum GC pause time. Should be tuned to meet the SLA.
* `-XX:+UseConcMarkSweepGC` - Enables usage of the CMS collector.
* `-XX:+CMSClassUnloadingEnabled` - Allows class unloading when the CMS collector is enabled.
* `-XX:+UseParNewGC` - Utilize a parallel collector for the young generation. This parameter minimizes pausing by using multiple collection threads in parallel.
* `-XX:+DisableExplicitGC` - Prevent explicit garbage collections.
* `-XX:+UseG1GC` - Turn on G1 Garbage Collector.

[discrete]
=== Other settings

There are two additional parameters which are suggested to be used:

* `-server` - Enables server mode for the JVM.
* `-XX:+ UseLargePages` - Instructs the JVM to allocate memory in Large Pages. These pages must be configured at the OS level for this parameter to function successfully.

[discrete]
=== Example configuration

In most of the cases we suggest using CMS. However when using the latest JVM, G1 might perform slightly better.

.32GB JVM
----
-server
-Xmx32G
-Xms32G
-Xmn8G
-XX:+UseLargePages
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+DisableExplicitGC
----

.32GB JVM with G1 Garbage Collector
----
-server
-Xmx32G
-Xms32G
-Xmn8G
-XX:+UseG1GC
----

== Network configuration

{brandname} uses TCP/IP for sending packets over the network (for both cluster communication when using TCP stack or when communication with Hot Rod clients)

In order to achieve the best results, it is recommended to increase TCP send and receive window size (refer to you OS manual for instructions).
The recommended values are:

* send window size - 640 KB
* receive window size - 25 MB

== SSL provider

{brandname} server uses the default JDK provider for TLS encryption.

== Cache store performance

In order to achieve the best performance, please follow the recommendations below when using cache stores:

* Use async mode (write-behind) if possible
* Prevent cache misses by preloading data
* For JDBC Cache Store:
** Use indexes on `id` column to prevent table scans
** Use PRIMARY_KEY on `id` column
** Configure batch-size, fetch-size, etc

== Hints for program developers

There are also several hints for developers which can be easily applied to the client application and will boost up the performance.

[discrete]
=== Ignore return values

When you're not interested in returning value of the `#put(k, v)` or `#remove(k)` method, use `Flag.IGNORE_RETURN_VALUES` flag as shown below:

.Using Flag.IGNORE_RETURN_VALUES
[source,java]
----
include::code_examples/GetAdvancedCacheWithFlagsIgnoreReturnValues.java[]
----

It is also possible to set this flag using ConfigurationBuilder

.Using ConfigurationBuilder settings
[source,java]
----
include::code_examples/ConfigurationBuilderUnreliableReturnValues.java[]
----

[discrete]
=== Use simple cache for local caches

When you don't need the full feature set of caches, you can set local cache to "simple" mode and achieve non-trivial speedup while still using {brandname} API.

This is an example comparison of the difference, randomly reading/writing into cache with 2048 entries as executed on 2x8-core Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz:

.Number of operations per second (± std. dev.)
|===
| Cache type   | single-threaded cache.get(...) | single-threaded cache.put(...) | 32 threads cache.get(...) | 32 threads cache.put(...)

| Local cache  | 14,321,510 ± 260,807 |  1,141,168 ±  6,079 |   236,644,227 ± 2,657,918 |  2,287,708 ±   100,236
| Simple cache | 38,144,468 ± 575,420 | 11,706,053 ± 92,515 |   836,510,727 ± 3,176,794 | 47,971,836 ± 1,125,298
| CHM          | 60,592,770 ± 924,368 | 23,533,141 ± 98,632 | 1,369,521,754 ± 4,919,753 | 75,839,121 ± 3,319,835
|===

The CHM shows comparison for ConcurrentHashMap from JSR-166 with pluggable equality/hashCode function, which is used as the underlying storage in {brandname}.

Even though we use http://openjdk.java.net/projects/code-tools/jmh/[JMH] to prevent some common pitfalls of microbenchmarking, consider these results only approximate. Your mileage may vary.
