Skip to main content

Command Palette

Search for a command to run...

The Data Model Question Every Community Platform Gets Wrong

Updated
•8 min read•View as Markdown

Notes from a decade of watching community platforms ship the wrong architecture, and why the data-model decision has to come before the feature list.

For over ten years I've been watching platform after platform fail to do the things builders actually want. Not because the teams behind them were bad, but because they kept solving a different problem than the one I kept running into. I filled up notes on it. Every platform I evaluated added another entry to the list.

At some point the notes stopped growing and I decided to build the thing myself. Tenant.so is what came out of that. This piece is about one of the biggest recurring items in those notes, because it's the item that determines almost every architectural choice downstream: whether the platform is community-first or course-first, and why the sequencing matters far more than most teams realize.

Courses and Community Have Inverted Engagement Shapes

If you're building a platform that combines courses and community (which almost every all-in-one creator platform now claims to), the first architectural decision you make is which side of that pair is the substrate and which is the feature. Everything else is downstream of that choice.

The reason it matters is that courses and community have opposite data-flow patterns.

Course platforms are read-heavy and asynchronous. A member logs in, watches a lesson, marks progress, maybe leaves a comment, logs out. Writes are sparse. Consistency requirements are loose. Queries are heavily cache-able. You can serve a course platform to a hundred thousand users on relatively modest infrastructure because most requests are static reads.

Community platforms are the opposite. Write-heavy, real-time, and stateful. Every open connection is a persistent socket. Every message triggers fan-out to subscribers. Every presence change ripples through channels. Notification queues run constantly. The database is doing writes at a rate courses never see, and the consistency model has to answer "did this message actually arrive" questions that courses never ask.

Put another way: courses want fast reads on static content. Community wants low-latency writes on constantly-changing state.

Those two patterns produce completely different architectural choices at every layer. Database engine and schema shape, caching strategy, connection model, notification pipeline, presence tracking, event sourcing, all of it. Optimize for one, and you make the other harder.

What Happens When Community Gets Bolted On Later

The default sequencing, and the one my notebook kept flagging, is: build the course platform, launch, get customers, then add community as a v2 feature.

The problem is that by the time community shows up on the roadmap, the underlying data model has already been optimized for the course-delivery pattern. Adding community means retrofitting write-heavy real-time patterns onto a read-heavy async substrate. Every piece of that retrofit is expensive.

Real-time messaging usually means introducing a separate socket layer, keeping it in sync with the primary datastore, and handling the split-brain edge cases when they disagree. Presence tracking becomes a whole subsystem. The notification pipeline has to fan out fast enough that members actually feel pinged when something happens, which usually means introducing a queue, workers, and a delivery guarantee model none of the existing code was written to reason about.

None of this is impossible. It's just that every one of those subsystems has to be bolted on rather than designed in. The data model wasn't shaped for it. The query patterns weren't planned for it. The caching strategy wasn't planned for it.

That's why community features on most course-first platforms end up feeling like an app-within-an-app. They technically exist, but they don't share primitives with the rest of the platform, and the engagement patterns they can support are limited to what the retrofit can carry. This isn't a criticism of any specific competitor. It's a structural consequence of the sequencing choice.

What Community-First Substrates Typically Require

If you go the other direction and design the platform around community primitives first, then layer course delivery on top, the shape of the problem changes.

A community-first substrate typically has to handle:

  • Persistent connections as a first-class concept. Not a bolt-on real-time service, but part of the runtime. Every logged-in user has a live socket by default, and the rest of the platform assumes that.

  • Presence as shared state. Who is online, in which space, updated in near-real-time and queryable from any subsystem. Once you have that available, you can build features on top of it (matchmaking, "who's here right now" indicators, activity feeds that surface live conversations) that would be prohibitively expensive to retrofit.

  • Notifications as an event stream, not batch jobs. When something happens, it fans out immediately through the same pipeline that carries messages. Members feel the platform respond to their actions instead of waiting for a digest tomorrow.

  • A messaging primitive that supports both public and private conversations. Public channel messages and private DMs use the same underlying delivery system, with different routing and access rules on top. Unified code paths, easier to reason about at scale.

  • Gamification wired into the event stream. Points, streaks, and badges are triggered off the same events that drive notifications and feed updates. Not a separate service polling for activity.

None of that is exotic. It's what real-time community software has to have if it wants to feel like a community and not a message board with UX polish. The interesting part is that once the substrate is built this way, adding courses is a smaller problem than it sounds. Courses are structured content, progress state per user, and delivery mechanics. All of that fits comfortably on a data model that already handles far more write-heavy patterns. Course delivery becomes a read-heavy specialization of the community substrate, not a separate system.

The Tradeoff of Going Community-First

The honest cost of picking community as the substrate is that your LMS starts younger than the incumbents.

Kajabi has been iterating on course features since 2010. Teachable and Podia have roughly a decade each of LMS work behind them. Assignment grading, granular access rules, cert issuing, the long tail of course-creator power features. That's not a body of work anyone catches up on in a year.

The tradeoff is real. Going community-first means accepting that your course delivery is going to be leaner than the incumbents' for a while. In exchange, you get a community layer that actually runs in real-time, DMs that behave the way people expect DMs to behave, matchmaking that surfaces connections at scale, and gamification that ties into the same engagement pipeline as everything else. For creators whose primary bet is community engagement (with courses as one way to package what they sell), that tradeoff makes sense. For creators whose primary bet is the deepest possible LMS with a light community bolted on, it doesn't. Both audiences exist. Both are legitimate. They just need different platforms.

Why the Sequencing Question Comes First

If you're building software that mixes real-time interaction with structured content (community plus courses, community plus commerce, community plus almost anything), the sequencing decision is the one that determines what you can build later. Pick the substrate that matches your write patterns, and the second layer gets easier. Pick the wrong one, and you'll spend the next three years retrofitting.

That's the item from the notes that ended up mattering more than any other. Ten years of watching platforms ship the wrong sequencing choice, and every time the outcome looked the same: a community feature that never quite worked as a community, and members leaving to run parallel tools.

Tenant.so is the one I built after the notes stopped growing. The full breakdown of what shipping community-first actually looks like in practice is here: https://tenant.so/alternative/kajabi

The Takeaway

The data-model decision comes before the feature list. It comes before the pricing model. It comes before the go-to-market. If you're building software that mixes real-time engagement with structured content, decide which one is the substrate first and let the second layer inherit rather than compete with it.

Community-first substrates are harder to start. They require you to solve real-time infrastructure before you have paying customers, which is a much less forgiving on-ramp than shipping an LMS and adding community later. The upside is that everything you add on top gets to inherit the primitives, and the ceiling is much higher.

If you're evaluating platforms, or building your own, that's the question I'd start with.