CodeIgniter has a reputation for being lightweight, but a fresh install and a production application under real traffic behave very differently. When pages that once rendered in 80 milliseconds start taking two or three seconds, the framework itself is rarely the culprit. The slowdown almost always comes from a combination of PHP recompiling the same files on every request, database queries running without any caching layer, and the built-in output and query caching drivers sitting unused because they were never configured. On a Managed Cloud Shared Hosting account you cannot touch server daemons, but you have full control over the exact settings that matter for CodeIgniter speed: the PHP handler, OPcache, the framework cache drivers, Redis object storage, and LiteSpeed's response cache.
Diagnosing where the time actually goes
Before changing anything, confirm what is slow and why. CodeIgniter ships with a profiler that reports execution time, memory usage, database query counts, and the time each query consumed. In CodeIgniter 4, enable it temporarily by opening app/Config/Filters.php in cPanel File Manager (or DirectAdmin File Manager) and confirming the toolbar filter is active in the globals array, then set the environment to development in your root .env file with CI_ENVIRONMENT = development. Reload a slow page and the debug toolbar appears at the bottom of the browser, breaking down where the milliseconds are spent. In CodeIgniter 3, add $this->output->enable_profiler(TRUE); inside a controller method to get the same query and timing table.
Read the numbers carefully. If a single page fires 40 or 120 database queries, you have an N+1 query pattern that no server tuning will fully rescue; that needs query consolidation or caching. If query counts are reasonable but total execution time is high, the PHP layer is likely recompiling scripts on every hit because OPcache is off or undersized. If the profiler shows fast PHP but the browser still waits, the delay is in network or in uncached full-page rendering that LiteSpeed can absorb. Also review your account's error_log, which appears in the application directory and in the public root under cPanel's File Manager. Repeated deprecation warnings, failed cache writes, or "file not found" entries for view files each add measurable overhead when they fire on every request. Remove that noise first, because a log being written thousands of times an hour is itself a performance tax.
Finally, check which PHP version and handler you are running. In cPanel go to MultiPHP Manager, or in DirectAdmin open Select PHP Version. CodeIgniter 4 wants PHP 8.1 or newer, and running it under an outdated 7.4 handler leaves large performance gains on the table. Confirm the handler is lsphp (LiteSpeed's PHP), because that is what unlocks the LiteSpeed cache integration described later.
OPcache and PHP Selector settings you control
OPcache stores compiled PHP bytecode in memory so the interpreter skips parsing and compiling your framework files on every request. For a framework like CodeIgniter that loads dozens of class files per page, this is the single highest-impact change available to a hosting user. On CloudLinux with the PHP Selector, you enable and tune it without any server access. In cPanel open Select PHP Version, then the Extensions tab, and confirm opcache is checked. Switch to the Options tab to adjust its values. In DirectAdmin the equivalent lives under Select PHP Version → Options.
Set opcache.enable to On, raise opcache.memory_consumption to at least 128 (megabytes) so the cache does not thrash and evict your files, and set opcache.max_accelerated_files to 10000 or higher since CodeIgniter plus your models, controllers, and vendor libraries easily exceed the default file count. Set opcache.revalidate_freq to 60 on a stable production site so PHP only checks for changed files once a minute rather than on every request. If the PHP Selector does not expose a particular directive, you can set it per-site through a .user.ini file placed in your document root:
; .user.ini in public_html or your app's public/ folder
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
opcache.jit=tracing
opcache.jit_buffer_size=64M
Changes to .user.ini take effect after the value in user_ini.cache_ttl expires (300 seconds by default), so wait a few minutes before retesting. While you are in the PHP settings, raise memory_limit to 256M and set a realistic max_execution_time such as 60 for any admin or import-heavy routes. These do not make normal pages faster, but they stop long operations from failing halfway and leaving half-written cache files that force expensive rebuilds.
Framework caching: output, query, and Redis
CodeIgniter has three caching layers you should turn on deliberately. The first is full output caching. In CodeIgniter 4, cache a controller response by calling $this->response->setCache(['max-age' => 300]); or, more usefully for repeated pages, wrap expensive view rendering with the cache service. In CodeIgniter 3, add $this->output->cache(5); inside a controller to store the rendered page for five minutes in app/cache/ (or the legacy application/cache/). Output caching only suits pages that are identical for all visitors, such as public landing pages, product listings, or documentation, never logged-in dashboards.
The second layer is query and data caching through CodeIgniter's cache library. On shared hosting the default file driver works and lives inside your account, but file caching creates thousands of tiny files that slow down under load. If your account offers Redis, use it. Check availability in cPanel by confirming the redis PHP extension is checked in Select PHP Version → Extensions. Many Hostiso plans provision a per-user Redis socket or a host and port; find these in your control panel or provisioning email. Configure CodeIgniter 4 by editing app/Config/Cache.php:
public string $handler = 'redis';
public array $redis = [
'host' => '127.0.0.1',
'password' => null,
'port' => 6379,
'timeout' => 0,
'database' => 0,
];
Then cache the results of heavy queries in your models with the cache service: $data = cache('sidebar_categories'); if (! $data) { $data = $builder->get()->getResult(); cache()->save('sidebar_categories', $data, 600); }. This turns a repeated database round trip into a single in-memory lookup. Redis also serves as a fast session handler; set public string $driver = 'CodeIgniter\Session\Handlers\RedisHandler'; in app/Config/Session.php to remove session file locking, a common and easily missed cause of requests that appear to hang while waiting on the previous request to release a lock.
The third habit is reducing work the framework repeats. Autoload only the libraries and helpers a request needs, disable the profiler and set CI_ENVIRONMENT = production before going live, and make sure database queries use indexed columns. You can verify slow queries by running EXPLAIN on them inside phpMyAdmin and adding indexes there without any command line access.
LiteSpeed cache and .htaccess delivery tuning
LiteSpeed Web Server can store a full copy of a rendered page and serve it directly, skipping PHP and the database entirely on repeat requests. Because CodeIgniter has no official LiteSpeed plugin like WordPress does, you drive the cache with response headers and .htaccess rules. Emit a cache header from a public controller with $this->response->setHeader('X-LiteSpeed-Cache-Control', 'public, max-age=300'); in CodeIgniter 4, and LiteSpeed will cache that response for five minutes. Never send this header on authenticated or personalized pages.
Enable the cache module and set browser and compression rules in the .htaccess file at your document root:
<IfModule LiteSpeed>
CacheLookup on
</IfModule>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/webp "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
These rules compress text responses and let browsers keep static assets locally, cutting repeat-visit load times without touching PHP. Keep your existing CodeIgniter rewrite block that routes requests through index.php intact above these directives, since removing the front-controller rewrite breaks the application entirely. After deploying cache headers, verify them by loading a page twice and checking the response headers in your browser's developer tools network tab; a header such as X-LiteSpeed-Cache: hit confirms LiteSpeed served the cached copy. If you tune many similar frameworks, the approach here mirrors the layered strategy in our MediaWiki performance guide, where OPcache, Redis, and LiteSpeed each handle a distinct stage of the request. Apply the layers in order, retest with the profiler after each change, and you will isolate exactly which fix delivered the gain rather than guessing.