How Laravel 13.20 Fixed Same-Second Migrations
42sThis segment explains a common, frustrating issue with migrations and the new fix, offering practical value to developers.
▶ Play Clip"Title accurately describes the fix, but the video is short and focused, delivering exactly what it promises without fluff."
This video explains a critical fix in Laravel 13.20 that addresses a subtle but annoying issue with database migrations generated by LLMs. The problem occurs when multiple migrations are created within the same second, leading to incorrect execution order and potential errors, especially on MySQL. The video details the root cause, the community-driven solution, and how the fix works.
LLMs often generate multiple migration files with identical timestamps (same second), causing them to be executed in alphabetical order, which can break foreign key constraints.
Renaming a migration file to have the same timestamp as another changes the execution order, leading to errors like 'Failed to open table clients' on MySQL.
SQLite does not enforce foreign keys by default, so the error is not visible during development, while MySQL throws an error, making the issue database-dependent.
LLMs often combine multiple commands in a single terminal call, generating migrations in the same second, which leads to the timestamp collision.
A tweet from the author led to a pull request by 'Push Back', later improved by 'Nick', and merged by Taylor Otwell within 22 hours.
After updating to Laravel 13.20, running multiple 'make model' commands in the same second now generates unique timestamps (e.g., 06, 07, 08), solving the issue.
The release includes many other minor changes and improvements from the community and core team, linked in the video description.
Laravel 13.20 includes a robust fix for same-second migration collisions, ensuring correct execution order and preventing foreign key errors. The rapid community collaboration highlights the importance of reporting and addressing such edge cases.
What is the issue with same-second migrations in Laravel?
Multiple migrations created in the same second are executed in alphabetical order, which can break foreign key constraints.
00:03
Why does SQLite not show the error?
SQLite does not enforce foreign keys by default, so the error is not visible during development.
01:19
What is the root cause of same-second migrations?
LLMs often combine multiple commands in a single terminal call, generating migrations in the same second.
02:22
Who submitted the original fix and who improved it?
Push Back submitted the original fix, and Nick improved it with better backwards compatibility and tests.
03:04
What is the fix in Laravel 13.20?
The fix checks the migration directory and increments the timestamp by one second until a free prefix is found.
04:04
Same-Second Migration Issue
Highlights a common but subtle bug that can break applications, especially when using LLM-generated code.
00:03Database-Dependent Behavior
Shows how SQLite's lack of foreign key enforcement can hide errors that appear in production on MySQL.
01:19Rapid Community Collaboration
Demonstrates the power of community-driven development, with a fix merged within 22 hours.
03:04The Fix Logic
Explains the technical solution of incrementing timestamps to avoid collisions, ensuring correct migration order.
04:04[00:03] minor release contained a fix for a very annoying problem to me personally. I tweeted about it recently. So, with migrations, LLMs often make something like this. So, migrations within the same second. It was happening very
[00:20] rarely, but when it does, it actually breaks the things and it was very annoying. So, let me explain why it was happening, what it was breaking, and what is the actual fix in the newest Laravel version. So, this is the same
[00:32] project with fixed migration order. As you can see, no same second migration, but if we take a look at client contacts table, there's a foreign ID to client. And originally, how LLM generated those migrations was in the same second. So,
[00:46] let me reproduce that again. So, let's rename that migration file to be at the same second as clients table, exactly like it was as LLM generated. So, we have something like this, same second timestamp, and see the order then
[01:01] changes because the order is then alphabetical, which means that client contacts migration would be executed first before clients table even exists. with foreign key, and you would think that Opus 4.8 would catch that and fix
[01:19] it. But not necessarily. Let me show you why. It depends on which database you actually using, MySQL or SQLite. On MySQL, it would throw an error. On SQLite, not necessarily. So, let's change that to SQLite and comment all
[01:34] the others and run migrate fresh. So, I have migrate fresh, and as you can see, no error. Although, the order of migrations, as you can see, client contacts happened before clients, but for SQLite with foreign key behavior,
[01:52] it's no big deal. It works. So, if the AI agent works with SQLite, it will not even see the error. But, as soon as I get back to MySQL and relaunch migrate
[02:04] fresh with seed or without, as you can see, the error is clear. Failed to open table clients because, well, it doesn't exist yet. And the underlying reason of this happening is this. So, probably for efficiency, often LLMs try to combine a
[02:22] few commands in one terminal thing like make this and make that and make, for example, filament resource multiple resources in one command or something like that. I've seen that multiple times depending on the model. And then, of
[02:35] course, generating of migration happens well at the same second or a second after that there's another batch of migrations. So, yeah, this may be the result. Of course, again, it happens really randomly, but it does happen.
[02:50] But, luckily for me and for Laravel community, my Twitter account is pretty influential. So, a lot of people that, so push back from the core Laravel team noticed my tweet and submitted a pull request with the fix. But, also
[03:04] after that, another person, Nick, submitted his version of the pull request. After seeing push back version, he submitted kind of the same but a bit more improved pull request. So, that was 22 hours ago yesterday, and then Taylor
[03:20] merged that commit basically almost right away. So, this is how fast things can happen. So, thank you to Push Back, Taylor, and Nick for reacting so quickly. Let's try the fix. So, in the same project, I'll run composer update
[03:35] to update to the latest Laravel version of 13.20, and then I will try to run make model in the same second. So, yeah, as you can see, new version is out. And let's try PHP artisan something like this. So,
[03:49] fictional models task and then task subtask and let's see what happens now. So although it technically happened in the same second, the timestamp is different. So the solution by Push Back in the original pull request in the
[04:04] first one was to check the migration directory and then forward one second at a time until finds a free prefix. So this was the solution, get the path with
[04:16] date prefix and then while not empty then add But Nick argued in the comment that Push Back's solution had some backwards Back's solution had some backwards compatibility issues and Nick's solution
[04:29] was a bit deeper. So new function renamed collision free path instead of path and a bit more logic on top to get the current migration path and then also
[04:41] while but a bit different while a bit more thorough with backwards more thorough with backwards compatibility with tests also covering the cases. So as the final proof let's run three models in a row with same
[04:54] run three models in a row with same prefix and as you can see 060708 although technically it was in the same second. So yep, the solution does work well. Thank you Nick and Push Back and Taylor again. And there were more things
[05:08] released, many more things in the latest 13.20 of Laravel framework. So a lot of small changes in the minor versions, see the list it's pretty impressive from the community and the core team so I will link that in the description below so
[05:23] you may find something interesting for your specific cases. And I will keep channel so subscribe to the channel to not miss any of those videos and see you not miss any of those videos and see you guys in other videos.
⚡ Saved you 0h 05m reading this? Transcribe any YouTube video for free — no signup needed.