https://zulip.readthedocs.io/en/latest/production/requiremen... is a useful reference for folks interested in memory requirements for a self-hosted Zulip server.
3,222 karma · joined February 9, 2010
https://zulip.readthedocs.io/en/latest/production/requiremen... is a useful reference for folks interested in memory requirements for a self-hosted Zulip server.
https://www.nytimes.com/2017/11/05/world/yuri-milner-faceboo...
Also the total funds at the time was ~$150K, aka roughly what YC was doing before this announcement: https://techcrunch.com/2011/01/28/yuri-milner-sv-angel-offer...
(I believe the history is that at the time, YC didn't have the free cash flow themselves to invest in every YC startup).
$500k is enough money for a team with multiple founders who are OK with living on a graduate student budget of ~$30-40k/person/year (as my friends were, inflation adjusted, when we dropped out of graduate school to found Ksplice) to pay their expenses for multiple years, and still have plenty of money for hardware, hiring people to do specialty work they aren't good at, etc.
$125k is not, which means this change is a big shift in what is possible for a company raising money only from YC.
What this change means is that it's now more realistic for a team without any personal capital to start a startup and then bootstrap it from there, without raising capital from anyone other than YC (which I believe is experientially pretty different from having VC investors). Prior to this announcement, the main way to raise that kind of capital without angels/VCs on your cap table was the NSF's SBIR program.
Due to the selection process, companies accepted into YC generally are those that planning to raise a big funding round just after Demo Day, but I know a lot of folks who didn't succeed in doing so (some of whose companies are still in business 10 years later). This change in how much money YC offers means that failing to raise a satisfactory round at Demo Day does not mean they need to give up -- teams can spend a couple years figuring out their business if they think doing so is warranted.
(I have no YC affiliation other than having invested in many YC companies in the past).
At Zulip, we’re out to build the world’s best collaboration platform, and we’re committed to keeping it 100% open source. Zulip is the only modern team chat app that is ideal for both live and asynchronous conversations. Our product serves as the communication hub for businesses, open-source projects, educators and communities around the world.
We are looking for an experienced product designer with a strong background in visual design to make our web and mobile applications shine. Our product has been described as “everything Slack is, but smarter and more powerful.” By working to also make Zulip beautiful and easy to learn, you will have the opportunity to have a huge impact on the growth of our product.
We are also hiring for Engineering, Marketing, and Technical Writing roles. For full details on this role and other open positions, check out https://zulip.com/jobs/. Apply at jobs@zulip.com.
I'll add for folks thinking about this transition that we took a pretty different strategy for converting Zulip to be type-checked: https://blog.zulip.com/2016/10/13/static-types-in-python-oh-...
The post is from 2016 and thus a bit stale in terms of the names of mypy options and the like, but the incremental approach we took involved only using mypy's native exclude tooling, and might be useful for some projects thinking about doing this transition.
One particular convention that I think many other projects may find useful is how we do `type: ignore` in comments in the Zulip codebase, which is to have a second comment on the line explaining why we needed a `type: ignore`, like so:
* # type: ignore[type-var] # https://github.com/python/typeshed/issues/4234
* # type: ignore[attr-defined] # private member missing from stubs
* # type: ignore[assignment] # Apparent mypy bug with Optional[int] setter.
* # type: ignore[misc] # This is an undocumented internal API
We've find this to be a lot more readable than using the commit message to record why we needed a `type: ignore`, and in particular it makes the work of removing these with time feel a lot more manageable to have the information organized this way.
(And we can have a linter enforce that `type: ignore` always comes with such a comment).
We expect to have a native feature allowing a configurable set of streams to be browsed using a real Zulip web app UI without creating an account, available in beta in the next few weeks; we're actively integrating the implementation via https://github.com/zulip/zulip/pull/18532.
We plan to look at optional search indexing in that native implementation once the logged-out access feature is complete.
For context, Zulip is a 100% open-source team chat project (in the same space as Slack/IRC/etc.). You can self-host Zulip, which we've put a lot of effort into making easy, or host it on Zulip Cloud (with both free and paid plans). There's no individual subscription option for the product at all -- just like with Slack -- so the app store policies to enforce their monopoly by requiring all individual purchases be taxed by Google/Apple shouldn't even apply to us.
But we've still had multiple rounds of rejections caused by aggressive enforcement of these policies:
* A couple years ago, Apple reviewers repeatedly rejected updates to the app because the privacy policy / terms of service pages linked from the app contained the zulip.com website footer, which in turn link to the pricing page for Zulip's paid offerings. This means our Privacy Policy could be a way to get people to buy something without paying the Apple tax! We "resolved" this, on the advice of their appeals expert, by passing a special parameter when loading these pages from the ToS/Privacy links in the mobile apps that hides the header/footer sections of the page :(.
* In May, Apple reviewers repeatedly rejected the Zulip mobile app for linking to its own source on GitHub. At first we thought the problem was that we had recently set up GitHub Sponsors [1]. Further correspondence determined that the problem was even more ridiculous: Any GitHub page has a tiny link in the https://github.com/zulip/zulip-mobile footer for GitHub's own pricing! We were able to convince them to approve it in the end, but we were close to giving up and removing the GitHub links. I'm still upset about the whole experience because it was a huge waste of energy.
It's not clear to me whether these rejections are what Apple's policies intended or just the policies being incorrectly applied. But it doesn't really matter: these appeal processes are opaque and scary and mostly consist of them repeating what you need to change with minimal explanation. If not for the entrenched monopoly, we'd be looking to switch to another vendor that wasn't so sloppy about something that's very important to us. I think the harm caused by sloppiness on the part of monopolies doesn't get enough attention.
[1] This would have been wrong too, though I do know some companies use a Patreon as the way to sell their product, and I can imagine that being a workaround that Apple would be on the lookout for. But it's easy to check that we're definitely not playing that game.
* One can cheaply compose full-text search with other search operators by just doing normal joins on database indexes, which means we can cheaply and performantly support tons of useful operators (https://zulip.com/help/search-for-messages).
* We don't have to build a pipeline to synchronize data between the real database and the search database. Being a chat product, a lot of the things users search for are things that changed recently; so lag, races, and inconsistencies are important to avoid. With the Postgres full-text search, all one needs to do is commit database transactions as usual, and we know that all future searches will return correct results.
* We don't have to operate, manage, and scale a separate service just to support search. And neither do the thousands of self-hosted Zulip installations.
Responding to the "Scaling bottleneck" concerns in comments below, one can send search traffic (which is fundamentally read-only) to a replica, with much less complexity than a dedicated search service.
Doing fancy scoring pipelines is a good reason to use a specialized search service over the Postgres feature.
I should also mention that a weakness of Postgres full-text search is that it only supports doing stemming for one language. The excellent PGroonga extension (https://pgroonga.github.io/) supports search in all languages; it's a huge improvement especially for character-based languages like Japanese. We're planning to migrate Zulip to using it by default; right now it's available as an option.
More details are available here: https://zulip.readthedocs.io/en/latest/subsystems/full-text-...
I'm not sure about this detail of Slack's ToS. At a technical level, you can certainly export your data from a Slack (which is we implement https://zulip.com/help/import-from-slack); I imagine it's easy to write a tool to format and publish it.
FWIW Zulip maintains https://github.com/zulip/zulip-archive, which is a configurable API-based tool for creating a static HTML archive from a Zulip organization, with tooling to update it every few minutes. A lot of larger open projects use it. (We're also working on a native logged-out access feature with less janky formatting, which has a working PR that we need to integrate).
I suppose you could export your data from Slack, import it into Zulip, and then publish that using zulip-archive if you didn't want to write any code, but I'm sure the formatting would be better preserved if one avoided the "convert Slack markup to Zulip markup" step.
We provide our full Zulip Cloud Standard paid plan for free to open source projects (and various other worthy causes!). We also prioritize and build features specifically because OSS projects asked for them:
https://zulip.com/for/open-source/
Hundreds of open source projects, including Rust, Julia, MariaDB, and Clojure, use Zulip as their team chat platform. We often hear from large open source projects that they substantially prefer Zulip's topic-based model to the user experience in Discord or Slack, or that they found it made their open source community work. See for example these tweets from the last few weeks:
* https://twitter.com/mojavelinux/status/1409702273400201217
* https://twitter.com/ornicar/status/1412672302601457664
Also in contrast with open core products like Mattermost, Zulip is proudly 100% open source software. You can learn a bit more about Zulip's open source model here:
https://blog.zulip.com/2021/04/28/why-zulip-is-on-github-spo...
* https://zulip.com/api/real-time-events
* https://zulip.com/api/register-queue
* https://zulip.readthedocs.io/en/latest/subsystems/events-sys...
We use this same long-polling based /events API interface for all official clients (web, mobile, terminal), our interactive bots ecosystem (https://zulip.com/api/running-bots), and many integrations (E.g. bridges with IRC/Matrix/etc.).
We also offer webhooks, because some platforms like Heroku or AWS Lambda make it much easier to accept incoming HTTP requests than do longpolling, but the events system has always felt like a nicer programming model.
(Zulip's events system was inspired by separate ~2012 conversations I had with the Meteor and Quora founders about the best way to do live updates in a web application).
We are actively working on several ideas in this space. (One of the most important that was released in 4.0 is the redesign of the Reply button to make starting a reply feel like it does in other chat tools).
I expect we'll be able to get into a really nice place with a combination of new settings with some mixture of "Easy mode" defaults, design changes, and onboarding adjustments. (We will do this while carefully preserving model/paradigm, in case anyone's worried). Feel free to stop by chat.zulip.org if you want to discuss specifics.
FWIW, we regularly hear from large organizations, including some with thousands of nontechnical users, about their having great luck migrating to Zulip. Usually they tell us they did a 30-minute training and then things went smoothly from there, or they didn't and it took a couple weeks for some users to get the hang of it.
In the scheme of things, doing a training is a pretty minimal investment to be able to use a better product for hundreds of hours a year. But of course Zulip would grow a lot faster if nobody worried whether their nontechnical users will thrive on it, so this area is a priority for us.
The product feedback on external guests is very helpful! You're encouraged to stop by chat.zulip.org and start threads in #feedback about each item if you'd like to help design how we address it, but in any case I'll discuss them with the community.
(For readers missing context, Zulip provides read-only access to many organization-level settings to normal users as a form of documentation on the organization's policies and what options exist that one might ask an administrators to adjust).
These integrations are a bit ugly and certainly not the ideal design, but they work and help a lot of communities that are 90% on Zulip but still want an IRC presence for whatever reason. (A fun historical note: Zulip's had a really nice puppet-powered bridge with Zephyr since 2012, because that was how we got enough usage during its early development to design the product and its data model with real users).
Longer term, we're planning to build a native Zulip federation feature. For us the technical strategy has been to first make a Zulip world-class user experience, and do native federation later.
Our strategy is motivated by XMPP, which like Matrix is extremely general (E.g. I talked to people who used XMPP as message bus for their backend infrastructure 10 years ago). XMPP is dying as a chat protocol because nobody can build a modern world-class chat application using it as the client/server protocol.
E.g. multiple people who'd worked as engineers on now-dead chat products complained that because their mobile apps talked XMPP to their server, it was impossible for them to make the apps start quickly in medium-size organizations, because of all the round-trips required.
In contrast, Zulip's client/server protocol both on web and mobile returns all metadata in a single HTTP request: https://zulip.com/api/register-queue, and then after that, another to fetch whatever messages you're going to look at.
That said, I don't think you should expect a Zulip-style threading user experience in Element anytime soon. Regardless of how the Matrix protocol for federation between servers is extended, providing the "Zulip user experience" would likely require a major overhaul of both their client/server protocol for Element and their client user experience. (Also, the proposal you link is for HN-style threading, not Zulip-style topics).
I don't understand Element's internals, but my basis for this claim is a huge portion of all technical and design work we do on Zulip wouldn't be necessary or would be much simpler if Zulip didn't have topics (E.g. the architectural decision criticized in https://news.ycombinator.com/item?id=27150492 is a good example). See https://news.ycombinator.com/item?id=27150196 for a few more examples. I imagine Element will only invest in all of that work that if they believe it's important to their business.
As an outside observer, Element's business focus seems to be on competing with WhatsApp/Messenger/Signal/Telegram/SMS, not Slack, so while I'd love to see Matrix/Element borrow Zulip's topics model, you probably shouldn't hold your breath.
Especially since that latency is mostly invisible, thanks to local echo: https://zulip.readthedocs.io/en/latest/subsystems/sending-me...
It's also not very high-value to optimize; that database write is 10-20% of the total time to process sending a message to everyone in a large open community like chat.zulip.org (with 18K total users).
We know this is a real UX problem, and we're working on it.
Before Zulip 4.0, there was a "Saved as draft" notice that appeared on closing the compose box, but empirically, that was invisible to some users, who had the terrible experience of fearing their message was lost.
The 4.0 release replaces the notification with a darker and better located notification, which will likely help some users. But we'll only know for sure whether it's still invisible to some users with time.
In any case, we're planning several more changes to improve the drafts user experience that didn't make it into this release.
https://github.com/zulip/zulip/issues/17396 is one current issue on the topic.
Agreed!
To clarify the terminology, "guests" in Zulip (and other team chat products, e.g. Slack) generally refers to users with an account but with limited access. https://zulip.com/help/roles-and-permissions has more detail on that.
We've been tentatively planning to use the term "web-public streams" for streams that an open community has configured to be accessible without creating a Zulip account. The project is quite far along; the latest PR is here:
https://github.com/zulip/zulip/pull/16728
(The PR looks stale, but that's only because we paused integrating it to focus on finishing 4.0; I would be sad if we don't have it at least in beta this summer.)
I agree with that, and I hope my comment above didn't mean to sound dismissive of concerns about visual design!
Visual work to mean these workarounds are not required is one of our main priorities for the next few months, and I mentioned the above mainly because many folks have found them helpful when using the Zulip that exists today.
(As a sidenote, we have an open position for a designer).
I don't think this is accurate. At least, I'm aware of a chat project called Chime at Dropbox circa 2015 that was not based on Zulip and at least at the time did not materially involve anyone from the original Zulip team.
(I suppose some of those things could have changed since I last heard anything on the topic).
Interesting, I've never heard that rumor before.
> a single write in a 5000 member public group would result in 5000 writes to the user table.
This hasn't been true since we implemented soft deactivation in 2017. You can read about the feature in our documentation here; I think it's a pretty cool design:
https://zulip.readthedocs.io/en/latest/subsystems/sending-me...
The optimization takes advantage of the fact that public groups with 10Ks of members tend to have a lot of totally inactive users, and so if you have a good way to know that only 600 of them have logged in during the last 2 weeks, your server can run like it only has 600 users.
It is true that Zulip writes a tiny UserMessage table row with (user_id, message_id, flags) for every active recipient of a message, we need to do so in order to track the unread state for all of those recipients (as well as related details, like mobile push notifications state). We need to write to that row a second time when the user reads the message.
With modern postgres and SSDs, writing 1000 rows is really cheap, and so part this is extremely fast when sending messages with 1000 online recipients, which isn't a thing real users do constantly anyway (since that's effectively an announcement, not a chat message).
Folks who are curious can read https://chat.zulip.org/#narrow/stream/3-backend/topic/send_m..., which is related optimization work we did this week that made it into this release.
(You could have a bad experience if you use remote storage that rate-limits "IOPS", though, because AWS at least used to count each row as an IOP and would use your full quota for 20s if you marked 20K messages as read with a 1000 UOP/s plan).
* Using the night theme, which some folks strongly prefer to day theme.
* Zooming to 110%, which makes Zulip's font size similar to Slack and its clones.
With any luck, this summer we'll migrate our default font size to match other modern webapps, ideally with a "Dense mode" that preserves the current size for folks who want to fit more content on their screen.
I've thought about changing the default theme to the day theme, but it seems a little sad to remove our current defaut (of automatically detecting the browser configuration via `prefers-color-scheme`).
So if Slack and all of its clones copy Zulip's model, I'd call that a success for us having changed the way people work. That said, Zulip is 100% open source under the Apache license (very rare these days), and that will remain a differentiator, as you can't self-host Slack, nor can you audit its source code or fork it to solve a problem specific to your use case. (We also have a lot of other innovative features, like native LaTeX support, customizable linkifers, etc.).
That said, topics are not something one can just copy in an existing chat app -- there's a lot more to Zulip's topic-based threading model than "a feature".
* Being able improve organization by renaming and splitting topics, move topics between streams, etc., is critical to the reading and conversation experience. This requires lot of thought about subtle technical and user experience details. (E.g. if someone renames a topic, and you were in the process of composing a reply, your compose box updates to the the new topic).
* Tracking unread counts on a per-message basis, rather than a "pointer within a channel", which is required for splitting topics to do something sane. This, in turn, requires clever data structures so that the moment the browser loads, you can see where all 35000 unread messages are. (Folks routinely have that when they come back to a busy open community after months away).
* All sort of clever performance and client-side caching things to make it feel like the browser has all your data so that clicking around feels instant.
* Dozens more things along these lines.
And those are just the engineering details. The bigger part of topics that it requires an overhaul of the whole UI. At least for us, a huge fraction of features are different than they would otherwise be because of topics (E.g. Zulip's compose box supporting sending to a different place than what you're looking at, and fading messages that weren't sent to that place to help users avoid mistakes). This sort of overhaul is hard to do, and even harder to do with a large existing userbase.
As a result, if Zulip fails, I'd be very surprised if it's because other companies copied Zulip's model so well that there was no reason to prefer Zulip's topics implementation.
Far more likely is some combination of our competition having infinite marketing dollars, inertia in organizations that don't realize how much better their working experience could be, and Microsoft's campaign to make everyone unwilling use anything other than Teams, because "we already bought Teams with our Office 365 subscription".
Essentially everyone has miniature versions of the catch-up problem:
* Fulltime employees coming back from a normal 1-2 week vacation. * Anyone working closely with collaborators in other time zones (I wake up every morning to a couple hundred new messages in chat.zulip.org sent by our international community members). * Any leader who spends a lot of time in meetings and wants to focus on the meeting and then batch-process communications afterwards. * Any engineer who wants to be able to spend a whole or half day focusing on a really difficult problem and catch up on conversations afterwards. * Anyone who's a part-time participant in an open community, whether they just check it once a day, one a week, or once a month. A user in this situation really wants to skim everything that happened and find what's interesting to them, not read the last few hours' traffic, which is what the Slack/Discord/Teams model forces you to do.
The same technique core works for all of these cases: pick your favorite streams and read them with `n` as I described above, then perhaps browse the list of topics in several more and click into just the topics that interest you and then mark the rest (if any) as read.
All IRC-inspired chat tools are a really rough experience for part-time participants -- they just don't have a way to let you prioritize reading interesting conversations. We discuss this issue at length and its consequences for inclusivity of the communities that use them in https://zulip.com/for/open-source/. (It's framed around inclusivity in open source, but the Slack channel model also can exclude leaders who spend most of their time in meetings)
(As a sidenote, being able to do this is why Zulip pushes users to have every conversation in a topic, rather than "threading" being a side feature used for 10% messages like some other tools do.)
I don't think most people need to read everything they receive, but in my role as the project leader of a large open source community, essentially every conversation in chat.zulip.org is potentially relevant for me, so skimming every conversation is useful.
The critical thing here, both in my daily work and coming back from time away, is that Zulip makes skimming really cheap (`n` to jump to next topic, then read a moment and then hit `End` if it seems likely that the thread is resolved to check the conclusion, and then repeat). So a 150-message thread debugging something takes like 30 seconds -- read the first post (maybe a bug report), note who was helping investigate, jump to send and see that the topic ends with a PR link or other resolution.
At the same time, Zulip's organization means I could find the dozen of threads that might be a short thread presenting a question or problem that I'm our main expert on. In these cases, I can read the thread carefully, and send a reply resurrecting the thread (2 months later) with answer that was missing, some added context/background, or a link to a PR I made to put the answer in our documentation (my preferred solution to unanswered questions).
This has the effect of unblocking a bunch of useful work that had been waiting for me to return, and also giving me good context on everything I missed.
It's also pretty fun to see all the great that folks did while I was away :)
But "Element Matrix Services" (aka New Vector) launching and marketing a product/feature that is not open source is AFAIK something new, and it'd be very surprising if this is the last such feature they announce.
(Before today, they were one of the very few examples I knew of a VC-funded open source company where their product remained entirely open source.)
I expect we'll never get a useful explanation from Google for why this incident happened -- abuse teams, like fraud teams, are worried about the bad guys using the explanations to tune their tactics and so tend to never explain anything.
But the details of how Google screwed up here also don't matter. A sudden Friday night suspension of a popular, legitimate app is insane! That possibility shouldn't be in the flowchart.
I get that for malware/spam/etc., it's important to immediately suspend, but I don't understand why Google doesn't take more seriously the very negative harm caused by doing that to a legitimate app. Some notice and appeal opportunity should be required before suspending a popular app by a legitimate publisher.
I'm upset, and a bit scared, but I can't say I'm surprised. This sort of random/erroneous/arbitrary punishment without explanation happens all the time with Google and other major tech companies. And every app developer I've met has experienced _significant_ disruption to their app publishing efforts due arbitrary/random rejections by an Apple app store reviewer, and this has been the case for years, so we can pretty confident that the vendors won't improve unless they are forced to do so.
There needs to be regulatory oversight of the Google/Apple app stores and the negative consequences for everyone else of their error-prone and ruthless enforcement processes.