What Is a File Descriptor in Simple Terms
When you open a file, the kernel does not give you the file directly. It gives you a numbered ticket — a file descriptor. To read or write, you present your ticket. When you are done, you close the ticket (close the file descriptor) and it becomes available for reuse.
This abstraction is what makes Unix so elegant: files, network sockets, pipes, and devices are all represented the same way. The same read() and write() system calls work on all of them.
How It Works
Every process has its own file descriptor table. The kernel maintains a system-wide open file table that the process tables reference.
Process file descriptor table:+----+----------------------------------------+| FD | Points to |+----+----------------------------------------+| 0 | stdin (keyboard or pipe input) || 1 | stdout (terminal or pipe output) || 2 | stderr (terminal error output) || 3 | /var/log/app.log (opened by the app) || 4 | socket (TCP connection to database) || 5 | /etc/config.yaml (config file) |+----+----------------------------------------+The three standard file descriptors:
0 stdin Standard Input Default: keyboard in interactive shell In scripts: first positional input 1 stdout Standard Output Default: terminal screen Redirect: command > file.txt 2 stderr Standard Error Default: terminal screen (separate from stdout) Redirect: command 2> errors.txtI/O redirection uses file descriptors:
## Redirect stdout (fd 1) to filecommand > output.txtcommand 1> output.txt ## same thing ## Redirect stderr (fd 2) to filecommand 2> errors.txt ## Redirect both stdout and stderr to same filecommand > all.txt 2>&1## 2>&1 means: redirect fd 2 to wherever fd 1 is currently pointing ## Appendcommand >> output.txt ## Discard outputcommand > /dev/null ## discard stdoutcommand 2> /dev/null ## discard stderrcommand > /dev/null 2>&1 ## discard both ## Redirect stdin from filecommand < input.txt ## Here-document: inline stdincat << 'EOF'This is line 1This is line 2EOFPractical Commands
## List open file descriptors for a processls -la /proc/$$/fd/## Shows stdin, stdout, stderr and any open files ## List open files for all processes (verbose)lsof ## List open files for a specific processlsof -p 1234 ## List open files by a specific userlsof -u www-data ## Find which process has a file openlsof /var/log/nginx/access.log ## Find processes with deleted files still openlsof | grep deleted## These files consume disk space but show as deleted in ls ## Check file descriptor limitulimit -n## Typical: 1024 (too low for high-traffic servers) ## Increase limit for current sessionulimit -n 65536 ## Set system-wide limit in /etc/security/limits.confcat /etc/security/limits.conf## www-data soft nofile 65536## www-data hard nofile 65536 ## Check current usage for a processcat /proc/1234/limits | grep 'open files'ls /proc/1234/fd | wc -l ## count open FDsToo many open files error:
Error: EMFILE: too many open filesError: accept4: Too many open files This means the process has hit its file descriptor limit.Each network connection uses one file descriptor.A busy web server handling 10000 connections needsat least 10000 file descriptors plus more for log files,configuration files, and other resources.## Increase for nginx in /etc/nginx/nginx.confworker_rlimit_nofile 65536; ## Increase for systemd services in unit file[Service]LimitNOFILE=65536 ## Verify the service picked up the new limitcat /proc/$(pidof nginx)/limits | grep 'open files'Troubleshooting
| Symptom | Command | What to Look For |
|---|---|---|
| "Too many open files" error | `lsof -p PID | wc -l` |
| Disk space not freed after delete | `lsof | grep deleted` |
| Cannot delete file in use | lsof filename |
Process with file open |
| High FD usage | `ls /proc/PID/fd | wc -l` |
PLACEMENT PRO TIP**Tip:** When a file is deleted but disk space is not freed, a process still has the file descriptor open. The data blocks are not released until all file descriptors referencing the file are closed. `lsof | grep deleted` finds these. Restarting the process closes its file descriptors and frees the space.
REMEMBER THIS**Remember:** File descriptor exhaustion is a common cause of production failures in high-traffic services. The default limit of 1024 is appropriate for a developer laptop but completely inadequate for a production web server handling thousands of concurrent connections. Always increase the limit as part of production configuration.