When building media-heavy websites or resource libraries, providing users with clear information about the files they are about to download is a hallmark of good user experience. Whether it is a PDF whitepaper or a high-resolution image, knowing the file size helps users manage their data usage and expectations. In Craft CMS, the asset.size property returns the file size in raw bytes, which isn't very helpful for the average visitor.
In this guide, you will learn multiple ways to transform those raw bytes into human-readable formats like KB, MB, and GB. We will explore the built-in filters available in modern Craft versions, how to perform manual calculations for custom needs, and how to handle the technical nuances of decimal versus binary byte calculations.
Using the Built-in filesize Filter
The most efficient and recommended way to handle file size formatting in Craft CMS (versions 3.x, 4.x, and 5.x) is by using the filesize filter. This filter is specifically designed to take a byte count and convert it into the most appropriate unit automatically.
Instead of writing complex logic to determine if a file should be labeled as KB or MB, the filesize filter does the heavy lifting for you. It evaluates the size and appends the correct suffix based on the magnitude of the number.
{# Outputting a human-readable file size #}
{% set asset = entry.myAssetField.one() %}
{% if asset %}
<p>Download size: {{ asset.size|filesize }}</p>
{% endif %}
This will result in outputs like "1.2 MB" or "450 KB" depending on the file. It is a clean, readable solution that follows the DRY (Don't Repeat Yourself) principle of modern web development.
Manual Calculations for Custom Formatting
While the filesize filter is excellent for general use, there are scenarios where you might need more granular control. For example, you might want to display all file sizes strictly in Megabytes, even if the file is small, or you might want to force a specific number of decimal places.
In these cases, you can use standard Twig math and the round filter. Since 1 Kilobyte is typically calculated as 1,024 bytes in a binary system, you can perform the following operations:
{% set bytes = asset.size %}
{% set kiloBytes = (bytes / 1024)|round(2) %}
{% set megaBytes = (kiloBytes / 1024)|round(2) %}
<p>Size in Bytes: {{ bytes }}</p>
<p>Size in KB: {{ kiloBytes }} KB</p>
<p>Size in MB: {{ megaBytes }} MB</p>
If you want to get even more specific with the visual presentation—such as using a comma as a decimal separator—you can chain the number_format filter:
{# Force 2 decimal places, use a comma for decimals and a period for thousands #}
{{ megaBytes|number_format(2, ',', '.') }} MB
The Science of Bytes: Base 1000 vs. Base 1024
A common point of confusion for developers is the difference between the decimal (SI) system and the binary system for measuring data. In the decimal system, 1 Kilobyte is 1,000 bytes. In the binary system (often used by operating systems like Windows), 1 Kibibyte (KiB) is 1,024 bytes.
By default, Craft CMS uses a base of 1000 for its internal calculations. This means that if you use the filesize filter, a 1,000-byte file will show as "1 KB." If your project requirements demand the binary 1,024 base, you may notice slight discrepancies between what Craft reports and what a user sees on their local machine.
Internally, Craft CMS utilizes the yii\i18n\Formatter class to handle these conversions. Specifically, it calls the asShortSize() method. Understanding this link is helpful if you ever need to dive deeper into the framework's formatting logic.
Global Configuration for File Sizes
If you find that the default base-1000 calculation doesn't align with your project's standards, you can override this globally in your Craft installation. This is done within your config/app.php file. By adjusting the formatter component, you ensure that every instance of the filesize filter across your entire site uses your preferred base.
To change the base to 1024, add the following configuration:
return [
'components' => [
'formatter' => [
'sizeFormatBase' => 1024,
],
],
];
Applying this change will make your template outputs consistent with binary-based file explorers, which is often preferred by technical audiences or for specific types of asset management systems.
Frequently Asked Questions
How do I format sizes for multiple assets in a loop?
When working with an Assets field that allows multiple uploads, you should apply the filter within your loop. This ensures each individual file size is calculated correctly.
{% set documents = entry.myDocuments.all() %}
<ul>
{% for doc in documents %}
<li>{{ doc.title }} ({{ doc.size|filesize }})</li>
{% endfor %}
</ul>
Can I translate the "MB" and "KB" strings?
Yes. Because the filesize filter uses Craft's internal translation and formatting system, the units will automatically adapt to the current site locale. If your site is set to German, for example, the units will follow local conventions without any extra code on your part.
Is the filesize filter available in older versions of Craft?
The filesize filter was introduced in Craft 3. If you are still running a legacy Craft 2 site, you will need to use the manual math approach described earlier in this article, as the built-in filter is not available in that version.
Wrapping Up
Formatting asset sizes in Craft CMS is a straightforward process once you know the tools at your disposal. For most use cases, the |filesize filter provides the perfect balance of simplicity and intelligence. However, for those specialized projects requiring binary precision or custom math, Twig's flexibility and Craft's configuration files allow you to tailor the output to your exact needs.
By implementing these techniques, you improve the accessibility and professionalism of your site, ensuring that users have all the information they need before clicking that download button.