Understanding Linux System Directories: What Goes Where?

The Linux filesystem follows the Filesystem Hierarchy Standard (FHS), which defines what each directory contains. Key directories include: /etc for system configuration files, /home for user files, /var for variable data like logs, /usr for installed programs and libraries, /bin and /sbin for essential commands, /tmp for temporary files, /proc and /sys for virtual kernel interfaces, and /dev for device files. Understanding this structure explains where to find any file on a Linux system and why Linux is organized differently from Windows.

A Map of the Linux Filesystem

Open a terminal on any Linux system and list the root directory:

$ ls /
bin   dev  home  lib    lib64  lost+found  mnt  proc  run   srv  tmp  var
boot  etc  init  lib32  libx32 media       opt  root  sbin  sys  usr

Unlike Windows where your files and applications are organized under C:\Users, C:\Program Files, and a handful of other locations, Linux spreads its contents across dozens of top-level directories, each with a specific purpose. At first glance, this structure can seem arbitrary or overwhelming. Where does software get installed? Where are configuration files? Where do log files go?

The answer is not arbitrary at all — it follows the Filesystem Hierarchy Standard (FHS), a specification that defines what each directory should contain and why. This standard, maintained by the Linux Foundation, gives Linux its consistent structure across distributions. A file at /etc/nginx/nginx.conf is the nginx configuration on Ubuntu, Fedora, Arch, and any other Linux distribution. A log file at /var/log/syslog is a system log on any Debian-based system. This consistency is why documentation, tutorials, and system administration knowledge transfers between distributions.

Understanding the Linux directory hierarchy transforms you from someone who can follow instructions to someone who can figure out where things are on any Linux system — because the structure itself tells you where to look. It also explains Linux’s design philosophy: separating user data from system data, read-only content from frequently-changing content, essential boot-time binaries from optional software, and user programs from system administration tools.

This article walks through every significant directory in the Linux filesystem hierarchy, explaining what it contains, why it exists where it does, and how understanding it helps you work more effectively with Linux.

The Root of Everything: /

The forward slash / is the root of the entire Linux filesystem — the single starting point from which all other paths descend. There is no drive letter, no “My Computer” container. Everything begins at /.

When you see a path like /home/sarah/documents/report.pdf, it means: starting from the root (/), go into home, then into sarah, then into documents, and find report.pdf.

The root directory is owned by root and is typically mounted from the system’s primary partition. Everything else — other partitions, USB drives, network shares — is grafted onto this tree through the mounting system.

/bin and /sbin: Essential Command Binaries

/bin (Binaries)

/bin contains essential user command binaries that must be available in single-user mode and during early system boot — before other filesystems are mounted. Commands every user needs are here:

$ ls /bin | head -20
bash    cat    chmod   cp    date   dd   df   dir   echo   false
grep    gzip   hostname  ls   mkdir  mv   ps   pwd   rm     sh

On modern Ubuntu, Fedora, and Arch Linux, /bin is a symbolic link to /usr/bin. The distinction between /bin and /usr/bin was historically important (early systems kept /usr on a separate partition that might not be mounted at boot), but the separation is now considered obsolete. The FHS has been updated to allow this merge.

$ ls -la /bin
lrwxrwxrwx 1 root root 7 Jan 15 2023 /bin -> usr/bin

/sbin (System Binaries)

/sbin contains essential system administration commands — programs primarily used by root to manage, repair, and administer the system:

$ ls /sbin | head -20
fdisk   fsck    ifconfig  init   ip    iptables  ldconfig  lvm
mkfs    modprobe mount    reboot  shutdown  swapon  tune2fs  useradd

Like /bin, /sbin is now a symlink to /usr/sbin on modern distributions:

$ ls -la /sbin
lrwxrwxrwx 1 root root 8 Jan 15 2023 /sbin -> usr/sbin

/usr: The Main Software Tree

/usr (historically “Unix System Resources,” sometimes retroactively called “User System Resources”) is the second-largest directory on most Linux systems and contains the bulk of installed software. It is designed to be read-only and shareable across multiple systems on a network.

/usr/bin

The primary location for user-facing program binaries. When you install Firefox, git, Python, gcc, or virtually any application through your package manager, the main executable lands in /usr/bin:

$ ls /usr/bin | wc -l
1347    # Over a thousand commands on a typical Ubuntu install

$ which firefox
/usr/bin/firefox

$ which python3
/usr/bin/python3

/usr/sbin

System administration programs that are not needed at early boot but are required for system management:

$ ls /usr/sbin | head -10
adduser   apache2   cron   deluser   nginx   sshd   useradd   userdel   visudo

/usr/lib

Libraries (shared code) used by programs in /usr/bin and /usr/sbin. These are .so (shared object) files — the Linux equivalent of .dll files on Windows:

$ ls /usr/lib | head -10
apt  bluetooth  cups  firefox  gcc  git  locale  python3  systemd  x86_64-linux-gnu

/usr/lib64 and /usr/lib32

On 64-bit systems, these directories contain 64-bit and 32-bit library variants respectively:

  • /usr/lib64 or /usr/lib/x86_64-linux-gnu — 64-bit libraries (primary)
  • /usr/lib32 or /usr/lib/i386-linux-gnu — 32-bit libraries (for running 32-bit programs)

/usr/share

Architecture-independent data — files that are the same regardless of CPU type and can be shared across different machines:

$ ls /usr/share | head -15
applications    backgrounds    bash-completion  ca-certificates
doc             fonts          games            gnome
icons           locale         man              mime
pixmaps         sounds         themes           zoneinfo

Notable subdirectories:

  • /usr/share/man/ — man page files for all installed programs
  • /usr/share/doc/ — package documentation, changelogs, READMEs
  • /usr/share/locale/ — translation files for internationalization
  • /usr/share/fonts/ — system fonts
  • /usr/share/applications/ — .desktop files for application launchers

/usr/include

Header files for C and C++ development. When you compile programs that use system libraries, these files provide the function declarations and data structure definitions:

$ ls /usr/include | head -10
arpa  bits  byteswap.h  ctype.h  dirent.h  errno.h  fcntl.h  fenv.h

/usr/local

Software installed locally by the system administrator, outside the package manager’s control. The structure mirrors /usr:

/usr/local/
├── bin/     ← Locally installed executables
├── lib/     ← Locally installed libraries
├── share/   ← Locally installed shared data
├── include/ ← Locally installed headers
└── etc/     ← Configuration for locally installed software

When you compile software from source and run make install, it typically installs into /usr/local/. This separation keeps package-manager-controlled software (/usr/) distinct from manually installed software (/usr/local/).

/usr/local/bin appears before /usr/bin in the default PATH, so locally installed versions take precedence over distribution packages.

/etc: System Configuration

/etc (historically “et cetera,” now commonly interpreted as “Editable Text Configuration”) contains system-wide configuration files. These are text files that administrators edit to configure how the system and its services behave.

$ ls /etc | head -30
apt          bash.bashrc  ca-certificates  crontab  default  fstab
group        hostname     hosts            init.d   locale   login.defs
modprobe.d   motd         network          nginx    os-release  passwd
profile      resolv.conf  shadow           shells   ssh       sudoers
systemd      timezone     udev             vim      wpa_supplicant

Key configuration files in /etc:

  • /etc/passwd — user account information
  • /etc/shadow — password hashes (root-readable only)
  • /etc/group — group definitions
  • /etc/fstab — filesystem mount configuration
  • /etc/hosts — static hostname-to-IP mappings
  • /etc/hostname — this machine’s hostname
  • /etc/resolv.conf — DNS resolver configuration
  • /etc/apt/ — APT package manager configuration
  • /etc/ssh/ — SSH server and client configuration
  • /etc/nginx/ — nginx web server configuration
  • /etc/systemd/ — systemd configuration
  • /etc/crontab — system-wide scheduled tasks

Key principle: /etc contains configuration, not executables, not data. If a program reads settings on startup, those settings are in /etc. Package managers install default configurations here; administrators customize them.

/home: User Home Directories

/home contains the personal directories for all regular user accounts:

$ ls /home
alice  bob  carol  sarah

Each user’s home directory is their personal space — completely under their control. By convention, personal files, application configuration (dotfiles), and user-specific data all live here:

/home/sarah/
├── .bashrc          ← Bash configuration
├── .config/         ← Application config (XDG standard)
├── .local/          ← User-local applications and data
├── .ssh/            ← SSH keys and config
├── Desktop/
├── Documents/
├── Downloads/
├── Music/
├── Pictures/
└── Videos/

/home is often placed on a separate partition. This allows reinstalling the operating system without touching user data — simply mount the existing /home partition after reinstallation.

The root user’s home is not in /home — it is at /root. This ensures root always has a home directory even if the /home partition fails to mount.

/root: The Root User’s Home

$ ls /root
# (requires root access to view)
$ sudo ls /root
backup_scripts  .bashrc  .profile  system_notes.txt

/root is the home directory for the root superuser, placed at the filesystem root rather than inside /home for practical and historical reasons. Root’s files are kept separate from regular user files, and /root remains accessible even in recovery situations when /home may not be mounted.

/var: Variable Data

/var contains files whose content changes frequently during normal system operation — as opposed to /usr which is relatively static:

/var/log

System and application log files — perhaps the most important subdirectory for system administrators:

$ ls /var/log
apt      auth.log   boot.log  btmp      cups     dmesg
dpkg.log  kern.log  lastlog   mail.log  nginx    syslog
ubuntu-advantage.log  ufw.log  wtmp

Key log files:

  • /var/log/syslog — general system messages (Ubuntu/Debian)
  • /var/log/auth.log — authentication attempts and sudo usage
  • /var/log/kern.log — kernel messages
  • /var/log/dpkg.log — package installation and removal history
  • /var/log/nginx/ — nginx web server access and error logs
  • /var/log/apache2/ — Apache web server logs

/var/cache

Cached data from applications — can be safely deleted (though it will slow the next operation that needs to rebuild the cache):

$ ls /var/cache
apt      debconf  fontconfig  ldconfig  man   samba   snapd
  • /var/cache/apt/archives/ — downloaded .deb packages (can free significant space with sudo apt clean)

/var/lib

Persistent application state data — data that programs need to maintain between invocations:

$ ls /var/lib
apt       dpkg      flatpak   mysql     nginx     postgresql
snapd     systemd   ufw       update-notifier
  • /var/lib/dpkg/ — dpkg’s database of installed packages
  • /var/lib/mysql/ or /var/lib/postgresql/ — database files
  • /var/lib/flatpak/ — installed Flatpak applications

/var/spool

“Spooled” data awaiting processing:

  • /var/spool/cron/ — user crontab files
  • /var/spool/mail/ — local mail for users
  • /var/spool/cups/ — print jobs

/var/tmp

Temporary files that should persist across reboots (unlike /tmp which is typically cleared at boot). Files here are preserved but may be cleaned periodically.

/tmp: Temporary Files

/tmp stores temporary files created by programs and users during a session. On most modern systems, /tmp is a tmpfs — a RAM-based filesystem that is cleared on every reboot:

$ df -h /tmp
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           7.9G  2.3M  7.9G   1% /tmp

Programs use /tmp for scratch space, inter-process communication files, and temporary downloads. Because it is in RAM, it is fast. Because it is cleared on reboot, it should not store anything important.

The sticky bit is set on /tmp (drwxrwxrwt) — anyone can create files, but only the file’s owner can delete their own files.

/proc: The Process and Kernel Virtual Filesystem

/proc is a virtual filesystem — it does not exist on disk but is created by the Linux kernel in memory, providing a window into running processes and kernel state:

$ ls /proc | head -20
1       15      234    buddyinfo  cmdline     cpuinfo    crypto
devices diskstats dma  driver     execdomains  fb         filesystems

Numbered directories (1, 15, 234…) correspond to process IDs. Each contains information about that running process:

$ ls /proc/1/
attr  cgroup  cmdline  comm  cwd  environ  exe  fd  maps  mem  status

Key /proc files:

  • /proc/cpuinfo — CPU details (what lscpu reads)
  • /proc/meminfo — memory information (what free reads)
  • /proc/version — kernel version
  • /proc/mounts — currently mounted filesystems
  • /proc/uptime — system uptime in seconds
  • /proc/net/dev — network interface statistics
  • /proc/loadavg — system load average
  • /proc/sys/ — tunable kernel parameters (modifiable with sysctl)
$ cat /proc/cpuinfo | grep "model name" | head -1
model name	: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz

$ cat /proc/uptime
431820.35 2341847.23

/proc is the source of truth that tools like ps, top, free, and lscpu read — they are essentially formatted views of /proc contents.

/sys: The System and Hardware Virtual Filesystem

/sys is another virtual filesystem exposing kernel data, specifically hardware devices and their drivers — more structured and hardware-oriented than /proc:

$ ls /sys
block  bus  class  dev  devices  firmware  fs  hypervisor  kernel  module  power
  • /sys/class/ — devices organized by type (net, block, input, etc.)
  • /sys/devices/ — the full device tree
  • /sys/bus/ — buses the kernel knows about (PCI, USB, etc.)
  • /sys/block/ — block devices (storage)
  • /sys/kernel/ — kernel parameters and state

Many tunable system parameters live in /sys. For example, checking battery status:

$ cat /sys/class/power_supply/BAT0/capacity
78    # Battery at 78%

$ cat /sys/class/power_supply/BAT0/status
Discharging

Setting CPU governor (performance, powersave, etc.):

$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
powersave

$ echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

/dev: Device Files

/dev contains device files — special files that represent hardware devices and virtual devices. Reading and writing these files communicates directly with the hardware:

$ ls /dev | head -20
block  char  console  disk  fd  full  fuse  hidraw0  input  kvm
loop0  mem   net  null  pts  random  sda  sdb  shm  stdin  stdout  tty  urandom  zero

Key device files:

  • /dev/sda, /dev/sdb — storage drives
  • /dev/nvme0n1 — NVMe SSD
  • /dev/tty1 through /dev/tty6 — virtual console terminals
  • /dev/pts/ — pseudo-terminal devices (terminal emulator windows)
  • /dev/null — the black hole: discards all input, returns EOF on read
  • /dev/zero — returns infinite null bytes when read
  • /dev/random, /dev/urandom — random number generators
  • /dev/stdin, /dev/stdout, /dev/stderr — standard I/O streams
  • /dev/loop0, /dev/loop1 — loop devices for mounting ISO images
# /dev/null: discard output
$ noisy_command > /dev/null 2>&1

# /dev/zero: create a file of zeros (e.g., for testing)
$ dd if=/dev/zero of=testfile bs=1M count=100

# /dev/urandom: generate random data
$ dd if=/dev/urandom of=random_key.bin bs=32 count=1

/boot: Boot Loader and Kernel Files

/boot contains the files needed to boot the system — the kernel, initial RAM disk, and bootloader configuration:

$ ls /boot
config-6.8.0-49-generic   grub                         initrd.img-6.8.0-49-generic
config-6.8.0-51-generic   initrd.img                   initrd.img-6.8.0-51-generic
efi                        initrd.img.old               vmlinuz
System.map-6.8.0-49-generic  System.map-6.8.0-51-generic  vmlinuz-6.8.0-51-generic

Key files:

  • vmlinuz-* — the compressed Linux kernel
  • initrd.img-* — the initial RAM disk (temporary filesystem used during early boot)
  • grub/ — GRUB bootloader configuration
  • efi/ — EFI bootloader files (on UEFI systems)
  • config-* — kernel build configuration
  • System.map-* — kernel symbol table (for debugging)

/boot is often on a separate small partition. On UEFI systems, the EFI System Partition (/boot/efi) is formatted as FAT32 and is where the UEFI firmware looks for boot files.

/lib, /lib32, /lib64: Essential Libraries

Essential shared libraries needed by binaries in /bin and /sbin, required at boot before /usr is mounted:

$ ls /lib | head -10
firmware  modules  systemd  udev  x86_64-linux-gnu
  • /lib/modules/ — kernel module files (loadable drivers)
  • /lib/firmware/ — firmware files for hardware devices
  • /lib/systemd/ — systemd internals

Like /bin, modern distributions symlink /lib to /usr/lib:

$ ls -la /lib
lrwxrwxrwx 1 root root 7 Jan 15 2023 /lib -> usr/lib

/media and /run/media: Removable Media

/media (and on newer systemd distributions, /run/media/username/) is where removable storage is automatically mounted:

$ ls /media/sarah/
MYUSB    BACKUP_DRIVE    PHOTOS_SD

When you plug in a USB drive or SD card, the desktop environment creates a subdirectory here and mounts the device. The mount point name usually matches the drive’s label.

/mnt: Manual Mount Points

/mnt is the traditional location for temporary manual mounts — storage you are mounting for a specific task rather than automatic or permanent access:

$ sudo mount /dev/sdb1 /mnt/backup
$ ls /mnt/backup
archives  databases  logs
$ sudo umount /mnt/backup

By convention, system administrators create subdirectories under /mnt for specific purposes: /mnt/usb, /mnt/nas, /mnt/iso. Unlike /media (which is managed automatically), /mnt is entirely manual.

/opt: Optional/Third-Party Software

/opt is for optional, self-contained application packages — software that is not managed by the distribution’s package manager and installs as a standalone directory:

$ ls /opt
google    containerd    pycharm    teamviewer    zoom

Commercial software, vendor-specific tools, and large self-contained applications often install here. Each application gets its own subdirectory:

/opt/google/chrome/    ← Google Chrome
/opt/pycharm/          ← JetBrains PyCharm IDE
/opt/zoom/             ← Zoom video conferencing

The key characteristic of /opt software: it does not scatter files across /usr/bin, /usr/lib, etc. Everything the application needs lives inside its /opt/appname/ directory, making removal as simple as deleting that directory.

/srv: Service Data

/srv contains data served by the system’s services:

$ ls /srv
ftp  http  tftp
  • /srv/http/ or /srv/www/ — web server document root (though /var/www/ is more common in practice)
  • /srv/ftp/ — FTP server files

/srv is less consistently used than other directories — many distributions and applications prefer /var/www/ for web content and other locations for service data. Its presence in the FHS provides a standardized location when used.

/run: Runtime Data

/run (a relatively modern addition to the FHS, replacing /var/run) stores runtime data for running services — PIDs, sockets, lock files, and other transient data that should not persist across reboots:

$ ls /run
NetworkManager   cups    dbus    docker.sock    lock    mount   networkd
snapd.socket     sshd.pid  systemd  udev   user
  • /run/sshd.pid — SSH daemon’s process ID
  • /run/docker.sock — Docker’s Unix socket
  • /run/systemd/ — systemd runtime state
  • /run/user/1000/ — per-user runtime directory (for the user with UID 1000)

/run is a tmpfs — entirely in RAM, cleared on reboot. This ensures stale PID files and sockets from a previous session never interfere with a new boot.

/lost+found: Filesystem Recovery

Each ext4 filesystem has a lost+found directory at its root. When fsck (filesystem check) repairs a filesystem after a crash or unclean unmount, it may recover file fragments or orphaned files (inodes with no directory entry). Recovered data is placed in lost+found with numeric names:

$ ls /lost+found
# (usually empty on healthy systems)
# After fsck recovery might contain: #12345  #67890  #11111

Only ext filesystems (ext2, ext3, ext4) have lost+found. You can safely ignore it — its contents are only relevant after a filesystem corruption event.

The Linux vs. Windows Directory Comparison

Linux Windows Contents
/ C:\ Root of the filesystem
/home/username/ C:\Users\username\ User’s personal files
/etc/ Registry + C:\Windows\System32\ System configuration
/usr/bin/ C:\Windows\System32\ + C:\Program Files\ Installed programs
/usr/share/ C:\Program Files\ (shared data) Shared application data
/var/log/ C:\Windows\Logs\ Log files
/tmp/ %TEMP% Temporary files
/dev/ No direct equivalent Device access
/proc/ No direct equivalent Process/kernel info
/opt/ C:\Program Files\ Optional applications

Quick Reference: Linux Directory Purposes

Directory Purpose
/ Root of the entire filesystem
/bin → /usr/bin Essential user commands
/sbin → /usr/sbin Essential system admin commands
/boot Kernel, initrd, bootloader
/dev Device files
/etc System configuration files
/home User home directories
/root Root user’s home directory
/lib → /usr/lib Essential shared libraries
/media Auto-mounted removable media
/mnt Manual temporary mount points
/opt Self-contained optional software
/proc Virtual: process and kernel info
/run Runtime transient data
/srv Service data (web, FTP)
/sys Virtual: hardware/device info
/tmp Temporary files (cleared on reboot)
/usr Installed software and data
/usr/bin User program binaries
/usr/lib Shared libraries
/usr/local Locally installed software
/usr/share Architecture-independent data
/var Variable/changing data
/var/log Log files
/var/cache Application caches
/var/lib Persistent application state

Conclusion: The Map Is the Territory

The Linux filesystem hierarchy is not bureaucratic complexity — it is a carefully considered organizational system that separates concerns: read-only from read-write, user data from system data, essential boot-time files from optional software, volatile runtime data from persistent configuration.

Once you internalize this map, Linux becomes significantly more navigable. Need to find where an application was installed? Check /usr/bin for the executable, /usr/lib for its libraries, /usr/share for its data, /etc for its configuration. Need to troubleshoot a service? Its logs are in /var/log, its configuration in /etc, its runtime state in /run. Need to install software outside the package manager? It belongs in /usr/local or /opt.

The FHS also explains why Linux tutorials transfer between distributions — Ubuntu and Fedora use the same directory structure. A sysadmin who knows where things are on one Linux system knows where to look on any Linux system. The hierarchy is the shared language of Linux administration.

Hot this week

What Are Snap, Flatpak, and AppImage Packages?

Learn what Snap, Flatpak, and AppImage are, how universal Linux packages work, their differences, pros and cons, and when to use each format for installing software.

How to Change Your Desktop Environment in Linux

Learn how to install and switch desktop environments in Linux — from GNOME to KDE Plasma, XFCE, MATE, Cinnamon, and more. Includes installation steps and how to choose the right DE.

What Is a Symbolic Link in Linux?

Learn what symbolic links (symlinks) are in Linux, the difference between soft and hard links, how to create them with ln, and practical uses for symlinks in system administration.

How to Mount and Unmount Drives in Linux

Learn how to mount and unmount drives, USB drives, and partitions in Linux using the mount command, /etc/fstab for persistent mounts, and how to safely eject external drives.

Understanding the Linux Man Pages: Your Built-in Documentation

Learn how to use Linux man pages to look up any command, understand its options, and navigate the built-in documentation system. Includes man, info, apropos, and whatis.

Topics

What Are Snap, Flatpak, and AppImage Packages?

Learn what Snap, Flatpak, and AppImage are, how universal Linux packages work, their differences, pros and cons, and when to use each format for installing software.

How to Change Your Desktop Environment in Linux

Learn how to install and switch desktop environments in Linux — from GNOME to KDE Plasma, XFCE, MATE, Cinnamon, and more. Includes installation steps and how to choose the right DE.

What Is a Symbolic Link in Linux?

Learn what symbolic links (symlinks) are in Linux, the difference between soft and hard links, how to create them with ln, and practical uses for symlinks in system administration.

How to Mount and Unmount Drives in Linux

Learn how to mount and unmount drives, USB drives, and partitions in Linux using the mount command, /etc/fstab for persistent mounts, and how to safely eject external drives.

Understanding the Linux Man Pages: Your Built-in Documentation

Learn how to use Linux man pages to look up any command, understand its options, and navigate the built-in documentation system. Includes man, info, apropos, and whatis.

How to View Running Processes in Linux

Learn how to view and manage running processes in Linux using ps, top, htop, pgrep, and pstree. Understand process states, PIDs, CPU/memory usage, and how to find and kill processes.

What Is BASH? Understanding the Linux Shell

Learn what Bash is, how the Linux shell works, the difference between the terminal and the shell, Bash features every user should know, and how to customize your shell environment.

How to Check Your Linux System Information

Learn how to check Linux system information including OS version, kernel, CPU, RAM, disk space, network, and hardware details using essential terminal commands.

Related Articles

Popular Categories