Why /tmp Can Crash Your Spring Boot App and How to Fix It
An e‑commerce Spring Boot service crashed when uploading large files because Linux’s /tmp is a memory‑based tmpfs that fills RAM, causing OOM kills; the article explains the underlying tmpfs behavior, common pitfalls, and a three‑step solution using /var/tmp with proper configuration and permissions.
Are You Experiencing the "Memory Trap"? (Real Case)
Last Wednesday at 2:47 AM, an e‑commerce upload service crashed. The ops engineer saw the log:
java.io.IOException: The temporary upload location [/tmp/tomcat.8080.123456789] is not validStrangely, the server memory usage was only 30%, disk space was ample, and the problem persisted after a restart.
Why /tmp Is a "Time Bomb" (Core Principle)
Misconception: /tmp Is Just Disk Space
df -h /tmp
# Example output:
# tmpfs 1.8G 0 1.8G 0% /tmpThe key truth: /tmp is a tmpfs (memory‑based file system). Its size equals about 50 % of RAM (e.g., 8 GB on a 16 GB machine). Uploading large files writes directly to memory, and system cleaners like tmpwatch or systemd-tmpfiles may delete files automatically.
Your Spring Boot Is Facing a "Triple Blow"
Problem stages:
Uploading : Memory spikes to 95 % → OOM Killer terminates the process (files are written to memory via tmpfs).
System Cleanup : After a restart, uploads fail because the /tmp/tomcat.xxx directory was removed.
Configuration Failure : spring.servlet.multipart.location still errors due to missing or incorrect directory permissions.
💡 Lesson: On Amazon Linux 2023, /tmp defaults to tmpfs, so a 500 MB upload consumes 500 MB of RAM; the system cleanup then “explodes” the process.
Ultimate Solution: Three Steps to Avoid the Memory Trap
Step 1: Abandon /tmp, Use /var/tmp (Linux Recommendation)
# Create a safe directory (required!)
sudo mkdir -p /var/tmp/springboot-uploads
sudo chmod 777 /var/tmp/springboot-uploadsStep 2: Spring Boot Configuration (Double Insurance)
# application.properties
# 1. JVM global temporary directory (affects all Java operations)
-Djava.io.tmpdir=/var/tmp/springboot-uploads
# 2. Spring file‑upload specific directory
spring.servlet.multipart.location=/var/tmp/springboot-uploads/upload
# 3. Embedded Tomcat work directory
server.tomcat.basedir=/var/tmp/springboot-uploads/tomcat
# 4. Prevent large files from occupying memory
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=200MB💡 Why choose /var/tmp? It is not tmpfs (it resides on disk), so space is not limited by RAM. The system does not auto‑clean it (unlike /tmp, which is typically cleared after 30 days).
Why Does Your Configuration Still Fail? (Pitfall Guide)
Common Error 1: Forgetting to Create the Directory
// Log error: java.io.IOException: The temporary upload location is not valid
// Fix: Create the directory beforehand!
File dir = new File("/var/tmp/springboot-uploads");
if (!dir.exists()) dir.mkdirs(); // Auto‑create (recommended)Common Error 2: Incomplete Configuration Override
# Wrong: only changed multipart.location
spring.servlet.multipart.location=/var/tmp/springboot-uploads/upload
# JVM still uses default /tmp → error persistsCorrect approach: Apply three overlapping configurations.
# application.properties
spring.servlet.multipart.location=/var/tmp/springboot-uploads/upload
server.tomcat.basedir=/var/tmp/springboot-uploads/tomcatCommon Error 3: Insufficient Permissions
# Wrong: application lacks write permission
chown -R nobody:nobody /var/tmp/springboot-uploadsCorrect permissions: Ensure the process (e.g., tomcat / java ) has write access; chmod 777 works quickly (use a dedicated user in production).
Validate Configuration Effectiveness (Final Checks)
Method 1: Print Temporary Path at Startup
@SpringBootApplication
public class App {
public static void main(String[] args) {
System.out.println("JVM temporary directory: " + System.getProperty("java.io.tmpdir"));
SpringApplication.run(App.class, args);
}
}Startup logs should show:
JVM temporary directory: /var/tmp/springboot-uploadsMethod 2: Verify Uploaded File Location
# After uploading a 100 MB file
ls -lh /var/tmp/springboot-uploads/upload
# Should display a 100 MB temporary fileWhy Is This the "99% Developers' Pitfall"?
Developers often assume /tmp is disk space, leading to memory exhaustion when uploading large files, causing OOM kills, or they only adjust spring.servlet.multipart.location while the system still cleans /tmp, resulting in service outages.
Bottom line: In Linux, /tmp is a memory trap; /var/tmp is the safe zone. Amazon Linux 2023, CentOS 8, Ubuntu 22.04 all default to this behavior.
Final Configuration Snippet (Copy‑Paste Ready)
# application.properties
# 1. JVM global temporary directory (required!)
-Djava.io.tmpdir=/var/tmp/springboot-uploads
# 2. File‑upload specific directory
spring.servlet.multipart.location=/var/tmp/springboot-uploads/upload
# 3. Tomcat work directory
server.tomcat.basedir=/var/tmp/springboot-uploads/tomcat
# 4. Limit file size (prevent memory overflow)
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=200MB # Server initialization script (one‑click)
sudo mkdir -p /var/tmp/springboot-uploads/{upload,tomcat}
sudo chmod 777 /var/tmp/springboot-uploadsConclusion
"Stop letting /tmp eat your memory! Use /var/tmp instead, with three lines of config and two commands, and enjoy safe, stable file uploads."
Next time your service crashes at 3 AM, don’t ask "why"—your /tmp is silently killing your application.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Cognitive Technology Team
Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
