The tech world loves a good return-to-roots story.
We went from the rigid, highly normalized schemas of early SQL… to the Wild West of NoSQL… and now, a little wiser, we’re finding our way back to PostgreSQL.
Not because it’s fashionable, but because reality showed up.
A Pendulum with a Broken Regulator
If you’ve been building systems for a while, you’ve probably lived through this cycle:
- The Monolith Era: Massive tables. Dozens of columns. ERDs so complex they required their own dedicated sprint planning.
- The NoSQL Rebellion: Schemas were optional. Joins were “evil.” Everything went into documents or wide rows. For a moment, life felt fast again.
- The Postgres Reality Check: We realized something uncomfortable — data integrity, constraints, and ACID transactions actually matter.
NoSQL wasn’t a mistake. It solved very real problems. Back then, joins were slow, scaling relational databases was painful, and migrations felt like downtime waiting to happen. Document stores let us move fast and scale horizontally. For a long time, that tradeoff was worth it.
The trouble started when those “flexible” schemas became permanent. What began as freedom slowly turned into ambiguity. Fields drifted. Assumptions leaked into application code. Debugging meant tracing business logic through layers of code instead of trusting the database to enforce reality.
PostgreSQL won its comeback not by rejecting those lessons, but by absorbing them. With JSONB, partial indexes, and sophisticated query planners, it became “SQL, but grown up.”
But even with the best tool in the shed, we’re still falling into old traps.
The Real Enemy: The “God Table”
As teams returned to Postgres, many rebuilt the same old pattern: The God Table.
It’s the table that starts simple, then quietly absorbs every new feature. Columns pile up. Nulls multiply. Eventually, nobody is quite sure which fields are still in use.
- Every migration feels like a high-stakes gamble.
- Every query requires 200 lines of context.
- Every new engineer quickly learns which tables are “too dangerous to touch.”
This isn’t a PostgreSQL problem; it’s a schema design problem.
Introducing: Micro Tables
At Per Diem, we’ve been leaning into a concept I’m deliberately coining here: Micro Tables.
The philosophy is simple: Keep tables tiny, atomic, and aggressively focused.
Instead of designing wide tables that try to describe every facet of an entity, Micro Tables break data into the smallest logical units that still make sense. We don’t do this because the database demands it — we do it because humans do.
Why Micro Tables Work:
- Instant Readability: You should understand a table in seconds. If you have to scroll horizontally to find the one column that matters, the table is doing too much.
- Safer Migrations: Adding a feature shouldn’t require an ALTER TABLE on a massive production table. Micro Tables turn migrations into small, predictable additions.
- Performance via Precision: Smaller rows mean better cache utilization. PostgreSQL is exceptionally good at joining indexed tables. Let the engine do what it was designed to do.
- Natural Decoupling: Much like microservices, Micro Tables allow different parts of your system to “own” their specific data without stepping on each other’s toes.
“Isn’t This Just Normalization?”
It’s a fair question.
Normalization is about mathematical correctness and reducing redundancy. Micro Tables are about developer ergonomics and system evolvability.
Sometimes we split tables even when normalization rules say we don’t have to simply because it makes the system easier to reason about and maintain. This isn’t about academic purity; it’s about building systems that survive contact with real-world requirements.
The Tradeoff: Complexity vs. Clarity
Yes, Micro Tables mean more tables. Yes, they mean more joins.
But this is a tradeoff the industry already accepted with Service-Oriented Architecture (SOA). More components don’t make systems simpler on paper, but they make them significantly simpler to evolve without fear.
From a scaling perspective, this model gives us more leverage. When a specific Micro Table grows, it can be partitioned, sharded, or optimized independently without dragging an entire “God Table” along for the ride.
More tables. Fewer surprises. Schemas that scale with teams, not just data volume.
Are We Overcorrecting?
Maybe. Or maybe it’s time we stopped building database “junk drawers” and started building precision instruments.
I’m curious to hear from the community:
- Have you successfully broken up a “God Table”?
- Is the join overhead worth the mental clarity for your team?
- Is “Micro Tables” a term you’d actually use in your next standup?
Let’s make PostgreSQL boring again in the best possible way.
Written by Doron Segal, co-founder & CTO at Per Diem.
Curious to hear what you think, solid idea, or completely off the mark?