Efficient Triple‑Layer Caching in CodeIgniter 4 Enables 100k+ Requests on Shared

Summary

This postmortem analyzes the architectural strategy behind SHONiR CMS, which successfully handles 100k+ requests on low-end shared hosting environments. The core achievement is not due to vertical scaling or expensive infrastructure, but rather a Triple-Layer Caching Architecture built on top of CodeIgniter 4 (CI4). By adhering to a strict “Don’t Touch the Core” philosophy, the system achieves massive throughput while maintaining extremely low memory footprints (peak usage ~659 KB).

Root Cause

The “problem” this architecture solves is the inherent resource limitation of shared hosting (limited CPU, low RAM, and high I/O wait times). Traditional PHP applications fail under load because each request triggers a full lifecycle:

  • Database I/O overhead: Querying tables for every single page load.
  • PHP Execution overhead: Re-parsing scripts and executing controller logic.
  • Asset Bloat: High bandwidth consumption from unoptimized image assets.

The implementation mitigates these through three specific layers:

  • Layer 1: Native CI4 Web Page Caching: Utilizes $this->cachePage() to bypass controller logic.
  • Layer 2: Static HTML Caching: Writes fully rendered HTML to the filesystem to eliminate DB connections entirely for repeat visitors.
  • Layer 3: Image Optimization Layer: Automates WebP conversion and compression to reduce payload size.

Why This Happens in Real Systems

In production environments, the bottleneck is rarely the programming language itself, but rather the latency of external dependencies.

  • Database Contention: As concurrent users increase, the database becomes a locking bottleneck.
  • Shared Resource Limits: On shared hosts, you are competing for the same CPU cycles and disk I/O as hundreds of other users.
  • Network Throughput: Large, unoptimized images saturate the network interface, increasing TTFB (Time to First Byte) and overall page load time.

Real-World Impact

When implemented correctly, this strategy transforms the performance profile of an application:

  • Memory Efficiency: Peak memory usage is reduced to negligible levels (under 1MB).
  • Scalability: The system can handle spikes in traffic (100k+ requests) that would typically crash a standard CRUD application.
  • Cost Reduction: High-performance delivery is achieved on “cheap” hosting, eliminating the need for expensive VPS or Cloud instances.
  • Developer Transparency: By injecting generation timestamps into the HTML, debugging cache freshness becomes trivial.

Example or Code (if necessary and relevant)

// Example of Layer 1: Native CI4 Page Caching
public function index()
{
    // Cache this specific page for 300 seconds
    $this->cachePage(300);

    $data = $this->model->getStaticContent();
    return view('content_view', $data);
}

// Example of Layer 2 Logic Concept: Static HTML Generation
public function generateStaticHtml($pageId)
{
    $html = $this->renderPage($pageId);
    $timestamp = date('d/m/y H:i:s T');
    $comment = "";

    $finalOutput = $comment . $html;
    file_put_contents(WRITEPATH . 'cache/htmls/page_' . $pageId . '.html', $finalOutput);
}

How Senior Engineers Fix It

Senior engineers focus on Architecture over Implementation. Instead of trying to “optimize” a slow database query with a more complex SQL statement, they look for ways to avoid the query entirely.

  • Respecting the Framework: They don’t hack the core; they extend the framework using its intended patterns (Hooks, Filters, or Libraries). This ensures upgradability.
  • Layered Defense: They assume every layer (DB, Disk, Network) will eventually fail or slow down, so they implement caching at every possible junction.
  • Observability: They include metadata (like the generation timestamp) in the output to ensure the system’s state is observable and verifiable in real-time.

Why Juniors Miss It

Junior developers often fall into the trap of micro-optimization rather than architectural optimization.

  • The “More Power” Fallacy: Juniors often believe that more traffic requires “more powerful hardware” or “better code,” failing to realize that caching is more efficient than coding.
  • Over-Engineering: They may attempt to implement complex Redis or Memcached clusters on a shared host where those tools aren’t even available, rather than using the filesystem effectively.
  • Ignoring the Lifecycle: They focus on the “Happy Path” (the code working once) rather than the “Load Path” (how the code behaves when 1,000 people hit it simultaneously).

Leave a Comment