Why are the migrations named as they are?

Why do migrations have such long names? A name like this:


would do.

where N is a sequential number.

Are there downsides to this approach?

I’m guessing here, but I imagine it’s because if its just n then the migration generator has to parse all the migration files to find the highest n. Using a timestamp (which is wha the number is) means it can create a sequence in order without checking things on the file system.

In addition, since the timestamp is the same length for all migrations the migrations can be sorted easily in lexical order by the migrator. Using just n would not allow this since n might be 1 or more digits. Sure, you could coerce the output to be 2 digits or 3 digits. But timestamps already take care of that too.

It lowers the chance of merge commits if developers on different machines both generate a migration.


For a single developer or a small team of 2-3 people, sequential numbers will do, right?

History has proven, that even this will cause enough of conflicts. Take a look at Ruby on Rails history.


In my opinion for a single developer & before first production deployment sequential numbers are fine.

What’s the drawback of using timestamps? They are safer even for a team of 1, unless you never open parallel feature branches.


I don’t see a drawback & yes I rarely use a parallel feature branch.

What are the benefits of using a sequential number?

  • the sequence is possibly faster readable / understandable by a human

What are the dangers of using a sequential number?

  • sorting in lexical order (kip) - concerning the implementation in the migrator
  • conflicts during parallel development

And why human need to read it/understand it at all? Tooling will take care of everything and you do not need to manually deal with that information at all.


That’s how migrations were generated in Rails until version 2.2.0 (in 2008!). As others have noted, there are some gotchas:

  • merge conflicts. In particular, the schema_migrations table tracks the versions of migrations (the number bits) but not the names so having two migrations named with the same number like 017_do_stuff.exs and 017_do_totally_different_stuff.exs is Very Bad

  • to get reliable sorting, it’s best to pad the numbers with leading zeroes. BUT you have to pick how many digits to use: Rails chose (IIRC) 3, and I’ve worked on projects where that would have overflowed years ago

Here’s the relevant commit; note that the issue number in the commit message likely refers the the long-dead Trac instance that Rails used to coordinate development on…


At my main job, I’ve been working on a project with just me and another dev for about a year, and we’ve been using NNNN_whatever.ext for our migrations, and we’ve had to renumber them when merging code several times. Unless you always work alone, the pattern that Phoenix uses will probably save you a good amount of work over time.


Then I’ll use NNN_something.ex for the migrations.

out of curiosity, what’s your reason to go for sequential numbers instead of the default timestamps? Of course you are free to do that, but I am curious to find if I am missing some compelling reason, as pretty much everybody in this thread advised against it.

1 Like

To answer your original question, the downsides are:

  1. ordering clashes when working with more than person
  2. ordering clashes when working with more than branch
  3. potential sorting issues where your padding is insufficient for your number of migrations
  4. Issues with overflow if you do pad your numbers
  5. Tooling expects timestamp_name as a standard now


  1. shorter file names

Personally I can’t think of a reason why you’d stick with numbers…


Personally I can’t think why you can’t think of that.

Hey, I think Ecto SQL - Ecto.Migration does not espect a timestamp.
Otherwise, if I’m wrong, we should change the documentation: https://hexdocs.pm/ecto_sql/Ecto.Migration.html

mix ecto.gen.migration something adds a migration with the timestamp, and it really reduces merge conflicts on a team. Plus the bonus of knowing when it was added, without looking at git history. But you can do whatever you want, which is why I like ecto :slight_smile:


Perhaps supply some reasons to further the discussion, like @JonRowe did.


Hey @webuhu I didn’t mean Ecto didn’t support numbers, but from the linked docs:

The NUMBER is a unique number that identifies the migration. It is usually the timestamp of when the migration was created.

To me “usually” implies “expects” even if it supports just plain numbers, but other tools I’ve used do expect timestamps rather than number.

Ok, that’s fine.

To all else following this discussion - I think in Ecto.Migrator sorting implementation it’s really just important you make sure the migration version is a number & is unique!

Everything else is your personal choice.
And that’s one of the great things within Elixir. You’ve the choice.
There is not just black & white.

1 Like