Requirements and scalability¶
To run a Zulip server, you will need:
A dedicated machine or VM
A supported OS:
Ubuntu 20.04 Focal
Ubuntu 18.04 Bionic
Debian 10 Buster
At least 2GB RAM, and 10GB disk space
If you expect 100+ users: 4GB RAM, and 2 CPUs
A hostname in DNS
Credentials for sending email
For details on each of these requirements, see below.
The installer expects Zulip to be the only thing running on the
system; it will install system packages with
apt (like Nginx,
PostgreSQL, and Redis) and configure them for its own use. We
strongly recommend using either a fresh machine instance in a cloud
provider, a fresh VM, or a dedicated machine. If you decide to
disregard our advice and use a server that hosts other services, we
can’t support you, but
we do have some notes on issues you’ll encounter.
Ubuntu 20.04 Focal, 18.04 Bionic, and Debian 10 Buster are supported for running Zulip in production. 64-bit is recommended. We recommend installing on the newest supported OS release you’re comfortable with, to save a bit of future work upgrading the operating system.
sudo add-apt-repository universe sudo apt update
CPU and memory: For installations with 100+ users you’ll need a minimum of 2 CPUs and 4GB RAM. For installations with fewer users, 1 CPU and 2GB RAM is sufficient. We strongly recommend against installing with less than 2GB of RAM, as you will likely experience out of memory issues installing dependencies. We recommend against using highly CPU-limited servers like the AWS
t2style instances for organizations with hundreds of users (active or no).
Disk space: You’ll need at least 10GB of free disk space for a server with dozens of users. We recommend using an SSD and avoiding cloud storage backends that limit the IOPS per second, since the disk is primarily used for the Zulip database.
See our documentation on scalability below for advice on hardware requirements for larger organizations.
Network and security specifications¶
Incoming HTTPS access (usually port 443, though this is configurable) from the networks where your users are (usually, the public Internet).
Incoming port 80 access (optional). Zulip only serves content over HTTPS, and will redirect HTTP requests to HTTPS.
Incoming port 25 if you plan to enable Zulip’s incoming email integration.
Outgoing HTTP(S) access (ports 80 and 443) to the public Internet so that Zulip can properly manage image and website previews and mobile push notifications. Outgoing Internet access is not required if you disable those features.
Outgoing SMTP access (usually port 587) to your SMTP server so that Zulip can send emails.
A domain name (e.g.
zulip.example.com) that your users will use to access the Zulip server. In order to generate valid SSL certificates with Certbot, and to enable other services such as Google authentication, public DNS name is simpler, but Zulip can be configured to use a non-public domain or even an IP address as its external hostname (though we don’t recommend that configuration).
Zulip supports running behind a reverse proxy.
Zulip servers running inside a private network should configure the
smokescreenintegration to protect against SSRF attacks, where users could make the Zulip server make requests to private resources.
Your Zulip server will need an SSL certificate for the domain name it
uses. For most Zulip servers, the recommended (and simplest) way to
get this is to just use the
--certbot option in the
Zulip installer, which will automatically get a certificate for you
and keep it renewed.
For test installations, an even simpler alternative is always
--self-signed-cert option in the
If you’d rather acquire an SSL certificate another way, see our SSL certificate documentation.
Outgoing email (SMTP) credentials that Zulip can use to send outgoing emails to users (e.g. email address confirmation emails during the signup process, message notification emails, password reset, etc.). If you don’t have an existing outgoing SMTP solution, read about free outgoing SMTP options and options for prototyping.
Once you have met these requirements, see full instructions for installing Zulip in production.
This section details some basic guidelines for running a Zulip server for larger organizations (especially >1000 users or 500+ daily active users). Zulip’s resource needs depend mainly on 3 parameters:
daily active users (e.g. number of employees if everyone’s an employee)
total user accounts (can be much larger)
In the following, we discuss a configuration with at most two types of servers: application servers (running Django, Tornado, RabbitMQ, Redis, Memcached, etc.) and database servers. Of the application server services, Django dominates the resource requirements. One can run every service on its own system (as docker-zulip does) but for most use cases, there’s little scalability benefit to doing so. See deployment options for details on installing Zulip with a dedicated database server.
Dedicated database. For installations with hundreds of daily active users, we recommend using a remote PostgreSQL database, but it’s not required.
RAM: We recommended more RAM for larger installations:
With 25+ daily active users, 4GB of RAM.
With 100+ daily active users, 8GB of RAM.
With 400+ daily active users, 16GB of RAM for the Zulip application server, plus 16GB for the database.
With 2000+ daily active users 32GB of RAM, plus 32GB for the database.
Roughly linear scaling beyond that.
CPU: The Zulip application server’s CPU usage is heavily optimized due to extensive work on optimizing the performance of requests for latency reasons. Because most servers with sufficient RAM have sufficient CPU resources, CPU requirements are rarely an issue. For larger installations with a dedicated database, we recommend high-CPU instances for the application server and a database-optimized (usually low CPU, high memory) instance for the database.
Disk for application server: We recommend using the S3 file uploads backend to store uploaded files at scale. With the S3 backend configuration, we recommend 50GB of disk for the OS, Zulip software, logs and scratch/free space. Disk needs when storing uploads locally
Disk for database: SSD disk is highly recommended. For installations where most messages have <100 recipients, 10GB per 1M messages of history is sufficient plus 1GB per 1000 users is sufficient. If most messages are to public streams with 10K+ users subscribed (like on chat.zulip.org), add 20GB per (1000 user accounts) per (1M messages to public streams).
Example: When the chat.zulip.org community server had 12K user accounts (~300 daily actives) and 800K messages of history (400K to public streams), it was a default configuration single-server installation with 16GB of RAM, 4 cores (essentially always idle), and its database was using about 100GB of disk.
Disaster recovery: One can easily run a hot spare application server and a hot spare database (using PostgreSQL streaming replication). Make sure the hot spare application server has copies of
/etc/zulipand you’re either syncing
LOCAL_UPLOADS_DIRor using the S3 file uploads backend.
Sharding: Zulip releases do not fully support dividing Tornado traffic for a single Zulip realm/organization between multiple application servers, which is why we recommend a hot spare over load-balancing. We don’t have an easily deployed configuration for load-balancing Tornado within a single organization, and as a result can’t currently offer this model outside of enterprise support contracts.
Zulip 2.0 and later supports running multiple Tornado servers sharded by realm/organization, which is how we scale Zulip Cloud. Contact us for help implementing the sharding policy.
Scalability is an area of active development, so if you’re unsure whether Zulip is a fit for your organization or need further advice contact Zulip support.
For readers interested in technical details around what features impact Zulip’s scalability, this performance and scalability design document may also be of interest.