← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Excessive File I/O

Performance PHP 5.0+ Intermediate
debt(d5/e3/b5/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list Blackfire, strace, and Xdebug — all specialist profiling/tracing tools. The pattern (config file read every request, file_exists in loops) is not caught by a standard linter and won't surface as a compiler error; it requires profiling under load or explicit syscall tracing with strace to quantify.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix specifies caching file reads in APCu or Redis after the first request — a targeted replacement of repeated disk calls with a cache layer. This touches the specific read sites (e.g. wrapping file_get_contents with an APCu check) rather than a single one-liner (e1), but doesn't require a cross-cutting refactor — it's a small, localised pattern replacement.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). applies_to covers both web and cli contexts in PHP, meaning the pattern can appear across many parts of a codebase (request handlers, CLI scripts, middleware). Once file reads are scattered throughout the codebase without caching, every new feature touching config or shared data risks reintroducing the problem, slowing down multiple work streams, but it doesn't fully define the system's shape.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field states explicitly: 'File I/O is fast enough that it rarely causes performance issues in PHP.' This directly contradicts the reality that file I/O is orders of magnitude slower than memory access. A competent developer familiar with other fast I/O abstractions (e.g. in-memory config patterns in other frameworks) may still assume PHP file reads are cheap, especially for small files. This is a well-documented but widely misapplied gotcha that contradicts intuitions built from working with modern caching-by-default frameworks.

About DEBT scoring →

Also Known As

file I/O bottleneck disk I/O performance file read in loop

TL;DR

Reading the same file multiple times inside a loop or across repeated calls — avoidable with simple in-memory caching.

Explanation

File I/O is orders of magnitude slower than memory access. Reading a file once per request is fine; reading the same file inside a loop that runs 100 times per request multiplies the I/O cost 100×. The standard fix is a static cache: static $cache = []; if (!isset($cache[$key])) { $cache[$key] = file_get_contents($path); } return $cache[$key]; The first read hits disk; subsequent reads return the cached value instantly.

Common Misconception

File I/O is fast enough that it rarely causes performance issues in PHP. Reading files inside loops, stat() calls on every request, and repeated fopen/fclose cycles are common PHP bottlenecks — a single file_get_contents() or APC cache read replacing repeated disk access provides significant gains.

Why It Matters

File I/O is orders of magnitude slower than memory access — reading a config file, log, or template on every request adds latency that compounds under load.

Common Mistakes

  • Reading configuration files on every request instead of loading once at startup.
  • Not caching file_get_contents() results for files that rarely change.
  • Writing to log files synchronously on every request — use async logging or a buffer.
  • Checking file_exists() in loops — each call is a filesystem syscall.

Code Examples

✗ Vulnerable
// Reading the same file on every request inside a loop
foreach ($userIds as $id) {
    $config = file_get_contents('/etc/app/config.json'); // disk hit every iteration
    $cfg    = json_decode($config, true);
    process($id, $cfg);
}
✓ Fixed
// Read once, reuse in memory
$cfg = json_decode(file_get_contents('/etc/app/config.json'), true);
foreach ($userIds as $id) {
    process($id, $cfg);
}

// For cross-request reuse: OPcache can cache PHP arrays returned from files
// config/cache.php → return [...]; and use opcache_invalidate() on change

Added 15 Mar 2026
Edited 22 Mar 2026
Views 58
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 2 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 1 ping S 2 pings M 2 pings T 3 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 7 Perplexity 7 Ahrefs 7 Scrapy 7 Google 5 SEMrush 5 Unknown AI 3 Claude 2 Bing 2 Meta AI 1 Majestic 1
crawler 41 crawler_json 5 pre-tracking 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Cache file reads in APCu or Redis after the first request — reading the same config or CSV file on every request wastes disk I/O; measure with strace to quantify real I/O calls
📦 Applies To
PHP 5.0+ web cli
🔗 Prerequisites
🔍 Detection Hints
config file read on every request; CSV parsed per request; file_exists in hot path; log file appended on every request sync
Auto-detectable: ✓ Yes blackfire strace xdebug
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: Function Tests: Update


✓ schema.org compliant