My 2007 Manifesto: The Bit Bucket Wars, GitOps, and Why AI Needs Constraints
I have been looking for this specific link for years. Before I ever started oraclenerd (by a whole eight days, as it turns out), I sent an email to my CIO on Monday, August 6, 2007.
The Friday before, one of our lead software architects had given a presentation on where our engineering organization was headed. All I heard for an hour was Ruby, Java, and C#. Not a single word about the database. Not a single word about the data. I raised my hand at the end and asked a question along the lines of, "Why isn't there more emphasis placed on the data?" Nobody wanted to get into it because everyone was in a rush to go bowling.
So I went home, stewed on it over the weekend, wrote up what I called a "manifesto," and emailed it directly to the CIO of our Fortune 400 company. Thirty minutes after hitting send, that familiar wave of panic set in: WTF did I just do? Do I still have a job?
Not only did I keep my job (for another nine months, anyway, which is a story for another day), I forwarded the email to a blogger who went by Dratz, who wrote Confessions of an IT Hitman over on IT.toolbox.com. On August 7, 2007, Dratz published it as a guest post: Chet Justice's manifesto, of sorts. A week later, on August 15, 2007, I launched oraclenerd with a shorter version titled My Manifesto.
Thanks to the Wayback Machine, I finally found the original IT.toolbox post. Reading it back nearly twenty years later, two things jumped out at me immediately:
- Not much has changed.
- For better or worse, I believe I've been consistent.
Here is the original post from August 7, 2007, preserved in all its glory.
The Original Post: August 7, 2007
Chet Justice's manifesto, of sorts.
Confessions of an IT Hitman by Dratz (IT.toolbox.com)
August 7, 2007A longtime reader and APEX handy man sent me an email he sent to his CIO. It reminded me of an email I sent to my CEO years ago. Sometimes you just have to point out the facts. He felt a massive opportunity was being missed (another developer-heavy shop) and just want to point out some things he felt were important. I took out his company name and the app names, but he ain't ashamed to stand by it, so I gave him TOP BILLING!
I hope it encourages you to make sure your voice is heard in one forum or another. You're paid to participate.
===============================
Dratz,
I thought you might appreciate this. I recently sent this to my CIO...fortunately I still have a job. He's pretty open to my opinions (which is all I can really ask for).
What spurred this on was a Friday presentation by one of our (main) software architects. All I heard was Ruby, Java and C#. Not a thing about the database.
The one thing I did leave out was APEX unfortunately.
enjoy!
--------------------
In the meeting on Friday I asked a question something along the lines of "Why isn't there more emphasis placed on the data?"
I didn't want to belabor my point because I knew everyone was in a rush to go bowling.
This is something of a manifesto for me:
From my point of view, I see two types of developers. One is of the application variety; they make GUIs and web sites. The other is the database developer, of which I fall in (I've done J2EE stuff in my past though). Application developers want to put all the business logic in the application or middle tier, that seems the most logical place for them. Database people, well, I, believe that you should put as much of the logic in the database as humanly possible. Get it as close to the data as possible. Much of the thinking behind this "architecture" is that you let database people write SQL or PL/SQL and let Application developers worry about the front end. I certainly don't want someone writing SQL or PL/SQL who really doesn't understand how to use it to its fullest potential, just like I wouldn't expect to write the best C# or Java code, because I don't understand how to fully utilize it.
Putting SQL (and PL/SQL) in the database gives you a few advantages:
- Maintenance: The SQL is in one place, the database. You don't have to search, through your entire code base, for everything that INSERTs into a specific table. Maintenance of that code is so much easier and can be written by people that understand it (DBA/Developers).
- Cost: How much do we pay for our Oracle license? I'm sure it's well into seven figures. Let's take advantage of what they (Oracle) have embedded into the database. Most of what I have seen at [company name] so far (I was in the App/Dev group for a few months) treats the database like a bucket; a giant, expensive bucket. Why not use what we are paying for? Oracle has written a lot of functionality that we could use:
- Advanced Queueing, aka Messaging: would be great to utilize for the [app name] workflow application. We wouldn't have to buy a COTS application (or pay consultants to help us).
- Change Data Capture: Would allow us (Data Warehouse) to capture only the records that have changed in [app name 2] thus significantly decreasing network traffic and would mean month end would not take nearly as long as it does now.
- External Tables: great way to upload files, just create a table that maps to it and your done. No more sql loader scripts to maintain, just a simple SELECT statement to retrieve the data.
- Data Integrity: Utilizing a well designed, constraint driven data model, you can create a system that won't get dirty data. Creating an API to enter data in those tables using Oracle packages, you know exactly what data is coming in and any validation checks can be handled by the database (foreign keys) or of the custom variety (i.e. creating strong datatypes; if it's a date it should be a DATE in Oracle, a column that stores dollars, a
NUMBER(30,2)which will only allow 2 digits behind the decimal). Check constraints can also be used, which would tie into Cost because you don't have to write as much code.I've read many arguments for an against. In my opinion, most of those arguing against don't really understand the database or how to use it. I'll admit it was an extremely difficult concept when I first started, but once I got it and realized it's power...
Mostly this is about keeping things simple. My previous employer was a small state funded company. I made an effort to keep things simple so that when I left, they wouldn't have to pay someone six figures to maintain it. I was successful in that endeavor and still receive praise from my former boss. I am very proud of that. Things don't have to be as complicated as we sometimes make them.
Data is the most important thing we have. Applications come and go, but data stays the same. This year's flavor might be gone in a couple of years and we'll need to port an entire application again. If most of that logic is in the database, it will be easy to do. If the logic is tied up in the application/middle tier, it will be a monumental undertaking.
This has been brewing for quite some time. Please don't think I'm gunning for someone's job, I'm not. I just haven't heard anyone really argue from the database side.
The Bit Bucket Wars: A Mandatory Reading List
I found this list of five in a DM to a colleague. Don't let the numbering fool you; #3 has two entries. I've sent it to friends and colleagues multiple times over the years, usually with the explainer: "If you're bored...please just read them in order."
- Application Developers vs Database Developers (February 2008): Where I introduced my friend and colleague "Mr. M" (Michael Cohen), who argued that databases were becoming less important, that writing to disk was too slow, and that database concerns were merely a narrow subset of application concerns.
- Application Developers vs. Database Developers: Part II (December 2008): The famous follow-up where I suggested you could build entire, scalable applications in PL/SQL, and Mr. M replied: "NO!!! NO!!! NOOOOO!!! I want to beat people like you who say this with a ball pean hammer... DUDE! SQL IS A PILE OF SHIT FOR EXPRESSING APPLICATION LOGIC!!!" (Blog that, mofo! So I did.)
- The "Database is a Bucket" Mentality and Everything is a Bit Bucket (March 2010): My post-nap rant about companies treating a seven-figure database engine like a dumb storage bucket just so they can pretend databases are interchangeable, followed immediately by Michael O'Neill's guest post comparing "the database is a bit bucket" to Java's "write once, run anywhere" myth.
- The Case for the Bit Bucket (March 2010): Written by "Mr. M" (Michael Cohen) himself. Instead of letting his comment get buried in a thread, I asked him to write a full guest post on
oraclenerd. He laid out the best version of the application developer's argument: modern OO languages and ORMs made developers more productive, horizontal scaling was easier in the middle tier, and the industry trend was unmistakably moving logic out of the database and into the application layer.
Fast-forward to 2026, and what have I been writing about over the last month? Why The Boolean is Lying to You in OLAP, why The Boolean is Still Lying to You in OLTP, why Every JSON Column Has a Schema, and When the Guardrail Stops Guarding. Different technology, exact same fight: put the truth in the physical data model, and stop treating the database like a dumping ground.
Where I Softened: Closing the Feedback Loop
Looking back at my 2007 and 2010 self, I'm not a jerk about it like I used to be.
Back then, when I wrote things like "most of those arguing against don't really understand the database," I was just lobbing grenades over the wall. I still believe there is a fundamental difference in how database developers approach applications versus application developers. Over the years, I've tried to better understand their perspective. But...what's the phrase? Accepting it is half the battle.
What changed for me was realizing that the divide isn't just stubbornness; it is structural. It comes straight back to a 2012 post by my friend, Cary Millsap: An Organizational Constraint that Diminishes Software Quality.
Cary pointed out that we organize software teams like a Henry Ford assembly line: architects design systems they never see written, developers write systems they never see run, and operators get stuck running systems they had no hand in designing. The fatal flaw in that assembly line is the absence of a feedback loop. When you are insulated from the downstream reality of what you build, you keep making the exact same mistakes for years without ever feeling the pain they cause.
A couple of years ago, I was working in an operator-facing analytics environment where three distinct roles existed in their own lanes: BI Developers, Data Engineers, and Data Architects (partially me). I used to tell them, often: "Y'all should be tied at the hip."
The BI Developer should have built a pipeline. The Data Engineer should have built a dashboard. And the Data Architect should know both. I didn't expect or want them to become experts in each other's jobs; I just wanted them to understand what it takes.
When you force that cross-pollination, the feedback loop closes. The Data Engineer suddenly feels how painful a poorly modeled table is when you actually try to build a report on top of it. The BI Developer sees how much work goes into shaping and testing data upstream. Without that shared context, everyone optimizes for their own narrow step on the assembly line, and the database gets treated like a bit bucket because the people writing the code never have to live with the mess downstream.
How GitOps Made the Pattern Worse
Here is the irony, though: while my tone softened, the underlying problem didn't go away. In fact, the GitOps revolution poured jet fuel on it.
GitOps was revolutionary for application and infrastructure engineering. Everything lives in Git. Everything is declarative. Pull requests trigger automated tests, containers spin up and tear down cleanly, and deployments are repeatable and reversible.
And then we applied those same ideas to data.
That made a ton of sense. Modern data transformation frameworks brought version control, automated testing, CI/CD, documentation, and repeatable deployments to a world that desperately needed all of them. But somewhere along the way, we started acting as though data itself behaved like code.
It doesn't.
Rolling back an executable is relatively easy. Rolling back a database change can be extraordinarily difficult. Code describes what a system should do. Data records what the system has already done.
Change a line of application code, deploy it, discover a bug, and you can deploy the previous version. Change a reference value that gets consumed by a hundred million transactions, and reverting the reference value doesn't revert what happened to those transactions. The state of the data has already changed, possibly in ways that cannot be reconstructed.
I fully acknowledge that difficulty. Database changes are harder precisely because state matters.
And that is where GitOps accelerated tendencies application developers already had: keep state at arm's length, make the database interchangeable, and put behavior in code where it can be versioned, tested, deployed, and rolled back like everything else.
Instead of bringing database design into the modern engineering workflow, we increasingly brought the software engineering workflow to the database:
- ORM-Driven Schema Drift: Schema migrations became auto-generated artifacts of application classes, often reviewed by developers who never look at the resulting physical execution plan or constraint model.
- Microservices Sprawl: To make deployments independent, we shattered monolithic databases into dozens of isolated bit buckets. Referential integrity across domains vanished, replaced by "eventual consistency" that frequently turns into eventual mystery.
- Dump Now, Model Later: In the analytics and data warehousing world, ELT and modern cloud data platforms made storage and compute cheap enough that teams stopped modeling at the source altogether. Just dump raw JSON payloads into the lakehouse, and let five layers of downstream SQL transformations try to reconstruct what a "valid order" or an "active customer" actually is.
GitOps didn't create the bit bucket mentality. It made the bit bucket easier to engineer around.
We got really, really good at shipping code. Unfortunately, we also got really, really good at generating dirty data.
The AI Revolution: GitOps for Data, or the Ultimate Test?
Which brings us to right now. I have a hunch that the AI revolution is going to be for data what the GitOps revolution was for application delivery, and it is going to force a reckoning on a debate I started having with my CIO in 2007.
Why did the "bit bucket" win the first round in 2010? Two reasons:
- Writing good SQL, designing constraint-driven schemas, and building tight database APIs took specialized knowledge that was scarce and slow to write by hand.
- Application developers wanted to work in a single language and move fast.
AI changes the math on both of those overnight.
First, the friction barrier got a hell of a lot lower. You no longer have to make the same trade between developer velocity and leveraging the database engine. An AI coding assistant doesn't get bored writing CHECK constraints, foreign keys, set-based SQL, migration scripts, or the tests around them. The excuse that "it's too tedious to model this properly in the database" gets a lot weaker when an agent can scaffold the constraints, the API, and the test suite in thirty seconds.
Of course, an AI coding assistant can also write a spectacularly wrong query or migration with complete confidence. Which brings us to the second point.
Second, and much more importantly: AI is starving for semantic truth, and a bit bucket has none.
When you treat a database as a dumb bucket (using generic VARCHAR columns for everything, skipping foreign keys because "the app handles relationships," and burying state transitions across fifteen microservice repositories), you strip the data of its meaning. A human developer can barely piece that context together by reading tribal knowledge in Slack. An AI agent pointed at a constraint-free database has no chance.
Think about what a constraint-driven data model actually is:
- Strong data types (
DATE,NUMBER(30,2)) are explicit contracts about what a value represents. - Foreign keys are a machine-readable map of how the business entities relate to one another.
- Check constraints and state tables are executable documentation of the business rules that cannot be violated.
And there is another difference now. Constraints aren't just documentation for the AI. They are the boundary around what the AI is permitted to make true.
I don't particularly care whether an agent understands that an order must belong to a valid customer if the database refuses to let it create one that doesn't. The foreign key doesn't need a prompt. The CHECK constraint doesn't hallucinate. The datatype doesn't decide that today's edge case deserves an exception.
That is the part of the 2007 argument I couldn't have anticipated. Constraints used to protect the database from application developers. Increasingly, they are going to protect it from the code the application developers didn't actually write.
Nineteen Years Later
In that August 2007 email, I wrote:
"Data is the most important thing we have. Applications come and go, but data stays the same. This year's flavor might be gone in a couple of years and we'll need to port an entire application again."
Since I wrote that, I have watched J2EE give way to Ruby on Rails, Rails give way to Node and React, monoliths give way to microservices, and on-prem racks give way to Kubernetes and serverless. Every single one of those application tiers has been rewritten, replatformed, or retired.
The data is still there. And the fundamental truth remains: whether you are running Oracle, Postgres, SQL Server, or whatever comes next, the database is still not a bucket.
I'm a lot nicer about how I say it these days. I try to close the feedback loop and tie teams at the hip instead of just yelling across the wall.
But nineteen years after hitting send on an email I thought might get me fired, the thing underneath all those words (a lesson I learned from Tom Kyte) hasn't changed:
Put the truth as close to the data as you can.
In 2007, I thought that protected us from bad application code.
In 2026, I'm starting to think it might protect us from AI, too.
Architected by Chet, written by Gemini 4 Argon
No comments:
Post a Comment