Child pages
  • Tuning the Server

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Stoc

Java Virtual Machine (JVM) Tuning

Java

...

Version

Servoy supports both Java 5 7 and Java 6 8 (for the Application Server, the Smart Client and Servoy Developer). As Java 6 8 has numerous performance improvements, it is preferred over Java 57.

If the hardware in which Servoy is running is 64bit, make sure to also run a 64 bit Java Virtual Machine. When in doubt which version is used, check the Servoy Admin page, under "Servoy Server Home" > "Servoy Server Status" > " JVM Information":

  • 64 bit: java.vm.name=Java HotSpot(TM) 64-Bit Server VM
  • 32 bit: java.vm.name=Java HotSpot(TM) Client VM
Note

An 32 bit JVM will allow a max memory of 2 Gb in total, In order to run with larger heap sizes (over 2 Gb) you have to use 64 bit JVM on a 64 bit OS

Java Virtual Machine Server

...

Mode

Java has 2 distinct operating modes: client mode and server mode. When running in server mode, the startup of the Java process will take longer and initial execution of code will be slower, but after a while the application will perform faster. The server mode is best suited for the Servoy Application Server.

...

If the JVM supports servermode, it will automatically detect if the machine it is running on is a "'capable" ' machine and automatically run in server or client mode depending. The definition of "capable" may differ from Java version to Java version. For Java 5/6 this means a 2CPU, 2Gb memory machine.

Checking whether or not a Servoy Application Server runs in client or server mode can be seen on the Servoy Admin page, under "Servoy Server Home" > " Servoy Server Status" > " JVM Information":

  • Server mode: java.vm.name=Java HotSpot(TM) 64-Bit Server VM
  • Client mode: java.vm.name=Java HotSpot(TM) Client VM

...

In servoy_server.sh/bat:

Code Block

java -server -Djava.awt.headless=true -XX:MetaspaceSize=60M -XX:MaxMetaspaceSize=60M -XX:MinMetaspaceFreeRatio=0 -XX:MaxMetaspaceFreeRatio=100 .....

When using the Service wrapper:

Code Block
# Java Additional Parameters
wrapper.java.additional.1=-Djava.awt.headless=true
wrapper.java.additional.2=-Duser.dir="C:\Servoy\application_server"
wrapper.java.additional.3=-Djava.io.tmpdir="C:Servoy\application_server\server\work"
wrapper.java.additional.4=-XX:MaxPermSize=128m
wrapper.java.additional.5=-XX:MetaspaceSize=200M
wrapper.java.additional.46=-XX:MaxMetaspaceSize=200M
wrapper.java.additional.7=-XX:MinMetaspaceFreeRatio=0
wrapper.java.additional.8=-XX:MaxMetaspaceFreeRatio=100 
wrapper.java.additional.9=-server


Note
JVM servermode on Windows 32-bit
JVM servermode on Windows 32-bit

On Windows 32 bit environments, the Java Runtime Environment does not include support for server mode. In order to take advantage of server mode optimizations on 32 bit Windows systems, it is required to install Java Development Kit (JDK)

Memory

Processes in Java, like the Servoy Application Server, need to be told explicitly the maximum of memory they are allowed to use. This setting, the maximum heap size, is important to adjust to the load the Servoy Application Server is to handle.

The maximum heap size setting is located in {servoy_install}/application_server/servoy_server.sh/.bat, through the "Xmx" setting.

When the Application Server is started as a Service the setting can be found in {servoy_install}/application_server/service/wrapper.conf, by the name of "wrapper.java.maxmemory".

By default the maximum heap size is set to 256MB. This setting should be changed when:

  • The actual used memory is >= 70% of the specified maximum. The actually used memory can be found on the main page of the Admin page, under System Information, like: Heap memory: allocated=549184K, used=371473K, max=699072K
  • When the expected client load will exceed the maximum: As a rule of thumb:
    • Smart Client: assume a memory usage of about 600kb for each Smart Client. NOTE: When the Servoy HTTP Tunnel is used, assume 900kb per Client.
    • All other type of Clients (Web, Headless, Batch): the required memory for each client depends on the size and design of the solution, but should be in the order of magnitude of a couple of Mb per Client.
  • When there is plenty of free real memory available on the OS level. Java processes in general perform better when not having memory constraints. For example, when 2Gb free real memory is left, add the 2Gb to the maximum heap size. The Java process will only take what it needs.

Database Connection Pool Tuning

The Servoy Application Server uses a pool of database connections per configured Database Server. 

The maximum number of active and idle connections within a pool is configurable to preserve resources. For example, a single connection could easily take up a couple of Mb, both on the Servoy Application Server side, as well as on the database engine side.

The settings are configurable on the Servoy Admin page, under Database Servers:

  • Maximum connections active: the maximum number of connections that can be created within the pool.
    If set too low, handling requests towards the database might slow down, as one request needs to wait until another request is processed and the connection is returned to the pool
    If set too high, the exceptions might occur if the database cannot handle that many concurrent connections or if more memory is required than is available
  • Maximum connections idle: the maximum number of inactive or idle connections in the pool
    Active connections that are done processing a request are returned to the connection pool as idle connections. If the number of idle connections goes over the maximum, the connections are removed.
    As instantiating new connections takes time, the value shouldn't be too low. On the other side idle connections take up resources, so the number shouldn't be too high either.

The maximum number of active connections is also limited by the maximum number of connections the database itself is configured to allow. For the bundled PostgreSQL database engine, the maximum is 100 connections. However, these 100 connections are for all connections made to the database instance. This means that if there are multiple Database Servers defined on the Servoy Application Server which are all hosted on the same database instance, the max. 100 connections are for all Database Servers combined. This must be taken into account when setting up the maximun number of active connections.

By default, the maximum active connections setting is set to 10. This could be too low when serving may clients from one Application Server or when the clients do many requests to the database. As rule of thumb, if the actual used active connection regularly goes above 70% of the maximum a higher number of maximum active connections should be configuredSee Memory Management

Database Connection Pool Tuning

See Connection Pooling in the Database Connections chapter

Database Tuning

Architecture

In order to get the best possible performance, the communication between the Servoy Application Server and the database needs to be as fast as possible. The fastest option would be installing the database engine and the Servoy Application Server on the same machine, whether or not this is possible depends on the dimensions of the physical server and the resource requirements of both the database engine and the Servoy Application Server.

When opting for dedicated servers for both the database engine and the Servoy Application Server, the connection between them should be as fast as possible, preferably a direct 1Gb cable connection between the two machines.

Database Tuning

When experiencing performance issues , analyse the "'Performance Data" ' page of the Servoy Admin page . This can be analysed to find slow performing SQL statements, or SLQ statements that are fired often.

The page provides an overview of all queries fired at the database.

At any given time regular SQL statements (Type = Relation, Load foundset) should have an average execution time below 0.5 seconds. 

The  The performance data is sorted by the total time taken to perform the query, being the result of the average time * number of executions.

At any given time regular SQL statements (Type = Relation, Load foundset) should have an average execution time below 25 milliseconds.

Especially for SQL statements that are fired often and take up significant time it should be checked if it's possible to optimize the database, for example by creating the relevant indexes. 

Web Client Settings Tuning

servoy.webclient.templates.use_local_ids

For the Web Client, Servoy generates HTML markup. In order for Servoy to dynamically update only parts of the UI through Ajax, each object in the HTML Markup receives a unique ID. This ID is also placed in the editable Web Client templates.

Servoy has 2 modes for generating the ID's:

  • Using unique identifiers that are part of the internal design of the Solution created with Servoy. These ID's, as they are part of the solution design, are the same on any Servoy Application Server where the solution is imported. 
  • Using local identifiers. These identifiers are generated at runtime and thus differ per installation and session.

The advantage of the local identifiers are that they are shorter in length, thus bring down the weight of the generated HTML markup. The advantage of the unique identifiers is that they are the same on any server where the solution is running.

If templates are used to modify the generated HTML markup for Web Clients, then the unique identifiers are to be used, in order to maintain the link between the identifiers in the edited templates and the identifiers used at runtime. Otherwise the local identifiers can be used.

By default a Servoy Application Server uses the unique identifiers. Enabling the use of local identifiers can be done by setting the servoy.webclient.templates.use_local_ids option on the Servoy Admin page to true (located under Servoy Settings > Web Client settings) 

...

Foundset loading and saving tuning

Servoy loads a foundset by first retrieving the PKs from the database. This retrieval is done in chunks: when the foundset is initialized, the first chunk is retrieved, consecutive chunks are retrieved when needed.

The actual record data is also retrieved from the database in chunks.

The size of the different chunks are controlled by 3 properties that can be set in the servoy.properties:

Setting

Default Value

Description

servoy.foundset.pkChunkSize

200

Chunk size for foundset PK retrieval

servoy.foundset.chunkSize

30

Chunk size for record data retrieval

servoy.foundset.initialRelatedChunkSize

2 * servoy.foundset.chunkSize

Chunk size for related record retrieval
For the initial load of related records both the PK's and data are retrieved in one query

servoy.foundset.statementBatching (since 2020.12)false

This only works for inserts of records that are after each other (without another record from another datasource in between).

It does now have side effects:

In statementBatching if you insert 10 records of the same datasource, that is now always then also in a transaction (not depending if you started a transaction) because it goes into the same (single) batch statement.

Because its now a transaction and a single statement to the db server, no matter if you are your self already in a transaction or we do it automatically now, if something goes wrong in 1 of the records, all records are failed, because databases don't tell us which one really failed, we would know this previously, and nothing is inserted

That nothing inserted was already the case in transaction mode, but this is with this property to true different in none transaction mode, which did do the inserts until the failure and now it fails the same as in transaction mode.

servoy.foundset.loadRelatedRecordsIfParentIsNew (since 2020.12)false

By default Servoy will not query for related records if the relation is a pk → fk relation.  So if the relation has on the primary side at least all the primary keys specified. Because this scenario should already not be possible in a good designed database (if there is a fk→pk constraint specified on the child table).  Child records should not already exist if there is no Parent record already. So Servoy does not ask the database for data in this scenario. Related lookups on not yet saved Parent records should only be used to make related records, not to expect to get data.

By setting this property to "true" you can force Servoy to query for data even for such scenario's

The values can be modified in an attempt to increase performance. The optimal values differ per application, thus no guidelines are available for alternative values. Tuning needs to be done by altering the values and monitoring the performance afterwards. The defaults are set based on averages.  

Web Client Tuning

Content Compression

In order to minimize the size of the content that the browser has to download for the Web Client, it's possible to turn on compressionthe application server serving the content can compress the content. The Servoy Application Server is currently not configured to automatically compress the content

Compression can be done by the Apache Tomcat instance that is part of the Servoy Application Server, or can be done by an HTTP server that is in front of the Servoy application Server, like an Apache HTTPD Server. 

In order to enable compression in the Tomcat instance that is part of the Servoy Application Server, open the file "server.xml" located in {servoy_install}application_server\server\conf\. and locate the Connector:

Code Block

<Connector port="8080"
  protocol="HTTP/1.1"
  maxThreads="500" connectionTimeout="60000"
  redirectPort="8443" useBodyEncodingForURI="true" />

and add the following atttributes:

...

 

...

so the connector is configured like this:

...

Save the edits and restart the Servoy Application Server to let the configuration changes take effect.

...

As of Servoy 6.0, the Tomcat compression configuration will be enabled by default

It is also possible to handle the compression outside of the Servoy Application Server, for example in an Apache HTTPD Server placed between the Servoy Application Server and the outside world. The advantage of this is that Tomcat's compression options are limited, so an external HTTP server offers more options.

...

Details on setting up mod_deflate on an Apache HTTPD server can be found here: http://httpd.apache.org/docs/2.0/mod/mod_deflate.html

When compression is handled by outside the Servoy Application Server, it is advised to turn of compression inside Servoy. This can be doen by modifying the server.xml file located in {servoy_install}application_server\server\conf\. and locate the Connector: 

Code Block
<Connector port="8080"
protocol="HTTP/1.1"
maxThreads="500" connectionTimeout="60000"
redirectPort="8443" useBodyEncodingForURI="true"
compressableMimeType="text/html,text/xml,text/css,text/javascript,text/plain" compression="on"
compressionMinSize="2048"/>

and removing the following atttributes: 

  • compressableMimeType
  • compression
  • compressionMinSize

Save the edits and restart the Servoy Application Server to let the configuration changes take effect.

Servoy Application Server

...

Log

At all times try to keep the Server log free from javascript application errors/excpetions, all application exceptions point to possible problems inside the application.

...