Camkode
Camkode

Laravel Performance Tip: Use INT Enums - Here's Why!

Posted by Kosal

Laravel Performance Tip: Use INT Enums - Here's Why!

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.

A Quick Recap: What Are Enums?

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;
}

Why Do Developers Use Strings? 🤔

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.

Why INT Enums Are Better âš¡

Using numeric (int) enums can provide substantial performance benefits, especially at scale.

✅ Faster Queries

  • Numbers are compared faster than strings by the database engine.
  • Indexed integer fields are significantly quicker to search, sort, and filter.

✅ Smaller Storage

  • An unsignedTinyInteger only takes 1 byte of storage.
  • In contrast, a VARCHAR(10) could take up to 11 bytes (plus index overhead).
  • Smaller fields = faster I/O and smaller indexes.

✅ Better Index Performance

  • Queries on numeric indexes are generally 2x to 5x faster than string indexes.
  • For large tables (1M+ rows), this speedup can reach 5x.

How to Store INT Enums in Laravel

Follow these steps to use backed enums with integers in Laravel:

1. Define the Enum as intbacked

enum UserStatus: int
{
    case Active = 1;
    case Inactive = 2;
    case Banned = 3;
}

2. Use unsignedTinyInteger() in the migration

$table->unsignedTinyInteger('status');

3. Cast the attribute in your Eloquent model

use App\Enums\UserStatus;

protected $casts = [
    'status' => UserStatus::class,
];

Now Laravel will automatically cast between the enum and the database value.

Real-World Impact

Metric VARCHAR TINYINT
Storage Size ~11 bytes 1 byte
Index Lookup Speed Slower 2x–5x faster
Performance (1M+ records) ~baseline Up to 5x faster

Conclusion

Using int enums in Laravel is a simple but effective optimization that improves:

  • Database query performance
  • Index efficiency
  • Storage footprint

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.