The sudden, intermittent crash of a development server with the cryptic "Too many open files (os error 24)" message is a frustration familiar to any modern JavaScript developer on Linux. This error halts productivity, especially when using high-performance tools like Next.js with Turbopack or Bun or Nodemon, which demand more resources than the operating system’s defaults allow.
This guide provides the definitive, copy-and-paste solution to permanently configure your Kubuntu system to eliminate this bottleneck, ensuring a stable, high-performance development environment.
1. The Development Dilemma: Why the System Fails
The Problem: File Descriptors (FDs) and Low Limits
The error is a direct violation of a core operating system limit, not a bug in your code. Every open resource—a file, a network connection, a pipe, or a monitoring process—is tracked by a File Descriptor (FD).
The Default: On Linux (and most Debian/Ubuntu systems), the default soft limit for FDs per process is usually 1024 or 4096.
The Trigger: Modern development servers, particularly those utilizing Hot Module Replacement (HMR) like Turbopack, must actively "watch" every file in your project directory, including the thousands of files nested deep within node_modules. Each watch consumes an FD, quickly exhausting the low default limit and crashing the process with os error 24.
The Sign: The telltale sign is the fatal message: Error [TurbopackInternalError]: Too many open files (os error 24), or similar variants like EMFILE: too many open files.
The Impact
The consequence is instability. The crash occurs occasionally because the total number of open FDs constantly fluctuates based on your workflow: the size of your project, the number of browser tabs, or other background applications (like a Language Server Protocol (LSP) running in VS Code).
2. The Solution: Three Essential System Configuration Steps
To provide stable operation, we must raise three independent, but related, system limits to a safe level (we will use a soft limit of 10000 for FDs, and 524288 for file watchers).
🚨 Prerequisite: You must use sudo for all file modifications. A simple text editor like nano is recommended.
Step 2.1: Raise the Inotify File Watcher Limit (Crucial for HMR)
This is the most critical fix for file-watching bundlers. This limit governs how many files the kernel can actively monitor.
Open the kernel configuration file:
sudo nano /etc/sysctl.conf
Add the following line to the end of the file:
fs.inotify.max_user_watches = 524288
Save and exit (Ctrl+O, Enter, Ctrl+X in nano).
Apply the change immediately:
sudo sysctl -p
Step 2.2: Set File Descriptor Limit for PAM Sessions (limits.conf)
This change ensures that all terminal sessions (TTY, SSH, etc.) inherit a safe soft limit.
Open the PAM limits configuration file:
sudo nano /etc/security/limits.conf
Add the following lines to the end of the file to set a soft limit of 10000 for all non-root users (*):
* soft nofile 10000
* hard nofile 65536
Save and exit.
Step 2.3: Set File Descriptor Limit for Systemd (Linux Desktop Sessions)
Since graphical logins often bypass the limits.conf file, we must set the limit explicitly in the systemd configuration that governs user sessions.
Edit the system-wide systemd configuration:
sudo nano /etc/systemd/system.conf
Find the [Manager] section and uncomment or add the DefaultLimitNOFILE line:
[Manager]
DefaultLimitNOFILE=10000:65536
Edit the user systemd configuration:
sudo nano /etc/systemd/user.conf
Find the [Manager] section and uncomment or add the DefaultLimitNOFILE line:
[Manager]
DefaultLimitNOFILE=10000:65536
Save and exit both files.
3. Finalize and Verify
Step 3.1: Apply All Changes
To ensure the new limits from limits.conf and the systemd configurations are correctly inherited by all new processes and sessions, a reboot is the most reliable method.
reboot
Step 3.2: Verification
After logging back in, open a new terminal and verify your new soft limit:
ulimit -n
Expected Output: The output should be 10000. If it is, your system is now configured for high-demand development.
Step 3.3: Back to Development
You can now confidently run your project without fear of the system crashing your environment:
❯ bun run dev
$ next dev
4. Troubleshooting and Reversion (The Emergency Fix)
If you needed to run your server before applying all the fixes, or if the permanent fix somehow didn't apply correctly, here is the emergency procedure.
The Temporary Command-Line Fix
You can temporarily override the soft limit for your current terminal session. This is reset when the terminal closes.
ulimit -n 8192
Run your development command in the same terminal session immediately after.
How to Revert Changes
If you encounter a new, unexpected error after making the permanent changes, you can revert the configurations to the default state:
Revert Inotify: Open /etc/sysctl.conf and comment out the line you added:
Then run sudo sysctl -p.
Revert PAM: Open /etc/security/limits.conf and remove the two lines you added.
Revert Systemd: Open /etc/systemd/system.conf and /etc/systemd/user.conf and comment out the DefaultLimitNOFILE lines:
A final reboot will restore your system to its original state. However, with the limits set to 10000, you should experience robust stability without the need for reversion.
The sudden, intermittent crash of a development server with the cryptic "Too many open files (os error 24)" message is a frustration familiar to any modern JavaScript developer on Linux. This error halts productivity, especially when using high-performance tools like Next.js with Turbopack or Bun or Nodemon, which demand more resources than the operating system’s defaults allow.
This guide provides the definitive, copy-and-paste solution to permanently configure your Kubuntu system to eliminate this bottleneck, ensuring a stable, high-performance development environment.
1. The Development Dilemma: Why the System Fails
The Problem: File Descriptors (FDs) and Low Limits
The error is a direct violation of a core operating system limit, not a bug in your code. Every open resource—a file, a network connection, a pipe, or a monitoring process—is tracked by a File Descriptor (FD).
The Default: On Linux (and most Debian/Ubuntu systems), the default soft limit for FDs per process is usually 1024 or 4096.
The Trigger: Modern development servers, particularly those utilizing Hot Module Replacement (HMR) like Turbopack, must actively "watch" every file in your project directory, including the thousands of files nested deep within
node_modules. Each watch consumes an FD, quickly exhausting the low default limit and crashing the process withos error 24.The Sign: The telltale sign is the fatal message:
Error [TurbopackInternalError]: Too many open files (os error 24), or similar variants likeEMFILE: too many open files.The Impact
The consequence is instability. The crash occurs occasionally because the total number of open FDs constantly fluctuates based on your workflow: the size of your project, the number of browser tabs, or other background applications (like a Language Server Protocol (LSP) running in VS Code).
2. The Solution: Three Essential System Configuration Steps
To provide stable operation, we must raise three independent, but related, system limits to a safe level (we will use a soft limit of 10000 for FDs, and 524288 for file watchers).
🚨 Prerequisite: You must use
sudofor all file modifications. A simple text editor likenanois recommended.Step 2.1: Raise the Inotify File Watcher Limit (Crucial for HMR)
This is the most critical fix for file-watching bundlers. This limit governs how many files the kernel can actively monitor.
Open the kernel configuration file:
Add the following line to the end of the file:
# Increase the number of inotify file watches for development (Turbopack, webpack, etc.) fs.inotify.max_user_watches = 524288Save and exit (Ctrl+O, Enter, Ctrl+X in nano).
Apply the change immediately:
Step 2.2: Set File Descriptor Limit for PAM Sessions (
limits.conf)This change ensures that all terminal sessions (TTY, SSH, etc.) inherit a safe soft limit.
Open the PAM limits configuration file:
Add the following lines to the end of the file to set a soft limit of 10000 for all non-root users (
*):# Set high soft and hard limits for max number of open file descriptors (nofile) # The hard limit is set high to allow future self-adjustment via ulimit -n * soft nofile 10000 * hard nofile 65536Save and exit.
Step 2.3: Set File Descriptor Limit for Systemd (Linux Desktop Sessions)
Since graphical logins often bypass the
limits.conffile, we must set the limit explicitly in the systemd configuration that governs user sessions.Edit the system-wide systemd configuration:
Find the
[Manager]section and uncomment or add theDefaultLimitNOFILEline:[Manager] # ... other settings ... DefaultLimitNOFILE=10000:65536 # ... other settings ...Edit the user systemd configuration:
Find the
[Manager]section and uncomment or add theDefaultLimitNOFILEline:[Manager] # ... other settings ... DefaultLimitNOFILE=10000:65536 # ... other settings ...Save and exit both files.
3. Finalize and Verify
Step 3.1: Apply All Changes
To ensure the new limits from
limits.confand the systemd configurations are correctly inherited by all new processes and sessions, a reboot is the most reliable method.Step 3.2: Verification
After logging back in, open a new terminal and verify your new soft limit:
ulimit -nExpected Output: The output should be 10000. If it is, your system is now configured for high-demand development.
Step 3.3: Back to Development
You can now confidently run your project without fear of the system crashing your environment:
4. Troubleshooting and Reversion (The Emergency Fix)
If you needed to run your server before applying all the fixes, or if the permanent fix somehow didn't apply correctly, here is the emergency procedure.
The Temporary Command-Line Fix
You can temporarily override the soft limit for your current terminal session. This is reset when the terminal closes.
ulimit -n 8192Run your development command in the same terminal session immediately after.
How to Revert Changes
If you encounter a new, unexpected error after making the permanent changes, you can revert the configurations to the default state:
Revert Inotify: Open
/etc/sysctl.confand comment out the line you added:# fs.inotify.max_user_watches = 524288Then run
sudo sysctl -p.Revert PAM: Open
/etc/security/limits.confand remove the two lines you added.Revert Systemd: Open
/etc/systemd/system.confand/etc/systemd/user.confand comment out theDefaultLimitNOFILElines:# DefaultLimitNOFILE=10000:65536A final reboot will restore your system to its original state. However, with the limits set to 10000, you should experience robust stability without the need for reversion.