laravel 5.4 specified key was too long, why the number 191
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Unpacking the Mystery: Why Laravel's String Length Default is 191
As senior developers working with relational databases, we often encounter subtle yet frustrating discrepancies between application-level defaults and underlying database engine constraints. The specific issue you've raised—why Schema::defaultStringLength(191) seems to be the magic number, while other values like 192 cause problems, especially when dealing with indexes—is a deep dive into the interaction between PHP string handling, MySQL character sets, and InnoDB index limitations.
This isn't just an arbitrary number; it’s a consequence of how MySQL structures its storage and indexing mechanisms. Let's break down this seemingly cryptic behavior from a practical, developer-centric perspective.
The Conflict: Application vs. Database Limits
The problem stems from two separate layers of constraints: the Laravel migration layer (application) and the InnoDB engine layer (database).
When you use methods like Schema::defaultStringLength(191) in a Laravel migration, you are setting an application-level suggestion for string lengths. However, when these fields are used to create indexes (which is common for unique constraints or foreign keys), they must adhere to the strict rules of the MySQL storage engine.
The key constraint here involves the maximum size of an index key in InnoDB tables. As noted in database documentation, the index key prefix length limit is around 767 bytes for optimized row formats. When dealing with variable-length character sets like utf8mb3, each character consumes 3 bytes. This means that a string of length $N$ will occupy approximately $N \times 3$ bytes in the index structure, plus overhead.
The Role of the Magic Number 191
The number 191 often emerges as a practical ceiling derived from these byte limitations when attempting to create composite keys or indexes on columns defined by default string lengths. If you try to set a length that results in an index key exceeding a certain boundary (like $767$ bytes), the operation fails, regardless of how large your PHP variable is.
The reason 192 often fails while 191 succeeds is due to precise byte arithmetic against the MySQL index limits. Incrementing by just one character can push the resulting index key slightly over the safe boundary, causing the insertion or index creation process to reject the command. This behavior highlights that database constraints are far more rigid than simple application-level defaults suggest.
Best Practice: Explicit Declaration is King
While understanding the 'why' is crucial, the most robust solution in modern Laravel development is to eliminate ambiguity by explicitly defining the required length directly on the column definition. Relying on default string lengths can lead to these subtle, hard-to-debug index errors.
Instead of relying solely on defaultStringLength, always define the precise constraints within your migration file. This ensures that the database schema perfectly reflects your application's data needs, aligning with principles advocated by Laravel's framework philosophy regarding clean Eloquent models and migrations (as discussed on https://laravelcompany.com).
Here is how you should handle string lengths for maximum compatibility:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUserTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
// Explicitly define the string length for better control and compatibility
$table->string('name', 255); // Use a standard, safe limit like 255 or 100
$table->string('email')->unique();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
By explicitly setting string('name', 255), you are communicating the exact requirement to MySQL, bypassing potential conflicts arising from default length settings. This approach ensures that whether you are creating indexes or performing bulk operations, the schema remains valid and predictable.
Conclusion
The mystery of the number 191 is a perfect example of how application logic intersects with deep database engine mechanics. It teaches us that when building robust systems, we must always respect the underlying constraints of the platform we are operating on. By understanding the interaction between string lengths, character sets, and index limits, we move beyond simply fixing errors to designing schemas that are inherently resilient. Always favor explicit definitions in your Laravel migrations to ensure your data integrity remains sound.