Putting the squeeze on: Compressing ORDS response size with GZIP

In the previous article, “Optimise Java settings with Application Process Monitoring“, we discussed how to get an insight on memory usage, CPU load, and response times. In this article, we will build on this knowledge by exploring the why, how and when on reducing response size by compressing ORDS responses with GZIP. This can be an effective way to reduce response size and ultimately improve response times as experienced by the end users. That can be especially important in systems where network latency to clients is a challenge. We will look at how to configure GZIP, and explore the trade-offs associated with response size versus CPU load.

GZIP Compression

Http clients, such as a web browser, indicate that they can accept a compressed response by listing the encoding algorithms they understand in the Accepts-Encoding header of the request. GZIP compression is a widely used compression algorithm for unix-based systems that has been around for more than two decades. It allows for reduced bandwidth between a web server and web client, resulting in faster page loading times.

Configuring a web server to compress content responses prior to transmission is beneficial, but it should not be done indiscriminately as it does consume CPU resources. It should be noted that compression can apply to the request received, as well as the response returned but in this article the focus is on making that response size smaller.

How much smaller? On average, one could be looking at response sizes being approximately 15% of the uncompressed file size.

# Uncompressed response size
curl http://localhost:8080/ords/hr/employees/ \
     --silent --write-out "%{size_download}\n" \
     --output /dev/null                         

8317

# Compressed response size
curl http://localhost:8080/ords/hr/employees/ \
     -H "Accept-Encoding: gzip" \
     --silent --write-out "%{size_download}\n" \
     --output /dev/null                         
1401

Compression is not a silver bullet. There are file types, such as most image files and PDF documents, that are already compressed so attempting to compress them again is a waste of CPU cycles. Similarly, small files may not justify the computational cost for a relatively insignificant gain. In fact, if you’re compressing files that are smaller than the Maximum Transmission Unit (MTU) size of a TCP packet (1500 bytes), you are wasting CPU cycles. To ensure that the compression is effective, you should limit it to files with a size greater than 1.4KB (1400 bytes).

Let Jetty Handle Compression

When ORDS is running in standalone mode it is running a specially configured instance of Eclipse Jetty as the web server for receiving HTTP(S) requests. GZIP is so widely used that Eclipse Jetty has a dedicated GZipHandler for requests and responses. In this article we will extend the ORDS standalone jetty server, using a jetty XML configuration file, to apply the handler to responses. When using Eclipse Jetty, you can configure your server to use compression for all responses, or only for responses that meet certain criteria. This flexibility allows you to tailor your server response compression settings to fit your specific needs. In this case, compression will be applied for certain mime-types where compression could help, and when the response size is greater than 128 bytes. That’s quite a low maximum size and there may not be any performance improvement gained but it does allow the demonstration of compression being applied to almost every response.

Note that in this example compression will be applied only for responses to GET requests. This is the default behaviour. However, you can use the GZipHandler documentation to guide you on configuring for more complicated scenarios.

When ORDS is running in a standalone mode, the Eclipse Jetty Home is ${configuration.directory}/global/standalone/. The Jetty XML syntax can be used to configure the Jetty Server for additional functionality by placing configuration XML files in the Jetty Home etc directory. The capability to do this is provided through the Eclipse Jetty server product.

ORDS 22.4 Installation and Configuration Guide

Here’s my ${configuration.directory}/global/standalone/etc/jetty-compression.xml configuration file that inserts the GzipHandler to the ORDS standalone jetty server instance.

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
      <Call name="insertHandler">
        <Arg>
          <New id="GZipHanlder" class="org.eclipse.jetty.server.handler.gzip.GzipHandler">
            <Set name="IncludedMimeTypes">
              <Array type="java.lang.String">
                <Item>text/html</Item>
                <Item>text/xml</Item>
                <Item>text/css</Item>
                <Item>text/javascript</Item>
                <Item>application/javascript</Item>
                <Item>application/json</Item>
              </Array>
            </Set>
            <Set name="minGzipSize">128</Set>
          </New>
        </Arg>
      </Call>
</Configure>

When ORDS is started in standalone mode with the above file in the configuration directory Eclipse Jetty Home etc folder, all responses will pass through the GzipHandler instance.

> ords --config /path/to/config serve

ORDS: Release 22.4 Production on Fri Feb 03 22:15:56 2023
...
Mapped local pools from /path/to/config/databases:
  /ords/                              => default                        => VALID     


2023-02-03T22:16:12.660Z INFO        Oracle REST Data Services initialized
Oracle REST Data Services version : 22.4.3.r0331239
Oracle REST Data Services server info: jetty/10.0.12
Oracle REST Data Services java info: Java HotSpot(TM) 64-Bit Server VM 11.0.13+10-LTS-370

As shown earlier, that applies to application/json responses such as for ORDS REST Services. It also applies to text/html responses for ORDS PL/SQL Gateway and even static content such as the APEX images.

Browser showing compressed content returned for static content such as style sheets.

Conclusion

This article has focused on ORDS in standalone mode and configuring the embedded Eclipse Jetty server instance. Similar compression options can be configured when ORDS is deployed on Apache Tomcat or Oracle WebLogic Server but the settings will be specific to those containers. Check their product documentation for information on how to configure that. The above Eclipse Jetty extension example is only applicable to ORDS standalone mode.

To reiterate, choosing the right compression configuration is important. It will take time, as well as monitoring of the additional resources involved. There may be specific paths where compression is too costly or the GZipHandler interferes with the successful processing of the response.

However, when using compression one should see benefits that include faster page loading times, improved user experience, and reduced bandwidth usage, all of which can help to improve overall performance of your ORDS based web application. Now that you know how, go make efficient use of your bandwidth!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s