How osTicket Stores Attachments and Inline Images

osTicket is a ticketing system, not a media gallery, but it still accumulates files at a surprising rate. Every email that lands in a department pulls in signatures, logos, embedded screenshots, PDFs, and the occasional multi-megabyte log archive. Each of those becomes a file record. Unlike a CMS that resizes uploads into thumbnails, osTicket does not generate derivative images or WebP variants. It keeps the original attachment exactly as it was received, then references it from the ticket thread. That design keeps evidence intact for support audits, but it means your disk usage grows in direct proportion to inbound traffic, and nothing is compressed on the way in.

The first thing to understand is where those files actually live. osTicket supports pluggable storage backends, and the default on a fresh install is the database backend, which writes attachment binary data into the ost_file_chunk table inside your MySQL/MariaDB database. On shared hosting this is the backend most likely to cause trouble, because your database size is counted against both your disk quota and, on CloudLinux, against I/O and memory limits during queries. A 2 GB attachment history stored in the database bloats every backup, slows phpMyAdmin exports, and makes the ost_file_chunk table the single largest object in your account. The alternative is the local filesystem backend, which writes files under your account's directory tree and keeps the database lean.

You can confirm which backend is active from the osTicket AdminCP. Log in at /scp, then open Admin Panel → Manage → Plugins. Filesystem and S3-compatible storage are shipped as plugins; if neither is enabled, osTicket falls back to the database. To see the raw table sizes, open phpMyAdmin from cPanel or DirectAdmin, select your osTicket database, and sort the table list by the Size column. If ost_file_chunk dominates, your attachments are inside the database and you are paying for it on every query and every backup.

Choosing and Configuring the Right Storage Backend

On a shared account the filesystem backend is almost always the better choice. It moves binary blobs out of the database and onto disk, where they compress well in backups and never slow down SQL queries. osTicket ships the Filesystem Storage plugin in the include/plugins/storage-fs directory, so no download is required. Enable it from Admin Panel → Manage → Plugins → Add New Plugin, then click the plugin name to open its instance configuration and set a storage path.

Point the path at a directory that sits outside your web root so files cannot be fetched directly over HTTP. On a cPanel account whose site lives in /home/USER/public_html, create a sibling folder such as /home/USER/osticket_attachments using the File Manager, then enter that absolute path in the plugin. osTicket still serves the files through its own authenticated download handler at file.php, so keeping them below the document root does not break access; it only prevents anonymous downloads of other customers' documents. After enabling and setting the plugin as the default, new attachments route to disk. Existing attachments stay in whichever backend received them, which is normal and does not cause errors.

If your plan includes or allows an external S3-compatible object store, osTicket's S3 plugin (storage-s3) can push attachments off your account entirely. This is worth considering when your attachment volume is large enough to threaten your disk quota, since object storage is billed separately and does not count against hosting disk. Configure it the same way through the Plugins screen, supplying the bucket name, region, and access keys issued by your object storage provider. Keep in mind that every download then makes an outbound request, so only choose this route if your ticket volume genuinely justifies it; for most help desks the local filesystem backend is simpler and faster.

Setting Upload Limits Through PHP Selector and .user.ini

osTicket enforces a maximum file size in two layers, and both must agree or uploads fail silently or with a confusing error. The application layer is set in Admin Panel → Settings → Tickets, under Maximum File Size. That value can never exceed what PHP itself permits, so the PHP layer is the real ceiling. On LiteSpeed with CloudLinux you control PHP through the hosting panel rather than editing a global php.ini you do not own.

In cPanel open MultiPHP INI Editor or Select PHP Version → Options; in DirectAdmin use Select PHP Version → Options in the PHP Selector. Raise these three directives together so they are consistent:

upload_max_filesize = 32M
post_max_size = 40M
memory_limit = 256M

post_max_size must be larger than upload_max_filesize because the POST body carries the file plus form fields; if a customer attaches several files at once, the combined body can exceed a single file's limit. If your panel does not expose a directive, create or edit a .user.ini file in public_html via File Manager with the same lines. LiteSpeed honors .user.ini on a short cache cycle, so allow a minute or two before testing. Avoid trying to set these in .htaccess with php_value directives; under LiteSpeed PHP running as LSAPI that approach often produces a 500 error rather than applying the value. If you do hit unexpected errors after changing limits, check public_html/error_log or the per-directory log for the failing request before adjusting further. Our companion piece on diagnosing white screens and HTTP 500 errors walks through reading those logs if a tuning change goes wrong.

After the PHP layer is raised, return to the Tickets settings and set the application maximum to a value at or below upload_max_filesize. Keep it conservative. A 10 MB cap handles screenshots and documents while discouraging staff from using the ticket system as a file transfer service, which is the fastest way to exhaust a quota.

Pruning Orphaned Files and Offloading Static Assets

Storage optimization is as much about deletion as it is about where files land. osTicket keeps attachments tied to tickets, so when you permanently delete or purge old closed tickets, their files are released too. Configure retention under Admin Panel → Settings → System if your version exposes a purge window, or delete aged tickets in batches from the staff panel. osTicket also includes a cron-driven cleanup routine that removes orphaned file records and expired drafts; make sure your cron task is firing. In cPanel's Cron Jobs or DirectAdmin's equivalent, schedule the API cron every five minutes:

*/5 * * * * php -q /home/USER/public_html/api/cron.php

Without that task running, soft-deleted attachments linger and the ost_file table keeps references that never clear, quietly wasting space. After a large purge, you can reclaim database overhead by running an OPTIMIZE on the attachment tables from phpMyAdmin: select the table, then choose Optimize table from the With selected dropdown. This is a per-table maintenance action available to an ordinary database user and does not require any server-wide privilege.

For performance, osTicket's own uploaded avatars, logos, and the static CSS and JavaScript under /scp/css, /css, and /images benefit from aggressive browser caching and optional CDN fronting. You cannot CDN the authenticated file.php download handler safely, because those responses are permission-checked per user, but the public static assets are ideal candidates. Add cache headers in public_html/.htaccess so LiteSpeed and any CDN in front of it hold the files longer:

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/png "access plus 1 month"
  ExpiresByType image/jpeg "access plus 1 month"
  ExpiresByType image/gif "access plus 1 month"
  ExpiresByType text/css "access plus 1 week"
  ExpiresByType application/javascript "access plus 1 week"
</IfModule>

If you use a CDN such as Cloudflare in front of your domain, create a page rule or cache rule that caches everything under /images/ and /css/ while explicitly bypassing /scp/ and /file.php. That keeps the staff control panel and private attachments dynamic and secure while letting the CDN serve the branding and interface assets from edge locations. The net effect is a lighter origin, faster first paint for both customers and agents, and a database that stays small enough to back up and restore without timing out.