Study
We replayed the git history of the database schema of nine open-source apps (Mastodon, GitLab, Forem, Cal.com, Lobsters, diaspora*, Documenso, Formbricks and Umami), one state per week, and followed 1,112 tables from the week they were created to the week they were dropped. Tables have a life expectancy, and it is lopsided.
Once a table exists, it tends to stay: 84.1% of tables are still there one year after they were created, 77.5% after three years, 72.8% after five. The founding tables are even tougher: of the 71 tables present in the first recorded state of each schema, 56 still exist today.
The curve drops early, then flattens. That shape is the whole story of this study.
229 tables were dropped over the period. 35.8% of them were gone within a month of being created, 49.3% within three months, 70.7% within a year. The median age at death is 106 days.
These are experiments, features that did not survive review or production, tables replaced during a redesign. A table that makes it through its first year is almost always there for good. Design decisions harden fast: the name, the keys and the columns you give a table in its first months are very likely the ones the project will live with.
A schema does not grow along a smooth line. In each project, the busiest 10% of the weeks with a schema change account for 49.0% to 80.0% of all the tables added. Long quiet stretches, then a migration that adds a whole feature at once. GitLab added 87 tables in a single week; Lobsters, at the other end, went 519 days without touching its schema.
Each project name links to its schema time-lapse on mcdview.
The older Rails apps lived for years with no foreign key in the database: GitLab for 4.7 years, Lobsters for 6.3 years, Mastodon for 1.0 years. The relationships were in the models, and the database only learned about them later, in batches. The projects started in the Prisma era declared foreign keys from day one.
And one project went the other way. Umami dropped its foreign keys on purpose: the
commit of 2022-12-27 is titled "drop foreign keys, add missing indexes",
and the schema has used relationMode = "prisma"
ever since, which leaves referential integrity to the ORM. Its tables are still related;
the database just does not enforce it.
We detected 23 renamed tables across the nine
projects, 14 of them at Formbricks, where the table that holds
organizations has been called, in turn, team → workspace → organisation → team → organization. Naming the core concept of a product is hard, and the schema
keeps the record of every attempt.
Columns churn more quietly: 7.6% of the columns ever added to a table that still exists were later removed from it.
To see these schemas move, open the time-lapses linked in the table above, or the open-source schemas page. The LinuxFr.org story, where 29 foreign keys arrived in a single commit, is told here.
db/schema.rb or
schema.prisma, following renames of the file), reduced to one state per
ISO week (the last commit of the week), dated with the commit date: 1,605 states.
GitLab is covered from 2011 to 2020, the years it kept db/schema.rb.db/structure.sql only exists in early 2013
and again from 2026, which makes lifetimes unmeasurable.