One database for five products — the architectural decision that defines LaunchWithAgency
One database for five products
There is a question that splits marketing tools into two categories, and almost nobody asks it before signing a contract: where, physically, does this tool's data live — and who else can read it without asking permission?
The industry's default answer gets uncomfortable when you spell it out. Your newsletter subscriber lives in Mailchimp's database. The lead who filled out the landing page lives in Webflow's database. The recipient of the transactional welcome email lives in Postmark's database. The blog post that same lead read before converting lives in Ghost's database. Four people? No — almost always one person, recorded four times, across four databases that have never met each other, under four separate contracts.
LaunchWithAgency begins by refusing that fragmentation at the deepest possible layer: storage. The five products — News, Blogs, Pages, Flows and Emails — are not five apps that "integrate." They are five surfaces over a single SQLite database. This article explains why that choice exists, how it is implemented, and what it changes for the operator.
The problem isn't the number of tools. It's the number of databases.
It's tempting to describe the modern stack's problem as "too many tools." That's not quite it. The problem is more specific and more corrosive: each tool carries its own private database, and the boundary between those databases is where your operation bleeds time.
Think about what happens when you want to answer a simple question — "how many of the subscribers who came in through the Black Friday landing page opened the email the following week?" That question crosses three databases: the landing page's (who came in), the newsletter's (who is a subscriber) and the transactional one's (who opened). None of the three tools can answer it alone, because none of the three holds the complete data. You end up exporting three CSVs, opening Excel, and running VLOOKUP on the email address — a manual JOIN between databases that should have been the same database.
That VLOOKUP is the symptom. The disease is architectural: you are paying five vendors to maintain five partial, desynchronized copies of the same reality.
The inversion: one schema, one file, five products
LaunchWithAgency inverts the order of construction. Instead of "the product first, then a database for it," the foundation is the database — and the products grow as different views over it.
Concretely: there is a file, data/local.db, a SQLite database. Inside it live the tables for all five products. The newsletter's lists and subscribers (newsletter_lists, newsletter_subscribers). The blogs and posts (blogs, blog_posts). The landing pages (landing_pages). The automations and their run histories (flows, flow_runs). The email templates, logs and events (email_templates, email_logs, email_events). And cutting across all of them, the authentication system's users table.
The most important consequence of this decision shows up in the foreign keys between tables of different products. When a blog can declare attachedNewsletterId pointing directly at a row in newsletter_lists, that is not an "integration." It is the relational database doing what relational databases do: guaranteeing, at the storage layer, that the blog and the newsletter are talking about the same entity. There is no synchronization because there is nothing to synchronize — there is one piece of data.
> Integration, in most tools, is a button labeled "connect." Here, integration is the fact that there is no button at all: the products are born in the same table.
What it changes in practice
Architecture theory only matters if it changes your day. It does — in at least four concrete places.
The lead is already the subscriber. When someone fills out a landing page in the Pages product, that person's record doesn't need to be "pushed" to the newsletter by an integration. Pages and News read and write the same database. The captured lead is, in the same instant and with no intermediate step, a row the newsletter can see. The export/import between capture and nurture simply ceases to exist.
Automation sees everything. The Flows product needs no API credentials to "look at" the other products. An automation that fires when someone subscribes to the newsletter doesn't consume a third-party webhook — it reacts to an internal event (newsletter.subscribed) recorded in the flow_events table, in the same database. There is no integration that can break silently, because there is no integration: there is a SQL query.
Context is complete in one place. Because the data isn't scattered, the dashboard can show the full picture of a campaign — landing, capture, nurture, send — without joining sources. The VLOOKUP question from above becomes a query crossing neighboring tables in the same file.
One invoice, one vendor, one backup. Five subscriptions growing in parallel become one. And, perhaps more importantly: your backup is a file. Copying local.db copies the entire operation — subscribers, posts, automations and logs — in a single move.
Being honest about the limits
A serious architectural decision also has to declare where it pinches. SQLite is a single-file database — it shines at concurrent reads and at operational simplicity, which is exactly why it fits this proposition. It is not the choice for a system that needs hundreds of simultaneous writes per second spread across regions. LaunchWithAgency is designed for the marketing operation of an agency or a product team — a workload where the database is never the bottleneck, and where the simplicity of having everything in one file is worth far more than the theoretical scale of a cluster you will never use. Choosing SQLite here is not a cost-cut: it is design.
Why this is the foundation, not a feature
If there were a single sentence to take from this article, it would be this: at LaunchWithAgency, integration is not a feature that can be added or removed — it is the shape of the database.
Every all-in-one suite promises that "everything talks." Most deliver that as a flagship product with satellite modules, each module with its own storage, and a synchronization layer running underneath to keep up the illusion of unity. That layer is where the bugs live, where the data diverges, and where the maintenance bill grows.
LaunchWithAgency doesn't have that layer because it doesn't have that boundary. Five products, one schema, one file. What for other tools is the hardest feature to maintain, here is simply the starting point.
> You don't need twelve tabs. You need a database that doesn't force you to have twelve tabs.