π File Descriptors in Linux β The Complete Guide (Beginner to Advanced)

π§ Introduction
Every time you:
open a file π
make an API call π
connect to a database ποΈ
chat in an app π¬
π Your system is using file descriptors (FDs) behind the scenes.
They are simple, powerful, and critical for system performance and scalability.
This blog explains file descriptors in a way that:
beginners can understand easily
developers can apply in real-world systems
π½οΈ What is a File Descriptor? (Canteen Analogy)
π§© Simple Analogy β Canteen Token System
Imagine a college/office canteen π
Food items = files/resources
Canteen staff = Operating System (OS)
Token number = file descriptor
π― How it works:
Instead of saying:
βGive me one masala dosa with extra chutney from counter 2β
You simply say:
βToken #5β
π Staff already knows:
- Token #5 β your order
π Important detail (same as FDs!)
Once your order is served:
Token #5 becomes free
Next person may get token #5 again
π Just like file descriptors are reused
π§ One-line definition:
A file descriptor is a small number used by the OS to identify and manage an open resource.
π’ Standard File Descriptors
Every Linux program starts with 3 default FDs:
FD Name Purpose
-------------------------
0 stdin Input (keyboard)
1 stdout Output (screen)
2 stderr Error messages
π Diagram
Program starts:
[Process]
|
---------
| 0 | β Keyboard (Input)
| 1 | β Screen (Output)
| 2 | β Error Output
---------
βοΈ How File Descriptors Work
Step-by-step
int fd = open("file.txt", O_RDONLY);
π§ What happens internally:
OS receives a request
Opens file
Finds the lowest free number
Assigns FD (e.g., 3)
π Diagram
Process FD Table:
FD β Resource
------------------------
0 β Keyboard
1 β Screen
2 β Error screen
3 β file.txt
π FD Allocation Rule (Very Important)
π OS always gives the lowest available FD
π Example
FDs in use: 0, 1, 2, 4, 5
Free FD: 3
Next open() β FD = 3
β Not like this:
Highest FD = 5
Next FD β 6
π Everything is a File in Linux
π File descriptors are not just for files
Resource Type Example
--------------------------------
File file.txt
Socket network connection
Pipe process communication
Device keyboard, disk
π Lifecycle of a File Descriptor
OPEN β USE β CLOSE
π Diagram
open() read/write close()
| | |
v v v
[FD] ------> [DATA] ------> [FREE]
π» Example
int fd = open("file.txt", O_RDONLY);
read(fd, buffer, size);
close(fd);
β οΈ File Descriptor Leak (Silent Killer)
π§ What is it?
π Opening resources but not closing them
π Example
while True:
open("file.txt")
π Diagram
Iteration β FD Count
1 β FD 3
2 β FD 4
3 β FD 5
...
1024 β π₯ Crash
β Error
Too many open files
𧨠Real-world impact
Server stops accepting users
Logs stop writing
Database connections fail
Random errors appear
π§ͺ How to Check FDs in Linux
π List FDs
lsof -p <pid>
π Count FDs
ls /proc/<pid>/fd | wc -l
π FD Limits in Linux
Type Meaning
--------------------------
Soft Current usable limit
Hard Maximum allowed
π Check limit
ulimit -n
π Typical values
Default β 1024
Production β 65535+
πΆ File Descriptors & fork()
When a process creates a child:
π Child inherits all FDs
π Diagram
Before fork:
Parent
|
FD 3 β file.txt
----------------------
After fork:
Parent Child
| |
FD 3 β file.txt FD 3 β file.txt
π Both share the same resource!
π FD Duplication
dup2(oldfd, newfd);
π Diagram
FD 1 β Screen
dup2(3,1)
FD 1 β file.txt
π Used in:
ls > output.txt
β‘ Real-World Use Cases
π¬ Chat Applications
1 user = 1 socket = 1 FD
1000 users = 1000 FDs
π€ Backend APIs
1 request:
β socket FD
β DB FD
β log FD
π Multiple FDs per request
ποΈ Audio/Video Apps
1 user β multiple streams β multiple FDs
π Very high FD usage
π§ Hidden Facts (Very Important)
π 1. FD numbers are reused
close(3)
open() β FD 3 again
𧬠2. Child processes share FDs
Parent closes FD β
The child can still use it β
β³ 3. TIME_WAIT state
Sockets stay briefly after closing
π₯ 4. FD leak is slow
Works fine initially
fails later
π§ 5. One user β one FD
1 user β 3β5 FDs
βοΈ 6. High-performance systems rely on FDs
epoll
event loops
π§© Best Practices
β Always close resources
with open("file.txt") as f:
data = f.read()
β Use connection pooling
reuse DB connections
reduce FD usage
β Monitor in production
track FD count
set alerts
β Increase limits
ulimit -n 65535
π― Final Summary
π§ Key Points
File descriptor = small number
Represents an open resource
Managed by OS
Reused efficiently
π Final Diagram
User Action
|
v
Open File / Socket
|
v
OS assigns FD (e.g., 3)
|
v
Program uses FD
|
v
Close FD β freed
π One-line takeaway
File descriptors are the invisible tokens that allow your program to communicate with files, networks, and the system.
π‘ Why it matters
Because it directly impacts:
scalability π
performance β‘
system stability π οΈ
Good developers donβt just take tokensβthey make sure to return them.
