Course contentsShow
← Node.js
Lesson 1485 of 1,98013. Error Handling and Resilient SystemsFree lesson

Managing File Descriptor Limits

You will audit and increase file descriptor limits to ensure your app can handle high concurrency without 'too many open files' errors.

In this lesson, you will learn how to audit your operating system’s constraints and tune file descriptor limits to prevent the dreaded EMFILE: too many open files error in high-concurrency Node.js environments.

Understanding the Constraint

In Linux and Unix-like systems, everything is a file. When your Node.js application handles incoming network connections, opens database sockets, or performs asynchronous I/O, each interaction consumes a file descriptor (FD). By default, many operating systems impose a strict limit on how many FDs a single process can hold open at once. If your application attempts to open a new file or socket after reaching this limit, the kernel will refuse the request, leading to service degradation or total failure.

Auditing and Increasing Limits

Before scaling, you must verify your current soft and hard limits. You can check the current process limit within your Node.js application using process.getrlimit('nofile'):

const { getrlimit } = require('node:process');

const limits = getrlimit('nofile');
console.log(`Soft limit: ${limits.soft}, Hard limit: ${limits.hard}`);

If your application handles thousands of concurrent users, the default limit (often 1024) will be exhausted quickly.

Implementation at the System Level

You can temporarily increase the limit for your current shell session using ulimit -n 65535. However, for production resilience, you must configure this permanently. Update the /etc/security/limits.conf file to ensure the Node.js user has sufficient overhead:

# /etc/security/limits.conf
node_user    soft    nofile    65535
node_user    hard    nofile    65535

Best Practices for Resilience

Simply increasing the limit is not a silver bullet. You should monitor your FD usage patterns to detect resource leaks, such as forgotten fs.close() calls or unmanaged socket connections. In a resilient system, the FD limit acts as a circuit breaker; if you consistently hit it, your application logic—rather than just the system configuration—likely requires optimization regarding connection pooling or stream management.

Key Takeaway: You must align your operating system’s file descriptor limits with your concurrency demands to avoid runtime crashes caused by EMFILE errors during peak traffic.