chmod 644 vs 755: Which One Should You Use?
644 for files, 755 for directories — but why, and what about the modes in between? A field guide to choosing Unix permissions, plus the recursive chmod trap that makes every file executable.
You’re copying a project onto a server, or a script won’t run, and the fix everyone reaches for is a mode: 644 here, 755 there. They are often applied by reflex, without a clear rule for which goes where. This is that rule. If you want the digits themselves decoded first, what chmod 755 means walks through the 4-2-1 system; here we take that as read and answer the practical question: given a file or a directory, which mode should it get?
The one-line rule
For the overwhelming majority of cases:
- Regular files →
644(rw-r--r--): the owner can read and write, everyone else can only read. - Directories and executables →
755(rwxr-xr-x): the owner has full control, everyone else can read and run/enter, but not change.
The single bit that separates them is execute. A data file — a .txt, a .json, an image, a stylesheet — has no reason to be executable, so 644 leaves the execute bit off. A directory or a program is useless without execute, so 755 turns it on. Get that one distinction and you’ve got 90% of the decisions right.
The reason execute is non-negotiable for directories trips people up, because it means something entirely different there than on a file. On a directory, execute is search (traverse) permission — the right to enter it (cd) and reach the files inside. A directory at 644 has no x: someone with r can still see the entry names, but they can’t enter it, reach an entry by name, or traverse below it. That makes 644 an unusable default for a directory, and it’s why chmod-ing a whole tree to 644 breaks it. (For the full file-vs-directory story, see the pillar.)
The recursive trap: chmod -R 755 and chmod -R 644
This is where the 644/755 decision most often goes wrong. You have a project directory with a mix of files and subdirectories, and you want to “fix the permissions,” so you run:
chmod -R 755 myproject/ # makes every file executable, too
chmod -R 644 myproject/ # strips traverse from every directory — now unusable
Neither does what you want. chmod -R 755 flips the execute bit on for every file, turning your READMEs and config files into “executables” — usually harmless, but sloppy, and a red flag in a security review. chmod -R 644 is worse: it removes the execute bit from every directory, so you can no longer enter any of them. The whole tree locks up.
A single absolute recursive mode cannot express both. If you have audited a tree and want to set the basic rwx bits to 644 on included regular files and 755 on directories, split by type:
# Split by type with find:
find myproject -type f -exec chmod 644 {} +
find myproject -type d -exec chmod 755 {} +
# A different, relative operation: add read and conditional execute
# but leave existing write bits unchanged:
chmod -R a+rX myproject/
These are not interchangeable repair commands. The
findpair resets the basic rwx bits by type;a+rXis relative and leaves existing write bits unchanged, so it can leave a directory at777. Audit special bits separately, and run either only after excluding.envfiles, private keys, and deployment credentials.
That capital X is the one to remember. Lowercase x sets execute unconditionally; uppercase X sets it only on directories, or on files that already have an execute bit for someone. So chmod -R a+rX myproject/ grants read to everything and execute to directories (and existing programs), while leaving data files non-executable. It does not reset the basic rwx bits to a 644/755 split: it only adds bits and preserves existing write permissions. Use it when that preservation is your intent; use the type-split form when you need to reset basic rwx bits by type. The chmod calculator shows the symbolic-to-octal mapping if you want to confirm what a given operation resolves to.
A recipe table
Beyond the two defaults, a handful of modes cover almost everything. Reach past 644/755 when you need to restrict access, not widen it:
Files
| Mode | Symbolic | Use it for |
|---|---|---|
644 | rw-r--r-- | The default: source, docs, config, assets |
600 | rw------- | Secrets — SSH private keys, .env, credentials |
640 | rw-r----- | Owner writes, group reads, others get nothing |
664 | rw-rw-r-- | A file a whole group needs to edit (see umask below) |
755 | rwxr-xr-x | Scripts and binaries anyone may run |
700 | rwx------ | A private script — only the owner runs it |
Directories
| Mode | Symbolic | Use it for |
|---|---|---|
755 | rwxr-xr-x | The default: anyone may enter and list |
700 | rwx------ | A private directory — ~/.ssh should be this |
750 | rwxr-x--- | Owner and group in, everyone else out |
775 | rwxrwxr-x | A shared directory the group can write to |
The through-line: start from a common baseline, then adjust deliberately. 600 and 700 are the “just me” versions; 640/750 bring in the group but not the world; 664/775 intentionally add group-write for shared work. You rarely need anything more exotic, and you almost never need 777 — if you’re reaching for it, the real problem is usually ownership, not permission.
Where the defaults come from: umask
You may have noticed you don’t usually set 644 and 755 by hand — new files just arrive that way. That’s umask at work. For ordinary creation calls without a default ACL, programs commonly request 666 for files and 777 for directories, and umask masks bits off. A common default is 022, which clears the write bit for group and other:
- New file:
666minus022→644 - New directory:
777minus022→755
Strictly speaking umask is a bit mask, not arithmetic: the kernel computes 666 & ~022. For the everyday values that reads the same as subtraction, but not for one like 023 — there 666 & ~023 is still 644, while subtracting would suggest 643.
That also answers a common question: why aren’t new files executable? Because the base for files is 666, which has no execute bit to begin with — umask can only remove bits, never add them. Execute is something you opt into with chmod +x, deliberately.
Change umask and you change the defaults everywhere. On a shared dev box, teams often set umask 002, which keeps group-write:
- New file:
666minus002→664 - New directory:
777minus002→775
That’s the 664/775 pair from the recipe table — the “my group collaborates on these” defaults. You can preview any of this in the calculator’s umask mode: give it a umask and it shows the resulting file and directory modes. Note that umask only governs new files; it never rewrites what’s already on disk, which is exactly when you fall back to chmod.
For a shared directory, 775 alone has a gap: files created inside it belong to whoever made them, in their primary group, so a teammate may not be able to edit them. The fix is the setgid bit (2775), which makes new entries inherit the directory’s group. Note that setgid fixes the group, not the write bit: for the group to actually keep write access on new files, the people creating them also need a group-friendly umask (like 002), or the directory needs a default ACL. Decoding that fourth digit is covered in the pillar; what it does at runtime, and how to tell when a special bit is causing trouble, is a topic of its own.
A quick decision guide
When you’re staring at something and reaching for chmod:
- Is it a file or a directory? File → start at
644. Directory → start at755. This alone is usually the answer. - Does it need to run? A script or binary needs execute:
755(or700to keep it private). A data file does not — leave it at644. - Who else needs in? Nobody →
600/700. Your group →640/750, or664/775if they must write. The whole world already gets read at644/755. - Recursively? Never apply one absolute numeric mode (
-R 755,-R 644) across mixed files and directories. Split withfind -type f/-type d, or usechmod -R a+rX— and only on a tree meant to be world-readable. - Tempted by
777? Stop. It’s almost never the fix — check ownership withls -landchowninstead.
Get the file-versus-directory call right and the rest follows. When you want to see a mode and its rwxr-xr-x string side by side, or check what a umask produces, the chmod calculator does both. And if you’ve set the right mode and a file still won’t open or run, the mode isn’t the problem — that’s a separate hunt through ownership, parent directories, and the layers underneath, which permission denied even after chmod walks through layer by layer.