Posted by Kosal
If you're looking to boost the performance of your Laravel applications, there's a small but powerful change you can make: use INT enums instead of string enums. Let's explore why this matters and how to do it right in Laravel.
Enums (short for enumerations) were introduced in PHP 8.1. They allow you to define a set of named values in a clean, structured way.
In Laravel, enums are often used to represent fixed sets of options, like UserStatus
, OrderType
, or PaymentMethod
.
enum UserStatus: int
{
case Active = 1;
case Inactive = 2;
case Banned = 3;
}
Many developers default to storing enums as strings for readability:
enum UserStatus: string
{
case Active = 'active';
case Inactive = 'inactive';
case Banned = 'banned';
}
While this is human-friendly, it's not ideal for performance.
Using numeric (int) enums can provide substantial performance benefits, especially at scale.
unsignedTinyInteger
only takes 1 byte of storage.VARCHAR(10)
could take up to 11 bytes (plus index overhead).Follow these steps to use backed enums with integers in Laravel:
int
backedenum UserStatus: int
{
case Active = 1;
case Inactive = 2;
case Banned = 3;
}
unsignedTinyInteger()
in the migration$table->unsignedTinyInteger('status');
use App\Enums\UserStatus;
protected $casts = [
'status' => UserStatus::class,
];
Now Laravel will automatically cast between the enum and the database value.
Metric | VARCHAR | TINYINT |
---|---|---|
Storage Size | ~11 bytes | 1 byte |
Index Lookup Speed | Slower | 2x–5x faster |
Performance (1M+ records) | ~baseline | Up to 5x faster |
Using int
enums in Laravel is a simple but effective optimization that improves:
When readability is still important, you can always map the enum to user-friendly labels in your application layer — no need to sacrifice performance for clarity.
💡 Pro Tip: Stick with unsignedTinyInteger for most enums — it's efficient and supports values 0–255, which is more than enough for most use cases.