Why SMF Media Grows Faster Than You Expect

Simple Machines Forum keeps an unusually tight relationship between the database and the filesystem when it comes to media. Every uploaded attachment, every member avatar, and every automatically generated thumbnail is written to disk inside your hosting account, while a matching row is recorded in the smf_attachments table. The forum software then rebuilds the public URL on each page load by joining those two sources. On a busy board this means two problems compound at once: the attachments directory balloons with thousands of files, and the database table grows with it, which drags down queries that render the message list.

The default behaviour also encourages waste. SMF stores the original image at full resolution and, if thumbnails are enabled, writes a second file for the preview. A single 4 MB phone photo posted by a member can produce a 4 MB original plus a thumbnail, and because SMF does not re-encode to a modern format, you are serving large JPEG and PNG files to every visitor. On a Managed Cloud Shared Hosting plan your disk quota and inode count are finite, and the attachments folder is frequently the single largest consumer of both. Hitting the inode limit is often what silently breaks uploads long before you run out of megabytes, because each tiny thumbnail counts as one inode.

There is a second operational wrinkle specific to SMF. By default the software obfuscates filenames (storing something like 1234_abcdef... with no extension) and routes downloads through index.php?action=dlattach. That is good for access control, but it means every image request runs PHP instead of being served as a static file, so LiteSpeed cannot cache it efficiently and a CDN has nothing clean to pull. Understanding these three realities—filesystem bloat, oversized originals, and PHP-mediated delivery—explains every optimization below. None of them require root, a package manager, or server-wide configuration; they are all reachable through the AdminCP, File Manager, .user.ini, and .htaccess.

Tuning Attachment and Thumbnail Settings in AdminCP

Start inside the forum itself, because the cheapest storage is the storage you never write. Log in as an administrator and open Admin → Attachments and Avatars → Attachment Settings. The most impactful control here is Maximum attachment size combined with Maximum width/height of posted images. Set a realistic ceiling—most communities are well served by a 1 MB per-file limit and a maximum image dimension of 1600×1600. When you set the width and height values, SMF resizes images on upload rather than storing the untouched original, which is the single largest saving you can make.

Keep Automatically resize images and Save attachment as thumbnail enabled, but set the thumbnail dimensions sensibly (for example 150×150) so the preview is genuinely small. Below that, confirm the Maximum folder size and, importantly, the Use subdirectories option. Enabling subdirectories splits attachments across multiple folders instead of piling tens of thousands of files into one directory; a single huge directory is slow for File Manager, slow for backups, and slow for the server to stat. SMF supports multiple attachment directories, so once a folder approaches a few thousand files you can add a new one under Attachment Settings and SMF will begin writing there.

The attachment upload size is also bounded by PHP. Because you cannot touch php.ini directly on shared hosting, create or edit a .user.ini file in your document root (typically /home/USER/public_html/) through cPanel File Manager or DirectAdmin File Manager. Keep the SMF limit and the PHP limit aligned:

upload_max_filesize = 2M
post_max_size = 8M
memory_limit = 256M
max_execution_time = 120

LiteSpeed reads .user.ini natively, and changes apply within a few minutes or after you touch a PHP file. Make sure the PHP version selected in cPanel MultiPHP Manager or DirectAdmin PHP Selector has the gd extension enabled, because SMF relies on GD for its resizing and thumbnailing; without it the resize options above silently fall back to storing full-size originals. If you have a choice, enable imagick in the PHP Selector extension list as well, since it produces cleaner downsizing.

Finally, prune what already exists. SMF ships a maintenance routine under Admin → Maintenance → Attachments and Avatars that finds orphaned attachments—files with no matching post—and removes them. Run Find and fix all errors and Remove old or orphaned attachments to reclaim both inodes and database rows in one pass.

Serving WebP and Caching Static Media with .htaccess

SMF does not natively transcode uploads to WebP or AVIF, and you cannot install a server-side conversion module without administrative access. What you can do is serve WebP versions when they exist and let the browser negotiate. Create the WebP copies with a free conversion pass on your own machine or a batch tool, upload them alongside the originals through File Manager, and then let .htaccess hand the right file to each browser. Because SMF obfuscates attachment filenames, this technique works best for predictable static media you manage directly—theme images, logos, custom galleries, and any attachment folder you have configured to keep real filenames.

Add the following to the .htaccess in your forum root. It checks the Accept header and substitutes a .webp file when the browser supports it and the file is present:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_ACCEPT} image/webp
  RewriteCond %{REQUEST_FILENAME} (.+)\.(jpe?g|png)$
  RewriteCond %1.webp -f
  RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1,L]
</IfModule>

<IfModule mod_headers.c>
  Header append Vary Accept env=REDIRECT_accept
</IfModule>

The Vary: Accept header is what keeps proxies and CDNs from serving a WebP file to a client that asked for the JPEG. Pair this with aggressive cache headers so repeat visitors and the CDN edge stop re-fetching unchanged media:

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png  "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/avif "access plus 1 year"
</IfModule>

<FilesMatch "\.(jpe?g|png|webp|avif|gif|ico)$">
  Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>

These directives only affect static files reachable by real path. Images delivered through index.php?action=dlattach still run PHP, so they bypass this logic. If image delivery performance is your priority, create a dedicated attachment directory in AdminCP that stores files with real extensions and point members' galleries there, which lets both the WebP rewrite and the cache headers take effect.

Connecting a CDN and Keeping the Account Lean

A CDN is the practical way to take image bandwidth off your shared account without needing object storage integration that SMF does not support. The cleanest approach on LiteSpeed is a pull-zone CDN: you sign up with a provider, give it your forum's hostname as the origin, and it issues a CDN hostname. SMF has built-in support for this. Open Admin → Configuration → Server Settings → Caching, and set the CDN URL / external media host where available in your SMF version, or use the Forum URL and theme settings to point static theme assets at the CDN hostname. The CDN then pulls your Themes/ images, CSS, and JavaScript on first request and serves cached copies from its edge afterward.

Because your .htaccess already sends long Cache-Control and Vary: Accept headers, the CDN will respect them and cache WebP and original variants separately. Verify this after setup by loading an image through the CDN hostname and checking the response headers in your browser's developer tools for a cache HIT and the correct Content-Type. If you see repeated MISS responses, the origin is probably sending Cache-Control: no-cache, which usually means the request is being handled by PHP rather than served statically—another reason to keep media on real-extension paths.

Keep the account lean on an ongoing basis with a few habits. Schedule the AdminCP attachment maintenance run monthly. Watch the inode and disk gauges in cPanel's Statistics sidebar or DirectAdmin's resource usage panel; attachments are almost always the first warning sign. When a single attachment directory passes a few thousand files, add a new one in AdminCP so SMF spreads writes. If you ever need to diagnose a failed upload or a resize that silently produced a full-size file, check the per-account error_log that LiteSpeed writes into the forum directory—GD memory exhaustion and missing extensions both surface there. Between on-upload resizing, orphan pruning, WebP negotiation, and a pull-zone CDN, you can hold an active SMF board's media footprint flat without ever touching anything above your hosting user.