One platform, five products
How a small team operates several live products by refusing to let each one reinvent the boring parts of the stack.
A question we get often, usually from other founders or engineers, is some version of: how does a company your size run five live products, plus four more in development, without the whole thing collapsing under its own maintenance burden? The honest answer is that we are not maintaining nine products. We are maintaining one platform, and letting nine thin layers of product-specific logic sit on top of it.
This post is a look at how that actually works, written for a technical audience rather than a general one.
The shared foundation
Internally we call the shared foundation pulse-core. It is not a single library so much as a set of conventions and services that every product is expected to use rather than reimplement: authentication, tenancy, database migrations, transactional email, and incident tooling.
Authentication
Every product authenticates users through the same identity layer, with the same session model, the same password and token handling, and the same audit logging. When we find and fix a security issue in that layer, we fix it once, for every product, instead of patching the same class of bug nine separate times across nine separate codebases written at nine separate points in time.
Tenancy
Most of our products are multi-tenant: UnitVanta manages multiple property portfolios, ResortOp manages multiple properties, BlitzPulse manages multiple trader accounts. Rather than each product inventing its own notion of a tenant, tenant isolation is a first-class concept in pulse-core, enforced at the data layer instead of trusted to application code to get right every single time. That matters, because tenant isolation is exactly the kind of thing you do not want to depend on every engineer remembering to check correctly, in every query, in every product, forever.
Migrations
Every product runs schema migrations through the same tooling, with the same review expectations and the same rollout process. A migration in one product looks like a migration in any other, which means an engineer moving between codebases, something that happens constantly on a team our size, does not have to relearn how schema changes get shipped safely every time they switch context.
Email, via PulsePigeon
Every product sends transactional and product email through PulsePigeon, our own email and ESP platform. This was not originally the plan. PulsePigeon exists because we got tired of fighting deliverability limits and vendor quotas on behalf of BlitzPulse, built our own answer to that problem, and then realized every other product had the exact same need. Now it is infrastructure, not a one-off integration each product handles separately.
Incident tooling
When something breaks, on-call for any product follows the same runbook shape and the same alerting conventions, and increasingly, as PulseSiren matures, the same paging infrastructure. An engineer paged for ResortOp at two in the morning uses the same tools and the same mental model they would use if they were paged for BlitzPulse instead.
Why boring wins
None of the pieces above are novel. Authentication, tenancy, migrations, email, and incident response are some of the least glamorous parts of building software, and that is exactly why we standardized them first. Novelty is expensive to maintain, and a small engineering team supporting nine products cannot afford novelty in the plumbing. We would rather spend our creative effort on the part of each product that is actually differentiated, the trading intelligence in BlitzPulse or the guest experience in ResortOp, and keep everything underneath it as boring and predictable as possible.
Boring also compounds. Every hour we do not spend debugging a product-specific authentication quirk is an hour spent on a feature a customer actually asked for. Every migration that looks like every other migration is one fewer thing a new engineer has to learn before they can ship safely. Consistency is not a constraint on velocity here. It is the reason we have any velocity at all, across this many products, with a team this size.
What this is not
To be clear about what we are not describing: pulse-core is not a public framework, and we are not open-sourcing it. We are also not claiming some novel architecture pattern nobody else has tried; shared platforms behind multiple products are a well-worn idea, particularly at studios and holding companies that operate more than one product line. What we are describing is closer to discipline than invention: picking a small number of boring, well-understood patterns for the unglamorous parts of the stack, and refusing to let each new product reinvent them.
If you are building more than one product with a small team, our honest recommendation is to find your own version of pulse-core early, before the second product's authentication code starts drifting from the first. It is much easier to standardize before you have nine things to reconcile than after.
BlitzPulse is educational decision support only. It does not provide investment, legal, accounting, or tax advice. Nothing here is investment advice.
← Back to Journal Subscribe to the Journal →