Linux Server

How to Troubleshoot a Spring Boot Application That Keeps Stopping on an Ubuntu VPS

Keywords: Spring Boot VPS, Ubuntu VPS troubleshooting, Java OOM Killer, Spring Boot memory issue, Nginx 502 Bad Gateway

Introduction

A few days ago, my personal blog suddenly became unstable. The application was running on a small Ubuntu VPS with Spring Boot, PostgreSQL, and Nginx.

Everything looked fine at first. The website worked normally for a while, then suddenly returned a 502 Bad Gateway error. After restarting the service, the website came back online, but the problem kept happening.

If your Spring Boot application randomly stops, crashes, or becomes unreachable on a VPS, this guide will help you troubleshoot the issue step by step.

This article focuses on practical debugging instead of guessing.

Step 1: Check Whether the Application Is Still Running

The first thing to verify is whether your Spring Boot service is actually running.

sudo systemctl status blog

Replace blog with your service name.

If the service is inactive, failed, or restarting repeatedly, you already know the problem is happening at the application level.

Useful commands:

sudo systemctl status blog
sudo systemctl restart blog
sudo journalctl -u blog -n 100 --no-pager

Step 2: Check the Application Logs

Before changing any configuration, read the logs.

sudo journalctl -u blog -n 200 --no-pager

Look for:

  • Java exceptions
  • Database connection failures
  • Port conflicts
  • OutOfMemoryError
  • Startup failures

Many developers immediately increase RAM or restart the server without checking logs first. This usually hides the real problem.

Step 3: Verify Nginx

If users see a 502 Bad Gateway page, Nginx is often the messenger, not the cause.

Check whether Nginx is healthy:

sudo systemctl status nginx

Check recent logs:

sudo journalctl -u nginx -n 100 --no-pager

Common scenarios:

  • Spring Boot is down
  • Spring Boot is listening on the wrong port
  • Reverse proxy configuration is incorrect

If Nginx is healthy but the backend is unavailable, continue with the next steps.

Step 4: Check Memory Usage

Memory problems are one of the most common reasons for unexpected application crashes.

free -h

Example:

Mem: 1.9Gi total
Used: 1.1Gi
Available: 569Mi
Swap: 0B

Pay special attention to:

  • Available memory
  • Swap size

A server with no swap is much more vulnerable to memory spikes.

Step 5: Check for OOM Killer Events

Linux includes a protection mechanism called the Out Of Memory (OOM) Killer.

When the operating system runs out of memory, it may terminate processes automatically.

Check kernel logs:

journalctl -k | grep -i oom

Or:

dmesg -T | grep -i "killed process"

If you see messages similar to:

Out of memory: Killed process 12345 (java)

you have found the real cause.

In my case, Linux repeatedly killed the Java process even though the application was configured with memory limits.

For a detailed explanation of this issue, see:

→ How I Fixed a Spring Boot Application That Kept Getting Killed by the Linux OOM Killer

Step 6: Identify the Largest Memory Consumers

Check which processes consume the most memory.

ps aux --sort=-rss | head -20

Typical services include:

  • Java
  • PostgreSQL
  • Redis
  • Docker
  • Elasticsearch
  • Nginx

Do not assume Spring Boot is always the problem.

In my investigation, I discovered that Docker services were still running even though I was not actively using containers.

Step 7: Verify Your Java Memory Settings

Review your systemd service configuration.

systemctl cat blog

Example:

ExecStart=/usr/bin/java \
-Xms256m \
-Xmx512m \
-XX:+UseG1GC \
-jar app.jar

For small VPS servers, setting a maximum heap size is important.

Without limits, Java may consume more memory than expected.

For more details, see:

→ My Spring Boot Memory Settings for a Small 2GB VPS

Step 8: Check Whether Swap Exists

Many developers skip this step.

Check swap:

swapon --show

Or:

free -h

If you see:

Swap: 0B

consider creating a swap file.

A lack of swap was the main reason my server became unstable.

Step 9: Create Swap Space

For a VPS with 2GB RAM:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Persist after reboot:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Verify:

free -h

You should now see swap space available.

For a deeper discussion about swap, see:

→ Why a 2GB VPS Needs Swap Space for Spring Boot Applications

Step 10: Check PostgreSQL Memory Usage

PostgreSQL is usually efficient, but it is still worth checking.

Useful settings:

show shared_buffers;
show work_mem;
show effective_cache_size;

For small servers, avoid allocating excessive memory to PostgreSQL.

Remember that PostgreSQL, Java, Nginx, and the operating system all compete for the same RAM.

Step 11: Review System Logs and Journal Usage

System logs are useful, but they should not grow forever.

Check journal size:

journalctl --disk-usage

Limit journal retention if necessary:

SystemMaxUse=200M
RuntimeMaxUse=100M

This helps keep small VPS instances clean and predictable.

→ What Is systemd-journald and Should You Limit Its Log Size?

Step 12: Monitor Before Making More Changes

After applying fixes, continue monitoring.

Useful commands:

free -h

ps aux --sort=-rss | head -20

journalctl -k | grep -i oom

Avoid making multiple changes at the same time.

Change one thing, observe the result, then continue.

Final Checklist

When a Spring Boot application keeps stopping on Ubuntu:

  • Verify the service status.
  • Read the application logs.
  • Check Nginx.
  • Check memory usage.
  • Search for OOM Killer events.
  • Identify memory-heavy processes.
  • Review Java memory settings.
  • Verify swap configuration.
  • Check PostgreSQL memory settings.
  • Monitor the server after applying fixes.

In my case, the root cause was surprisingly simple: a 2GB VPS running without swap. Once swap was added, the application became stable again.

The lesson is simple: always investigate first and optimize second.

Production issues are often caused by infrastructure details that are easy to overlook.