Deploy fails: No space left on device. df -h shows 35% free on /var. Nobody runs df -i: 100% inodes in storage/framework/sessions — 4 million 100-byte files.
Inodes are the invisible ceiling for small files.
Understanding inodes
Each file/symlink/socket uses an inode. Creation fails when inode table full despite free GB.
Always df -i on space incidents.
Diagnosis
Count files per top-level dir. Faster heuristics on web roots.
Classic web causes
File sessions, compiled views, failed jobs, temp extracts. Fix with Redis sessions, TTL cache, cleanup jobs.
Safe cleanup
Maintenance mode, targeted purge, not blind rm on active sessions.
Architecture
Separate cache volume, hash sharding subdirs, monitor inode % like disk %.
Ongoing prevention
Alert inode 85% like disk 85%. Nightly cache prune cron with deleted file metric.
Sessions: migrate Redis before inode incident — urgent retrofit costs more.
Avoid flat millions files: hash subdirs ab/cd/ef123.
Containers: limit json-file log driver max-size.
Shared hosting inode quota ticket: ask number before plan upgrade — sometimes free.
Migrate file sessions → Redis
Plan: temporary session dual-write, flip config, purge file sessions after 24h max TTL.
Measure inode before/after — proof of fix.
Framework cache prefix: version cache key (v2_) for safe mass purge.
Maildir thousands files: migrate to DB or object for attachments — inode fix temporary purge, not durable.
Local CI artifact cache: clean stale branches — each branch = thousands of files.
Diagnostic tools
Interactive ncdu for navigating millions of small files. debugfs expert only.
Exim/qmail mail queue: each message a file — purge queue if inbound spam attack.
Capacity plan: inode count at mkfs if rebuilding FS — mkfs.ext4 -N tuning.
Operational summary
Exhausted inodes signal unsuitable design (file sessions, unlimited cache) more than missing GB space. Systematic df -i on "no space left". Migrate Redis sessions, prune cache, hash directory sharding.
Containers and shared hosting: panel inode quotas — support ticket before saturation.
48h remediation plan
Day 1: confirm df -i, locate top directory, enable maintenance if needed, prune safe cache subset. Day 2: migrate Redis sessions, deploy prune cron, add 85% inode alert. Week: refactor cache strategy, hash subdirs, capacity review with host support.
Internal comms: inode incident ≠ disk full — clear message avoids finance wrong action "buy GB".
Developer education
Explain inodes in onboarding — junior devs reach for rm -rf on wrong tree when disk « full » with free GB.
Framework defaults file sessions locally — change default to Redis in template repo, not per project firefight.
Architecture follow-up
After inode firefight, schedule architecture review: which components create files per request and which can move to Redis, DB, or object storage. Present findings to engineering lead with cost estimate — inode fixes without architecture change recur.
New projects start from template with Redis sessions and cache TTL defaults — prevent repeat.
Package managers and node_modules on production server wrong pattern — build elsewhere, deploy artifact only.
Inode alert runbook linked from disk alert — on-call often checks GB first incorrectly.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Inode prevention
85% alert. Redis session migration. Hash subdirs. Prune cron. Ask inode quota before useless plan upgrade.
Containers and cache
json-file log max-size. Versioned cache prefix v2 for safe purge.
Decide and move forward without blind spots
- Confirm with
df -i— do not confuse with full disk in GB; clear message to finance. - Locate offending directory — session cache, thumbnails, fragmented logs, millions of small files.
- Migrate sessions to Redis — before incident if possible; urgent retrofit costs more.
- Hash subdirectories —
ab/cd/ef123instead of flat millions of files. - Alert inode at 85% — like disk 85%; nightly prune cron with metric.
Ask shared hosting support for inode quota before upgrade — compare via our directory and comparison tool.
Frequently asked questions
Disk space vs inodes?
Disk may show free GB while the filesystem has no inodes left to create a file — common with millions of small cache or session files.
Emergency steps?
Confirm df -i, find top directory, prune safe cache or migrate sessions to Redis. Do not buy extra GB — the problem is not block capacity.
If cache writes one file per request, inode ceiling comes before disk ceiling — do the math.
