Zulip: The Open-Source Team Chat With No Open-Core Catch — and a 10-User Push Notification Limit

Zulip: The Open-Source Team Chat With No Open-Core Catch — and a 10-User Push Notification Limit

Zulip: The Open-Source Team Chat With No Open-Core Catch — and a 10-User Push Notification Limit

Every chat tool promises to make communication effortless. Zulip is the only one that starts from the premise that most of it should not be real-time at all.
A team collaborating with threaded conversations on multiple screens Open-source Slack alternatives have a predictable shape. The repository is open, the community edition works, and then you discover that SAML costs money, LDAP sync costs money, guest accounts cost money, and message retention policy costs money. The licence says open source. The feature matrix says something else. Zulip is the exception, and it is worth being precise about why. It is Apache-2.0, roughly 26,000 GitHub stars, developed by Kandra Labs with well over a thousand contributors and nearly five thousand commits in the last twelve months. And the claim it makes on its own hosting page is unusually strong: unlike the competition, you don't pay for SAML authentication, LDAP sync, or advanced roles and permissions. There is no "open core" catch. That claim is, as far as I can verify from the repository and the documentation, true. There is no enterprise directory in the source tree holding back the good parts. There is no feature diff where the community edition is missing authentication. There is, however, a limit that will matter enormously depending on your situation, and it is not one you will find in the licence file. Self-hosted Zulip's mobile push notifications are limited to ten users on the free tier, because push notifications are routed through Zulip's own infrastructure and that costs them money. Above ten users you need a paid plan, or you build and distribute your own mobile apps. This is a deep-dive on the threading model that makes Zulip different, what the "no open core" claim actually covers, the four-service stack you will be operating, the real costs, and — at length — the push notification situation, because it is the single most likely thing to change your mind.

1. What Zulip Is

Zulip is a team chat application built around a structured conversation model. It competes with Slack, Microsoft Teams, Mattermost, and Rocket.Chat. It is written in Python on Django, with a JavaScript frontend, React Native mobile apps, and an Electron desktop client. The defining architectural choice is topic-based threading. Not optional threading bolted onto a channel — threading as the fundamental unit of conversation. Every message belongs to a stream (roughly a channel) and a topic (a subject line within that stream). You do not post into a stream; you post into a topic inside a stream. That sounds like a small difference. It is the whole product, and section 3 is about why. Beyond chat you get: full-text search across all messages, markdown formatting, emoji reactions, code blocks with syntax highlighting, file uploads, a bot API, webhooks, over a hundred native integrations, granular permissions and moderation, and export tooling.

2. Streams and Topics

A stream is a broad subject: #engineering, #support, #random. A topic is a specific conversation inside it: "deploy is failing on staging", "Q3 pricing page copy", "new laptop for Dana". When you open #engineering in Zulip, you do not see an undifferentiated wall of messages in arrival order. You see a list of topics, each with a participant count and an unread indicator. You read the topics you care about. You mark the rest read without opening them. When you post, you pick a topic or create one. Renaming a topic moves the conversation. Splitting a topic moves part of it. The inbox view aggregates the topics you are subscribed to across every stream, sorted by recency, and gives you a per-topic unread count rather than a per-channel one. The practical consequence is that you can be away for a day and catch up in ten minutes, because you are catching up on twenty specific conversations rather than scrolling four hundred interleaved messages trying to reconstruct which three threads mattered.

3. Why Threading Is the Actual Product

Real-time chat has a structural problem that everyone who has worked in a busy Slack workspace knows: the channel is a single shared timeline, and any two simultaneous conversations interleave into noise. The social consequence is worse than the mechanical one. Because everything is interleaved, real-time presence becomes mandatory. If you are not watching the channel as it happens, the context is gone — buried under forty messages about something else. So people watch the channel. And then they cannot do deep work, because they are watching a channel. Zulip's model breaks that. Because conversations are separated by topic, asynchrony is safe. You can be offline for six hours and return to twenty clean, separate conversations, each complete in itself. Nothing was lost. Nobody needed you to be present. This is why Zulip's own positioning is "the best of email and chat." Email's strength was that a thread is a self-contained unit you can read and answer on your own schedule. Chat's strength is immediacy when you want it. Zulip keeps both. The organisations that get the most out of it are the ones that were already suffering: distributed teams across many time zones, open-source projects with contributors on five continents, and engineering organisations that had quietly concluded that Slack was eating their mornings. The trade is real, and it should be stated plainly: the model has a learning curve. People arriving from Slack will post without topics, create topics like "question," and generally treat it like a channel until someone shows them otherwise. Teams that adopt Zulip successfully usually have someone who models good topic hygiene in the first two weeks. Teams that do not, end up with a stream full of "misc" topics and conclude that Zulip is just Slack with extra steps.

4. The "No Open Core" Claim

Let us test the claim, because it is the reason to consider Zulip over its competitors. Included in the self-hosted open-source edition, at no cost:
  • SAML authentication
  • LDAP and Active Directory user sync
  • SCIM user and group provisioning
  • Guest accounts with configurable access
  • Advanced roles and permissions, including granular moderation
  • Custom groups for flexible permission schemes
  • Data retention policies
  • Full and compliance data exports
  • Unlimited message history and search
  • All integrations and the full REST API
  • Custom emoji, custom profile fields, custom linkifiers
That list is the one that most competitors charge for. Mattermost gates a meaningful portion of its enterprise features. Rocket.Chat gates several. Slack gates almost everything useful behind paid plans. What is actually commercial:
  • Zulip Cloud hosting tiers (the SaaS product)
  • Commercial support contracts with SLAs for self-hosted deployments
  • Some advanced deployment and consulting options
  • Priority support
Notice the shape of that second list. It is support and hosting, not features. You are not buying the ability to use SAML. You are buying someone to answer the phone when it breaks. That is a materially more honest commercial model than the open-core pattern, and it deserves credit. If your objection to open-core products is philosophical rather than budgetary, Zulip is one of the few team chat projects that passes.

5. The Commercial Line, Precisely Stated

There is one place where self-hosted Zulip is not functionally unlimited, and it is the push notification limit. Zulip's self-hosted plans break down roughly as:
  • Free — complete team chat, all features, mobile push notifications for up to 10 users (or unlimited mobile notifications for eligible communities, which includes most open-source projects and some non-profits and educational institutions).
  • Basic — all features, unlimited mobile notifications, supports the project's development.
  • Business (25 user minimum) — unlimited notifications plus support for SSO configuration, guests, compliance exports, retention policies, and more.
  • Enterprise — adds OIDC SSO, AD/LDAP and SAML group sync, SCIM, implementation consulting, custom feature development, advanced deployment options.
Read that carefully and you will notice something slightly odd: the features are present in the free edition, and the paid tiers primarily add support and unlimited mobile notifications. This is consistent with the no-open-core claim — you are buying service levels, not unlocks. But it also means the free self-hosted tier has a genuine functional ceiling at ten users, which we will deal with properly in section 14.

6. Architecture: Four Services

The server is Python on Django, backed by PostgreSQL, with Redis, RabbitMQ, and Memcached alongside it. That is four stateful or semi-stateful services to run and monitor. This is the main operational difference between Zulip and, say, a single-binary Go application. AdGuard Home is one file you copy. Zulip is a small distributed system. What each piece does:
  • PostgreSQL — the durable store: messages, users, streams, everything that matters.
  • Redis — rate limiting, some caching, and transient state.
  • RabbitMQ — the event queue powering real-time delivery to connected clients.
  • Memcached — caching hot objects.
The upside of this architecture is that it scales. Zulip is designed to handle organisations with tens of thousands of users on modest hardware, and the queueing architecture is why — message fan-out goes through RabbitMQ rather than being handled in the web tier. The downside is that you now have four things that can fail, four things to monitor, four things to back up correctly (well, one to back up carefully and three to be willing to lose), and four sets of version compatibility to think about during upgrades.

7. Installation

Ubuntu or Debian with the official installer is the supported path: ``bash wget https://github.com/zulip/zulip/releases/latest/download/zulip-server-latest.tar.gz ./zulip-server-/scripts/setup/install --certbot \ [email protected] --hostname=zulip.example.com ` That script installs and configures the whole stack — Postgres, Redis, RabbitMQ, Memcached, Nginx, and the Zulip application — and optionally obtains a TLS certificate via Certbot. It is genuinely good. It is also the single reason the official recommendation is Ubuntu or Debian: the installer assumes that environment. Docker is also available, and the project ships a Docker Compose path. It works, and it is more portable, but be aware that the installer-based route is the one that receives the most testing and the best documentation. If you are running something other than Ubuntu or Debian, Docker is your realistic option. Prebuilt images exist for DigitalOcean and Render. The other notable operational feature: upgrades are a first-class, documented, scripted process. Zulip treats "you installed this two years ago and now need to be on the current version" as a supported path rather as an exercise for the reader, with upgrade scripts and release notes covering each step. Combined with roughly two releases in ninety days and continuous commit activity, the maintenance picture is about as good as it gets for a system of this complexity.

8. Hardware and Sizing

For a small team, the requirements are modest:
  • 2 GB RAM minimum, 4 GB recommended for anything beyond a handful of users.
  • 2 CPUs is comfortable for a small org.
  • Disk scales with message history and file uploads — tens of GB is typical for a small team with attachments, and you should plan for growth.
The documentation is explicit that Zulip is engineered to stay responsive at large scale on modest hardware, and the architecture supports that claim: the RabbitMQ-based fan-out is what keeps a 10,000-user organisation from melting a web server. The realistic small-team cost is a $10–20/month VPS with 4 GB of RAM, plus backups. That is the entire infrastructure bill for a hundred-person organisation's chat system, which is worth sitting with for a moment.

9. First-Run Configuration

After install you create an organisation and an owner account, then walk through: 1. Organisation settings — name, description, default language, whether the org is open or invite-only. 2. Authentication — password, Google, GitHub, GitLab, SAML, LDAP, or OIDC. This is the section where the no-open-core claim becomes visible: SAML and LDAP are right there, for free. 3. Streams — create the initial set and decide whether anyone can create public streams. 4. Permissions — who can invite, who can create streams, who can add custom emoji, whether message editing and deletion are allowed and for how long. 5. Integrations — webhook URLs for GitHub, GitLab, Jira, Sentry, Jenkins, and the rest. 6. Mobile push — which brings us back to the limit. The settings surface is deep. Zulip has an unusual amount of configuration for a chat tool, and it is mostly well-organised. Budget an hour for the initial pass rather than fifteen minutes.

10. Search, and the Cloud History Cap

Full-text search across messages and topics is a genuine strength — Zulip's search is fast and the syntax supports narrowing by stream, topic, sender, and time. One distinction matters:
  • Self-hosted: unlimited searchable history. Everything you have ever sent is searchable.
  • Zulip Cloud free tier: search history capped at 10,000 messages, with file storage capped at 5 GB total.
That cap is on the
hosted free tier, not on self-hosting, and it is the main reason a growing team using Zulip Cloud eventually either pays or moves in-house. It is also another argument for self-hosting: the thing being rationed on the free SaaS tier is the complete record of your organisation's communication, and there is no reason to accept a cap on that when you can host it yourself.

11. Integrations and Bots

Zulip ships over a hundred native integrations, and hundreds more via third-party extensions. GitHub, GitLab, Jira, Jenkins, Sentry, Nagios, Zendesk, and the usual suspects all have first-class support, typically via incoming webhooks that post into a stream and topic. The bot API is well documented and genuinely pleasant. Bots are first-class users with their own API keys, and the Python bindings are maintained as part of the project. If you have ever written a Slack bot and fought the token model, Zulip's is simpler. The REST API covers the full surface: send messages, manage streams and topics, administer users, read message history. For automation — provisioning users from your directory, posting deployment notifications into a topic, archiving conversations somewhere — the API is complete enough that you rarely hit a wall. One genuinely nice touch: because topics are structured, integrations can be far more precise. A deployment notification posts to one topic about one deploy, not into a general channel where it scrolls away.

12. Clients: Web, Desktop, Mobile

  • Web — the reference client, and the best one. Full-featured.
  • Desktop — Electron, available for Linux, macOS, and Windows.
  • Mobile — React Native apps for iOS and Android.
The honest note: the mobile apps have fewer features than the web client. This is a common pattern and Zulip is not unusually bad here, but if your team is mobile-first, evaluate the actual mobile experience before committing rather than assuming parity. There is also a command-line tool for the API-inclined.

13. Where Your Data Goes

Self-hosted Zulip is a strong data-sovereignty story, and the reasoning is straightforward. The message store is your Postgres database on your server. Every message, every file, every user record. There is no vendor copy. There is no telemetry requirement. Apache-2.0 imposes no obligation on you and, notably, no obligation on anyone else either — which is a different trade from copyleft, and one worth understanding (section 20). Compliance posture is inherited, not bought. Zulip's documentation and third-party profiles note that self-hosted deployments can be HIPAA and FERPA eligible — because you are running it on infrastructure whose compliance posture you control. Healthcare, education, and regulated finance organisations can put Zulip behind their own controls rather than trusting a vendor's. The jurisdiction caveat cuts the other way for the SaaS tier. Kandra Labs is a US company (San Francisco). Zulip Cloud is therefore subject to US jurisdiction, and — as with any US-hosted service — potentially to the CLOUD Act. Self-hosting removes that exposure completely. One more caveat, stated fairly: Kandra Labs does not publicly hold SOC 2 Type II or ISO 27001 for Zulip Cloud, as of the most recent public profiles. If your compliance framework demands a vendor attestation, Zulip Cloud will not currently give you one, and you should evaluate it as non-compliant infrastructure for regulated use until that changes. Self-hosting sidesteps this entirely, because the audited entity becomes your infrastructure rather than theirs.

14. The 10-User Push Notification Limit

This is the section that will decide it for a lot of readers, so let us be thorough. The situation: Zulip's mobile apps receive push notifications through Zulip's own push notification infrastructure. Routing mobile push requires the vendor to hold credentials for Apple's APNs and Google's FCM, and to operate the relay. That costs money per user. The limit: on the free self-hosted tier, mobile push notifications work for up to 10 users. Organisations above that need a paid plan for unlimited notifications — or they build and ship their own mobile apps with their own push credentials. Exceptions: unlimited mobile notifications are free for "eligible communities," which in practice includes most open-source projects, and some non-profit and educational institutions. If that is you, this entire section may not apply — check before you budget. What actually happens at user eleven: the apps still work. Messages, streams, topics, search, file uploads — all functional. What stops is the
push*. You open the app and see your messages; you do not get tapped on the shoulder. Is that acceptable? For some teams, yes. Desk-based teams who live in the web or desktop client will barely notice. For a field team, a support rotation, an on-call engineer, or anyone whose workflow depends on being interrupted by their phone — no, it is not acceptable, and you should treat the paid tier as mandatory from day one. The workarounds, and their real cost: 1. Pay. Simplest, supports the project, and honestly priced for the value. This is what most organisations should do. 2. Build your own mobile apps. Entirely possible — the code is Apache-2.0, so you can fork the React Native apps, add your own APNs and FCM credentials, and distribute them. That is a real project with real ongoing maintenance: app store accounts, signing certificates, a release process, and app updates every time you want upstream fixes. 3. Accept web-only notifications. Desktop notifications through the browser or Electron client work fine. If your team is at desks, this costs nothing. The honest framing: this is not open-core. It is not a feature being withheld. It is a genuine per-user cost that the vendor cannot make disappear, and they have chosen to pass it on above ten users rather than fake it. That is more honest than the alternative, and it is also a real constraint you must budget for.

15. No Built-In Voice or Video

Zulip has no native voice or video calling. No huddles, no built-in conferencing. For some organisations this is irrelevant — they use Zoom, Meet, or Jitsi and always will. For others, particularly those hoping to consolidate onto a single platform, it means Zulip cannot be the whole answer. The integration path is straightforward: Jitsi Meet and BigBlueButton both integrate, and there is a slash-command convention for spinning up a call and posting the link into the current topic. It works. It is not the same as having it native. Whether this matters depends entirely on whether you were planning to replace your conferencing tool. If you were, know now.

16. What It Actually Costs

| Component | Slack (paid) | Zulip self-hosted (free tier) | |---|---|---| | Per-user licence | Monthly per active user | $0, unlimited users | | Message history | Limited on lower tiers | Unlimited | | SAML / SSO | Higher tiers | $0, included | | LDAP / SCIM | Enterprise tier | $0, included | | Guest accounts | Paid | $0, included | | Infrastructure | $0 | ~$10–20/mo VPS at small scale | | Mobile push | Included | 10 users free, paid above | | Maintenance | None | Upgrades, backups, monitoring | The per-user saving is the headline and it is real: a 100-person organisation on a paid chat plan is spending five figures a year. Zulip on a $20 VPS is spending about $240. But the honest total includes the push notification tier if you need it, plus the operational time. Zulip is a four-service stack; budget a few hours a month for updates, monitoring, and the occasional incident. That is not nothing, and organisations with no one who wants to own that should seriously consider Zulip Cloud instead. The argument that survives the arithmetic: the per-user cost of chat scales with headcount, and that is the one cost you can least predict. Self-hosting converts an unpredictable per-seat expense into a predictable infrastructure one, and puts the entire communication history of your organisation onto hardware you control.

17. Zulip vs the Field

Slack is the incumbent and has the best integration ecosystem and the most polished surface. It is also per-seat, cloud-only, and holds your message history on someone else's infrastructure. If your team is already deeply embedded and the bill is acceptable, switching costs are real. Mattermost is the closest competitor in the self-hosted space, with a strong story for regulated and government deployments. It is open core — a meaningful portion of enterprise functionality sits in the paid edition. If you want the proprietary-tier features, budget for them. Rocket.Chat is broad and feature-rich with a large surface area, including some things Zulip lacks. It is also open core and, in my experience, heavier to operate. Element / Matrix offers federation, which is a genuinely different and powerful model — if you need to communicate across organisational boundaries without a shared server, Matrix is the only real answer. If you do not need federation, it adds complexity without benefit. Zulip's position is the clearest: the best conversation model for asynchronous work, the most honest licensing, and the most complete free feature set — at the cost of a heavier stack and a mobile push limit.

18. Migration and Lock-In

Zulip takes the no-lock-in claim seriously, and it shows in the tooling. There are high-quality import tools for Slack, Mattermost, Rocket.Chat, HipChat, Gitter, and IRC, plus a generic API for anything else. Slack exports import with users, channels, and message history preserved. There are also export tools going the other way: full exports of an organisation's data, compliance exports for regulated use, and a static HTML archive of message history. That last one is quietly excellent — a readable, self-contained archive of your organisation's conversations that requires no software to view, and will still be readable in twenty years. The practical consequence: moving to Zulip is a low-risk experiment. Import your Slack history, run it in parallel for two weeks, and if the team rejects it, export and go back. That reversibility is worth a great deal when you are asking an entire organisation to change how it communicates.

19. Honest Limitations

Mobile push caps at ten users on the free self-hosted tier. Covered at length; it is the big one. Four services to operate. Postgres, Redis, RabbitMQ, Memcached. More moving parts than single-binary alternatives. Officially Ubuntu/Debian. Other platforms work via Docker but with less testing and thinner documentation. No native voice or video. Integration only. Mobile apps lag the web client on features. The threading model requires adoption effort. People coming from Slack will not self-organise into good topics without prompting. Zulip Cloud lacks public SOC 2 / ISO 27001 as of the most recent profiles — relevant if you were considering the hosted tier for regulated use. Apache-2.0 is permissive, which cuts both ways. No copyleft means anyone can fork, close, and sell it. There is no structural guarantee that the project stays open in the way AGPL would provide. In practice Zulip's commercial model is support-based and aligned with keeping the code open, but the licence itself does not enforce that. Search and history caps apply to Zulip Cloud, not self-hosted.

20. Performance and Scaling

Zulip is designed for scale, and the architecture supports the claim. The RabbitMQ-based event queue means message fan-out does not happen in the request path. Connected clients receive events through a long-polling or event-queue mechanism rather than the server pushing to each one synchronously. Postgres handles durable storage with appropriate indexing, and Memcached absorbs hot reads. The project's own claim — comfortable for organisations with tens of thousands of users on modest hardware — is credible given the architecture, and there are public deployments at that scale. For the far more common case of a 20–200 person organisation, performance is a non-issue. A 4 GB VPS will not break a sweat. The scaling work only begins when you are big enough to have a dedicated ops person, at which point you will want to be reading the documentation's own scaling guide rather than this article.

21. Troubleshooting

Install script fails. Check that you are on a supported Ubuntu or Debian release and that the hostname resolves. The installer needs DNS to work for Certbot. Push notifications not arriving. Check your plan's user limit first, then check that the mobile app is signed in to the right server. Real-time delivery feels slow. RabbitMQ is unhappy. Check its status and logs. "Messages not appearing for some users." Permissions or stream subscription. Zulip's permission model is granular enough that a misconfigured group can hide a stream. Upgrades failing. Read the release notes for the specific version jump. Zulip's upgrade scripts are good, but multi-version jumps occasionally need intermediate steps. File uploads failing. Check disk space and Nginx's upload size limit, which defaults lower than most people expect. Search returning nothing. Check that the full-text index is populated after a large import; it can take a while.

22. Backup and Upgrades

The backup surface:
  • PostgreSQL — the critical one. Everything durable lives here. Use pg_dump on a schedule, and test a restore, because an untested backup is a hypothesis.
  • File uploads — stored on disk (or S3 if configured). Back them up too; a restore without attachments is a half-restore.
  • Configuration/etc/zulip/` holds settings and secrets. Version it in a private repository.
  • Redis, RabbitMQ, Memcached — transient. You can lose these and recover; you may lose a few in-flight events.
Zulip's own documentation covers backup and restore properly, including the restore-into-a-fresh-server procedure, which is the test you actually want to have run at least once before you need it. Upgrades are scripted and documented per release. The pattern: read notes, back up, run the upgrade script, verify. With roughly two releases in ninety days and steady commit activity, you are looking at a monthly-ish cadence — frequent enough to be current, infrequent enough to be manageable.

23. Who Should Run It, and Who Shouldn't

Run it if your team is distributed across time zones and losing context in real-time channels; if you want SAML, LDAP, and SCIM without an enterprise quote; if your organisation's communication history should be on hardware you control; if you are in a regulated industry and need to inherit your own compliance posture; or if you simply object to open-core on principle and want a project that does not play that game. Think twice if mobile push is mission-critical for more than ten people and you cannot pay (budget for it, or build your own apps); if you need native voice and video in the same tool; if nobody wants to own a four-service stack; or if your team is deeply embedded in Slack's ecosystem and the switching cost is higher than the licence saving. Consider Zulip Cloud instead if you want the conversation model without the operations. Just know about the 10,000-message search cap on the free tier and the current absence of public SOC 2 attestation.

24. The Verdict

Zulip is the most intellectually honest team chat project in the open-source space, and it wins on two axes that rarely align. The first is the conversation model. Topic-based threading is not a feature — it is a bet that most workplace communication should be asynchronous, and it is a bet that pays off for any team that has ever lost an afternoon to a busy channel. People who adapt to it rarely want to go back. The second is the licensing. SAML, LDAP, SCIM, guests, retention policies, compliance exports, unlimited history — free, in the open-source edition, in an Apache-2.0 repository with no enterprise directory holding the good parts back. Compared to competitors that gate authentication behind a paywall, that is a genuinely different posture, and it is why Zulip belongs on any shortlist for a self-hosted communication platform. The costs of that honesty are visible and worth budgeting: mobile push stops at ten users because push genuinely costs money per user, and you pay above that or build your own app. Voice and video are not native. The stack is four services, not one binary. And the threading model requires someone to model good habits in the first fortnight. None of those are hidden. All of them are things the project tells you up front — which, in a category where "open source" frequently means "the community edition," is itself the strongest recommendation.

Related

Comments (0)

No comments yet. Be the first to comment!

Leave a Comment