Every Linux file and directory has a set of permissions that controls who can read, write, and execute it. The chmod calculator is the tool developers reach for when setting these permissions, and misunderstanding it leads to one of two outcomes: either your files are locked so tight that your own application can't access them, or they're wide open for anyone on the system to modify. Neither is great for a production server at 2 AM.
This guide breaks down Linux file permissions from first principles — no hand-waving about "just run chmod 755 and it'll work." You'll understand exactly what those three digits mean, when to use symbolic vs numeric notation, and why chmod 777 is almost always the wrong answer. If you want to follow along and experiment, open the PinusX Chmod Calculator in another tab — it converts between numeric and symbolic modes in real time so you can see exactly what each permission set does.
How Linux File Permissions Work
Every file in a Linux filesystem has three permission groups: owner, group, and others. The owner is the user who created the file. The group is a set of users who share access. Others is everyone else on the system. Each group gets three permission types:
- Read (r) — view the file contents, or list a directory's contents
- Write (w) — modify the file, or create/delete files within a directory
- Execute (x) — run the file as a program, or enter a directory with
cd
Run ls -la in any directory and you'll see a 10-character string like -rwxr-xr--. The first character indicates the file type (- for regular files, d for directories). The remaining nine characters are three groups of three: owner, group, others. A letter means the permission is granted; a dash means it's denied.
-rwxr-xr-- 1 deploy www-data 4096 Feb 21 10:00 app.js
│├─┤├─┤├─┤
│ │ │ │
│ │ │ └─ Others: read only (r--)
│ │ └──── Group: read + execute (r-x)
│ └──────── Owner: read + write + execute (rwx)
└────────── File type: regular file (-)
Numeric (Octal) Notation: What chmod 755 Actually Means
The numeric mode in chmod uses three digits, one per permission group. Each digit is the sum of its permission values: read = 4, write = 2, execute = 1. Add them up for each group to get the final number.
| Permission | Value | Binary |
|---|---|---|
| Read (r) | 4 | 100 |
| Write (w) | 2 | 010 |
| Execute (x) | 1 | 001 |
So when someone tells you to run chmod 755:
- 7 (owner) = 4 + 2 + 1 = read + write + execute
- 5 (group) = 4 + 0 + 1 = read + execute
- 5 (others) = 4 + 0 + 1 = read + execute
In symbolic form, that's rwxr-xr-x. The owner can do everything; everyone else can read and execute but not modify the file. This is the standard permission set for executable scripts, web server directories, and most binaries on a Linux system.
chmod 755 vs 644: The Two Permission Sets You'll Use Most
In practice, two permission combinations handle 90% of real-world scenarios:
chmod 755 (rwxr-xr-x) — use for directories and executable files. The owner has full control. Group and others can read and traverse (for directories) or execute (for scripts and binaries). This is the correct permission for:
- Web server document roots (
/var/www/html) - Application directories
- Shell scripts and deployment scripts
- Any directory that a web server needs to enter
chmod 644 (rw-r--r--) — use for regular files that don't need to be executed. The owner can read and write. Everyone else can only read. This is the correct permission for:
- HTML, CSS, and JavaScript files served by a web server
- Configuration files (though some need more restrictive permissions)
- Log files that multiple users need to read
- Static assets like images and fonts
If you're deploying a web application and you're not sure what permissions to set, start with directories at 755 and files at 644. You can always tighten them later.
Why chmod 777 Is Almost Always Wrong
chmod 777 means every user on the system can read, write, and execute the file. Developers reach for it when they hit a "Permission denied" error and want it to go away immediately. It works — but it also opens the file to modification by any process running on the system, including compromised web servers, rogue cron jobs, and malicious scripts.
On a shared hosting environment, chmod 777 means other tenants' applications can read your database credentials, overwrite your deployment scripts, or inject code into your application files. On a dedicated server, it means any vulnerability in any running service becomes a direct path to modifying your files.
If you find yourself reaching for 777, stop and diagnose the actual permission problem. Usually the fix is one of:
- Change the file owner to the correct user:
chown www-data:www-data file.txt - Add your user to the correct group:
usermod -aG www-data deploy - Use 775 instead (group writable, not world writable)
- Set the directory's group sticky bit:
chmod g+s /var/www
Symbolic vs Numeric: When to Use Each
Chmod supports two notations for setting permissions. Numeric (octal) sets all permissions at once — chmod 644 file.txt replaces whatever permissions existed before. Symbolic notation lets you add or remove individual permissions without touching the rest:
# Numeric: set exact permissions (replaces everything)
chmod 755 deploy.sh
# Symbolic: add execute for owner only
chmod u+x deploy.sh
# Symbolic: remove write for group and others
chmod go-w config.yml
# Symbolic: add read for everyone
chmod a+r README.md
# Symbolic: set exact permissions (same as numeric 644)
chmod u=rw,go=r data.json
Use numeric when you want to set permissions from scratch — new deployments, provisioning scripts, Dockerfiles. Use symbolic when you need to tweak one specific permission without affecting the others, especially in shared environments where you don't want to accidentally remove permissions you didn't set.
Common Permission Patterns for Web Servers
Web server permissions are where most developers encounter chmod problems. Here's a reference for the most common setups:
| Scenario | Numeric | Symbolic | Why |
|---|---|---|---|
| Static files (HTML, CSS, JS) | 644 | rw-r--r-- | Web server reads; owner edits |
| Directories | 755 | rwxr-xr-x | Web server traverses; owner manages |
| Upload directory | 775 | rwxrwxr-x | App writes; group (www-data) writes |
| Config with secrets | 600 | rw------- | Owner only — no group, no others |
| SSH private keys | 600 | rw------- | SSH refuses keys with lax permissions |
| .env files | 640 | rw-r----- | Owner writes; app group reads |
| Executable scripts | 750 | rwxr-x--- | Owner and group run; others blocked |
| Log files | 664 | rw-rw-r-- | App and monitoring group both write |
Recursive Permissions: Don't chmod -R 755 Everything
A common mistake when fixing permission issues is running chmod -R 755 /var/www. This sets every file and directory to 755, which means every PHP file, every config file, and every uploaded image is now executable. That's a security risk — a web shell uploaded to your images directory becomes immediately executable.
Instead, set directories and files separately:
# Set directories to 755 (traversable)
find /var/www -type d -exec chmod 755 {} \;
# Set files to 644 (not executable)
find /var/www -type f -exec chmod 644 {} \;
# Then make specific scripts executable
chmod 755 /var/www/scripts/deploy.sh
This two-pass approach gives you the correct permissions without accidentally making non-executable files executable.
Special Permission Bits: setuid, setgid, and Sticky
Beyond the standard rwx permissions, Linux has three special bits that you'll occasionally encounter:
- setuid (4xxx) — when set on an executable, it runs with the file owner's permissions, not the executing user's. The
passwdcommand uses this to let regular users change their own passwords (which requires writing to/etc/shadow). Use with extreme caution — a setuid root program with a vulnerability gives attackers root access. - setgid (2xxx) — on an executable, it runs with the file's group permissions. On a directory, new files inherit the directory's group rather than the creating user's primary group. Useful for shared project directories where multiple developers need group-level access to all files.
- Sticky bit (1xxx) — on a directory, it prevents users from deleting files they don't own. The
/tmpdirectory uses this (permissions1777) so every user can create temporary files but can't delete other users' files.
Try It Yourself
Understanding chmod is easier when you can see the conversion between numeric and symbolic modes in real time. The PinusX Chmod Calculator lets you toggle individual permission checkboxes and instantly see the corresponding octal number, symbolic notation, and a plain-English description of what each permission set allows. It runs entirely in your browser — no server involved, no data transmitted.
For debugging permission issues on live servers, pair the chmod calculator with a quick ls -la to see current permissions, then use the PinusX Cron Expression Parser if you're setting up scheduled permission audit scripts. And when you're working with server config files in JSON or YAML format, the PinusX JSON Formatter keeps your configuration readable without sending sensitive server details to third-party tools.