Back to articles
Technology Insight

Optimizing Keycloak Auth Server Memory on Low-Spec Linux VPS (1GB RAM)

June 1, 2026

Introduction: The Challenge of Running Keycloak on Constrained Hardware

Keycloak has become the industry standard for open-source Identity and Access Management (IAM), offering robust support for OpenID Connect (OIDC), OAuth 2.0, and SAML 2.0. However, built on top of the modern Quarkus framework, Keycloak is traditionally designed to operate in enterprise environments with relatively generous resource allocations. Out of the box, Keycloak can easily consume 512MB to 1GB of RAM just sitting idle, making deployment on a low-spec Virtual Private Server (VPS) with only 1GB of total RAM a risky endeavor.

When RAM is depleted, the Linux kernel's Out-Of-Memory (OOM) killer will step in, abruptly terminating the Keycloak process and causing immediate authentication outages for your applications. Fortunately, Keycloak is highly customizable. With targeted optimizations spanning the Java Virtual Machine (JVM), the Quarkus runtime backend, database connections, and operating system configurations, you can achieve a stable, performant Keycloak deployment on an affordable 1GB RAM VPS. This guide provides an actionable roadmap to achieve this optimization safely for production workloads.

---

1. Strategic Prerequisites: Setting Up a Safety Net with Swap Space

Before modifying any configuration files, you must establish a system-level safety net. On a 1GB RAM VPS, memory spikes during startup, administrative realm exports, or sudden traffic bursts can instantly crash the server. Implementing Swap space allows the operating system to utilize the SSD/HDD storage as virtual memory, absorbing these transient spikes.

How to Configure a 2GB Swap File on Ubuntu/Debian

Run the following commands sequentially as root to create and activate a dedicated swap file:

# Create a 2GB pre-allocated file
sudo fallocate -l 2G /swapfile

# Secure the file permissions
sudo chmod 600 /swapfile

# Set up the swap area
sudo mkswap /swapfile

# Enable the swap file
sudo swapon /swapfile

# Make the change permanent across reboots
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Note: To ensure the OS only utilizes Swap when absolutely necessary (preventing disk I/O bottlenecks), reduce the system's 'swappiness' value. Open /etc/sysctl.conf and append vm.swappiness=10, then apply the changes using sudo sysctl -p.

---

2. Fine-Tuning the JVM and Quarkus Memory Footprint

Since Keycloak 17, the server operates on the Quarkus framework, which utilizes the standard Java Virtual Machine. By default, the JVM may attempt to grab up to 25% to 50% of system RAM automatically, leaving zero headroom for the OS or database. To constrain memory on a 1GB VPS, you must explicitly enforce strict heap boundaries via the JAVA_OPTS_APPEND environment variable.

Optimizing Heap Allocations

For a 1GB RAM system, allocating between 400MB and 512MB to the JVM Heap strikes the perfect balance. This leaves enough room for the Linux OS and an embedded or local database instance.

  • -Xms350m: Sets the initial memory allocation pool. Initializing it close to the maximum reduces the overhead of frequent heap expansions during boot.
  • -Xmx450m: Caps the maximum memory allocation pool. This guarantees Keycloak will never request more than 450MB for object allocations.
  • -XX:MaxMetaspaceSize=120m: Limits the memory used for class definitions and metadata, preventing slow, unconstrained memory leaks in the non-heap area.

Choosing the Right Garbage Collector

The default Garbage Collector (GC) in modern modern JVMs is G1GC, which is highly performant but possesses a larger memory footprint for its internal data structures. For memory-constrained setups, switching to the Serial Garbage Collector minimizes internal JVM management overhead, freeing up precious megabytes of physical RAM.

Configuration Example: Define the following environment variable in your systemd service file or your Docker Compose file:
JAVA_OPTS_APPEND="-server -XX:+UseSerialGC -Xms350m -Xmx450m -XX:MaxMetaspaceSize=120m -XX:+ExitOnOutOfMemoryError"

Including -XX:+ExitOnOutOfMemoryError ensures that if an OOM error does occur, Keycloak exits immediately, allowing system watchers (like systemd or Docker) to automatically clean up and restart the service cleanly.

---

3. Optimizing Keycloak Features and Internal Caches

Keycloak loads various capabilities by default, many of which may be irrelevant to your specific business requirements. Deactivating unused providers and shrinking internal Infinispan caches directly translates to reduced RAM consumption.

Disabling Unused Features

When starting Keycloak via the command line or container, explicitly disable heavyweight features you do not need, such as token exchange, step-up authentication, or specific account console extensions. Use the --disabled-features flag during build or startup:

kc.sh start --disabled-features=token-exchange,fapi,web-authn,client-secret-rotation

Constraining Infinispan Distributed Caching

Keycloak relies heavily on Infinispan for caching realms, users, sessions, and authentication tokens. By default, these caches can hold thousands of entries indefinitely. On a low-RAM VPS, you must restrict these cache boundaries by configuring the conf/cache-ispn.xml file.

Locate your cache configuration file and override the default max-count attributes for local caches to restrict them to reasonable maximum capacities:


    


    


    

By limiting the maximum count, Infinispan will aggressively evict least-recently-used (LRU) records from RAM, ensuring stable memory consumption even during heavy login surges.

---

4. Database Connection Pool Optimization

Every open database connection consumes memory both on the Keycloak server side and within the database engine itself (e.g., PostgreSQL or MySQL). The default connection pool configurations are designed to handle hundreds of concurrent requests, which will easily saturate a 1GB VPS.

Modify your conf/keycloak.conf file to limit the Agroal connection pool size to minimal values sufficient for low-to-medium traffic profiles:

# Reduce the maximum database connection pool size
db-pool-initial-size=2
db-pool-min-size=2
db-pool-max-size=5

Setting a maximum pool size of 5 ensures that even under peak loads, Keycloak will not open an excessive number of threads and database descriptors, preventing memory exhaustion at the data layer.

---

5. Verification and Production Monitoring

Once your optimizations are successfully applied, validation is crucial. Monitor your memory consumption using standard Linux CLI tools to ensure stability over time.

  1. Monitor Live RAM Usage: Execute free -h and top (or htop) to inspect physical memory allocation and verify that the Swap space is absorbing minor spikes safely.
  2. Track the JVM Behavior: If you have access, run jstat -gc to observe the frequency and duration of the Serial Garbage Collector sweeps.
  3. Analyze Log Outputs: Review your Keycloak startup logs to confirm that your JAVA_OPTS_APPEND strings were loaded successfully by Quarkus without warnings.

Conclusion

Running Keycloak on a 1GB RAM Linux VPS requires strict discipline and targeted configurations, but it is entirely feasible for microservices, staging environments, and small-scale production apps. By establishing a 2GB swap file, restricting the JVM heap to a maximum of 450MB, switching to the lightweight Serial Garbage Collector, and capping internal Infinispan cache limits, you eliminate the risk of OOM crashes. These optimizations keep your IAM layer highly secure, remarkably lean, and cost-effective.

Optimizing Keycloak Auth Server Memory on Low-Spec Linux VPS (1GB RAM) | DPTCloud