2020-08-11 01:47:54 +02:00
|
|
|
# Requirements and scalability
|
2016-07-12 21:35:25 +02:00
|
|
|
|
2018-03-03 03:12:40 +01:00
|
|
|
To run a Zulip server, you will need:
|
2021-08-20 22:54:08 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- A dedicated machine or VM
|
|
|
|
- A supported OS:
|
|
|
|
- Ubuntu 20.04 Focal
|
2021-09-09 09:38:43 +02:00
|
|
|
- Debian 11 Bullseye
|
2021-08-20 21:45:39 +02:00
|
|
|
- Debian 10 Buster
|
2022-01-22 15:29:19 +01:00
|
|
|
- At least 2 GB RAM, and 10 GB disk space
|
|
|
|
- If you expect 100+ users: 4 GB RAM, and 2 CPUs
|
|
|
|
- If you intend to [upgrade from Git][upgrade-from-git]: 3 GB RAM, or
|
2022-01-19 00:23:43 +01:00
|
|
|
2G and at least 1G of swap configured.
|
2021-08-20 21:45:39 +02:00
|
|
|
- A hostname in DNS
|
|
|
|
- Credentials for sending email
|
2018-03-03 03:12:40 +01:00
|
|
|
|
|
|
|
For details on each of these requirements, see below.
|
|
|
|
|
2022-02-16 01:39:15 +01:00
|
|
|
[upgrade-from-git]: upgrade-or-modify.md#upgrading-from-a-git-repository
|
2022-01-19 00:23:43 +01:00
|
|
|
|
2016-08-25 00:19:10 +02:00
|
|
|
## Server
|
2016-07-28 01:38:02 +02:00
|
|
|
|
2017-07-26 00:32:51 +02:00
|
|
|
#### General
|
|
|
|
|
2017-05-24 22:36:15 +02:00
|
|
|
The installer expects Zulip to be the **only thing** running on the
|
2022-01-25 07:21:47 +01:00
|
|
|
system; it will install system packages with `apt` (like nginx,
|
2021-11-18 01:45:48 +01:00
|
|
|
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, [our Docker image][docker-zulip-homepage], 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](install-existing-server.md).
|
2017-07-26 00:32:51 +02:00
|
|
|
|
2020-08-11 01:47:54 +02:00
|
|
|
#### Operating system
|
2017-07-26 00:32:51 +02:00
|
|
|
|
2022-03-06 23:44:19 +01:00
|
|
|
Ubuntu 20.04 Focal, Debian 11 Bullseye, and Debian 10
|
2021-11-18 01:45:48 +01:00
|
|
|
Buster are supported for running Zulip in production. You can also
|
|
|
|
run Zulip on other platforms that support Docker using
|
|
|
|
[docker-zulip][docker-zulip-homepage].
|
|
|
|
|
2021-09-09 09:38:43 +02:00
|
|
|
We recommend installing on the newest supported OS release you're
|
2021-11-18 01:45:48 +01:00
|
|
|
comfortable with, to save a bit of future work [upgrading the
|
|
|
|
operating system][upgrade-os].
|
2017-07-26 00:32:51 +02:00
|
|
|
|
2018-10-31 19:53:09 +01:00
|
|
|
If you're using Ubuntu, the
|
|
|
|
[Ubuntu universe repository][ubuntu-repositories] must be
|
2019-01-26 21:27:10 +01:00
|
|
|
[enabled][enable-universe], which is usually just:
|
|
|
|
|
2021-08-20 07:09:04 +02:00
|
|
|
```bash
|
2019-01-26 21:27:10 +01:00
|
|
|
sudo add-apt-repository universe
|
|
|
|
sudo apt update
|
|
|
|
```
|
2018-10-31 19:53:09 +01:00
|
|
|
|
2021-11-18 01:45:48 +01:00
|
|
|
[docker-zulip-homepage]: https://github.com/zulip/docker-zulip#readme
|
2022-02-16 01:39:15 +01:00
|
|
|
[upgrade-os]: upgrade-or-modify.md#upgrading-the-operating-system
|
2021-08-20 22:54:08 +02:00
|
|
|
[ubuntu-repositories]: https://help.ubuntu.com/community/Repositories/Ubuntu
|
2018-10-31 19:53:09 +01:00
|
|
|
[enable-universe]: https://help.ubuntu.com/community/Repositories/CommandLine#Adding_the_Universe_and_Multiverse_Repositories
|
|
|
|
|
2020-08-11 01:47:54 +02:00
|
|
|
#### Hardware specifications
|
2016-07-28 01:38:02 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- CPU and memory: For installations with 100+ users you'll need a
|
2022-01-22 15:29:19 +01:00
|
|
|
minimum of **2 CPUs** and **4 GB RAM**. For installations with fewer
|
|
|
|
users, 1 CPU and 2 GB RAM is sufficient. We strongly recommend against
|
|
|
|
installing with less than 2 GB of RAM, as you will likely experience
|
2021-08-20 21:53:28 +02:00
|
|
|
out of memory issues installing dependencies. We recommend against
|
2016-11-27 04:04:35 +01:00
|
|
|
using highly CPU-limited servers like the AWS `t2` style instances
|
2019-12-13 01:30:22 +01:00
|
|
|
for organizations with hundreds of users (active or no).
|
2017-06-04 08:38:44 +02:00
|
|
|
|
2022-01-22 15:29:19 +01:00
|
|
|
- Disk space: You'll need at least 10 GB of free disk space for a
|
2021-08-20 21:53:28 +02:00
|
|
|
server with dozens of users. We recommend using an SSD and avoiding
|
2019-12-13 01:30:22 +01:00
|
|
|
cloud storage backends that limit the IOPS per second, since the
|
|
|
|
disk is primarily used for the Zulip database.
|
|
|
|
|
|
|
|
See our [documentation on scalability](#scalability) below for advice
|
|
|
|
on hardware requirements for larger organizations.
|
2016-07-28 01:38:02 +02:00
|
|
|
|
2020-08-11 01:47:54 +02:00
|
|
|
#### Network and security specifications
|
2016-07-28 01:38:02 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Incoming HTTPS access (usually port 443, though this is
|
2022-02-16 01:39:15 +01:00
|
|
|
[configurable](deployment.md#using-an-alternate-port))
|
2019-06-17 21:16:34 +02:00
|
|
|
from the networks where your users are (usually, the public
|
2019-12-13 01:30:22 +01:00
|
|
|
Internet).
|
2021-08-20 21:53:28 +02:00
|
|
|
- Incoming port 80 access (optional). Zulip only serves content over
|
2019-12-13 01:30:22 +01:00
|
|
|
HTTPS, and will redirect HTTP requests to HTTPS.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Incoming port 25 if you plan to enable Zulip's [incoming email
|
2022-02-24 00:17:21 +01:00
|
|
|
integration](email-gateway.md).
|
puppet: Admit we leave epmd port 4369 open on all interfaces.
The Erlang `epmd` daemon listens on port 4369, and provides
information (without authentication) about which Erlang processes are
listening on what ports. This information is not itself a
vulnerability, but may provide information for remote attackers about
what local Erlang services (such as `rabbitmq-server`) are running,
and where.
`epmd` supports an `ERL_EPMD_ADDRESS` environment variable to limit
which interfaces it binds on. While this environment variable is set
in `/etc/default/rabbitmq-server`, Zulip unfortunately attempts to
start `epmd` using an explicit `exec` block, which ignores those
settings.
Regardless, this lack of `ERL_EPMD_ADDRESS` variable only controls
`epmd`'s startup upon first installation. Upon reboot, there are two
ways in which `epmd` might be started, neither of which respect
`ERL_EPMD_ADDRESS`:
- On Focal, an `epmd` service exists and is activated, which uses
systemd's configuration to choose which interfaces to bind on, and
thus `ERL_EPMD_ADDRESS` is irrelevant.
- On Bionic (and Focal, due to a broken dependency from
`rabbitmq-server` to `epmd@` instead of `epmd`, which may lead to
the explicit `epmd` service losing a race), `epmd` is started by
`rabbitmq-server` when it does not detect a running instance.
Unfortunately, only `/etc/init.d/rabbitmq-server` would respects
`/etc/default/rabbitmq-server` -- and it defers the actual startup
to using systemd, which does not pass the environment variable
down. Thus, `ERL_EPMD_ADDRESS` is also irrelevant here.
We unfortunately cannot limit `epmd` to only listening on localhost,
due to a number of overlapping bugs and limitations:
- Manually starting `epmd` with `-address 127.0.0.1` silently fails
to start on hosts with IPv6 disabled, due to an Erlang bug ([1],
[2]).
- The dependencies of the systemd `rabbitmq-server` service can be
fixed to include the `epmd` service, and systemd can be made to
bind to `127.0.0.1:4369` and pass that socket to `epmd`, bypassing
the above bug. However, the startup of this service is not
guaranteed, because it races with other sources of `epmd` (see
below).
- Any process that runs `rabbitmqctl` results in `epmd` being started
if one is not currently running; these instances do not respect any
environment variables as to which addresses to bind on. This is
also triggered by `service rabbitmq-server status`, as well as
various Zulip cron jobs which inspect the rabbitmq queues. As
such, it is difficult-to-impossible to ensure that some other
`epmd` process will not win the race and open the port on all
interfaces.
Since the only known exposure from leaving port 4369 open is
information that rabbitmq is running on the host, and the complexity
of adjusting this to only bind on localhost is high, we remove the
setting which does not address the problem, and document that the port
is left open, and should be protected via system-level or
network-level firewalls.
[1]: https://bugs.launchpad.net/ubuntu/+source/erlang/+bug/1374109
[2]: https://github.com/erlang/otp/issues/4820
2021-12-07 21:13:47 +01:00
|
|
|
- Incoming port 4369 should be protected by a firewall to prevent
|
|
|
|
exposing `epmd`, an Erlang service which does not support binding
|
|
|
|
only to localhost. Leaving this exposed will allow unauthenticated
|
|
|
|
remote users to determine that the server is running RabbitMQ, and
|
|
|
|
on which port, though no further information is leaked.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Outgoing HTTP(S) access (ports 80 and 443) to the public Internet so
|
2020-10-15 11:43:44 +02:00
|
|
|
that Zulip can properly manage image and website previews and mobile
|
2021-08-20 21:53:28 +02:00
|
|
|
push notifications. Outgoing Internet access is not required if you
|
2020-10-15 11:43:44 +02:00
|
|
|
[disable those
|
2021-04-15 01:25:02 +02:00
|
|
|
features](https://zulip.com/help/allow-image-link-previews).
|
2021-08-20 21:45:39 +02:00
|
|
|
- Outgoing SMTP access (usually port 587) to your [SMTP
|
2022-02-24 00:17:21 +01:00
|
|
|
server](email.md) so that Zulip can send emails.
|
2021-08-20 21:45:39 +02:00
|
|
|
- A domain name (e.g. `zulip.example.com`) that your users will use to
|
2021-08-20 21:53:28 +02:00
|
|
|
access the Zulip server. In order to generate valid SSL
|
2019-12-13 01:30:22 +01:00
|
|
|
certificates [with Certbot][doc-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).
|
2021-08-20 21:45:39 +02:00
|
|
|
- Zulip supports [running behind a reverse proxy][reverse-proxy].
|
2022-01-22 15:29:19 +01:00
|
|
|
- Zulip configures [Smokescreen, an outgoing HTTP
|
2021-11-17 22:17:56 +01:00
|
|
|
proxy][smokescreen-proxy], to protect against [SSRF attacks][ssrf],
|
|
|
|
which prevents user from making the Zulip server make requests to
|
|
|
|
private resources. If your network has its own outgoing HTTP proxy,
|
|
|
|
Zulip supports using that instead.
|
2019-12-13 01:30:22 +01:00
|
|
|
|
2021-08-20 22:54:08 +02:00
|
|
|
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
2022-02-16 01:39:15 +01:00
|
|
|
[smokescreen-proxy]: deployment.md#customizing-the-outgoing-http-proxy
|
|
|
|
[reverse-proxy]: deployment.md#putting-the-zulip-application-behind-a-reverse-proxy
|
2021-09-01 00:15:31 +02:00
|
|
|
[email-mirror-code]: https://github.com/zulip/zulip/blob/main/zerver/management/commands/email_mirror.py
|
2016-08-25 00:19:10 +02:00
|
|
|
|
|
|
|
## Credentials needed
|
|
|
|
|
2020-08-11 01:47:54 +02:00
|
|
|
#### SSL certificate
|
2016-08-25 00:19:10 +02:00
|
|
|
|
2018-03-03 03:24:05 +01:00
|
|
|
Your Zulip server will need an SSL certificate for the domain name it
|
2021-08-20 21:53:28 +02:00
|
|
|
uses. For most Zulip servers, the recommended (and simplest) way to
|
2018-03-03 03:24:05 +01:00
|
|
|
get this is to just [use the `--certbot` option][doc-certbot] in the
|
|
|
|
Zulip installer, which will automatically get a certificate for you
|
|
|
|
and keep it renewed.
|
2016-07-28 01:38:02 +02:00
|
|
|
|
2018-03-03 03:24:05 +01:00
|
|
|
For test installations, an even simpler alternative is always
|
|
|
|
available: [the `--self-signed-cert` option][doc-self-signed] in the
|
|
|
|
installer.
|
|
|
|
|
|
|
|
If you'd rather acquire an SSL certificate another way, see our [SSL
|
2019-09-30 19:37:56 +02:00
|
|
|
certificate documentation](ssl-certificates.md).
|
2018-03-03 03:24:05 +01:00
|
|
|
|
2022-02-16 01:39:15 +01:00
|
|
|
[doc-certbot]: ssl-certificates.md#certbot-recommended
|
|
|
|
[doc-self-signed]: ssl-certificates.md#self-signed-certificate
|
2017-12-13 05:08:35 +01:00
|
|
|
|
2016-08-25 00:19:10 +02:00
|
|
|
#### Outgoing email
|
2016-07-28 01:38:02 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Outgoing email (SMTP) credentials that Zulip can use to send
|
2017-02-22 06:12:12 +01:00
|
|
|
outgoing emails to users (e.g. email address confirmation emails
|
2021-04-20 23:27:25 +02:00
|
|
|
during the signup process, message notification emails, password
|
2021-08-20 21:53:28 +02:00
|
|
|
reset, etc.). If you don't have an existing outgoing SMTP solution,
|
2017-02-22 06:12:12 +01:00
|
|
|
read about
|
2022-02-16 01:39:15 +01:00
|
|
|
[free outgoing SMTP options and options for prototyping](email.md#free-outgoing-email-services).
|
2016-07-12 21:35:25 +02:00
|
|
|
|
2016-07-28 01:38:02 +02:00
|
|
|
Once you have met these requirements, see [full instructions for installing
|
2022-02-24 00:17:21 +01:00
|
|
|
Zulip in production](install.md).
|
2019-02-12 01:09:58 +01:00
|
|
|
|
|
|
|
[trusty-eol]: https://wiki.ubuntu.com/Releases
|
2019-11-22 02:07:17 +01:00
|
|
|
|
|
|
|
## Scalability
|
|
|
|
|
2019-12-13 01:30:22 +01:00
|
|
|
This section details some basic guidelines for running a Zulip server
|
|
|
|
for larger organizations (especially >1000 users or 500+ daily active
|
2021-08-20 21:53:28 +02:00
|
|
|
users). Zulip's resource needs depend mainly on 3 parameters:
|
2021-08-20 22:54:08 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- daily active users (e.g. number of employees if everyone's an
|
2021-08-20 22:54:08 +02:00
|
|
|
employee)
|
2021-08-20 21:45:39 +02:00
|
|
|
- total user accounts (can be much larger)
|
|
|
|
- message volume.
|
2019-11-22 18:59:43 +01:00
|
|
|
|
|
|
|
In the following, we discuss a configuration with at most two types of
|
|
|
|
servers: application servers (running Django, Tornado, RabbitMQ,
|
2021-08-20 21:53:28 +02:00
|
|
|
Redis, Memcached, etc.) and database servers. Of the application
|
|
|
|
server services, Django dominates the resource requirements. One can
|
2019-11-22 18:59:43 +01:00
|
|
|
run every service on its own system (as
|
|
|
|
[docker-zulip](https://github.com/zulip/docker-zulip) does) but for
|
2021-08-20 21:53:28 +02:00
|
|
|
most use cases, there's little scalability benefit to doing so. See
|
2022-02-24 00:17:21 +01:00
|
|
|
[deployment options](deployment.md) for details on
|
2019-11-22 18:59:43 +01:00
|
|
|
installing Zulip with a dedicated database server.
|
|
|
|
|
2021-08-20 21:53:28 +02:00
|
|
|
- **Dedicated database**. For installations with hundreds of daily
|
2020-10-26 22:27:53 +01:00
|
|
|
active users, we recommend using a [remote PostgreSQL
|
2020-10-26 22:52:30 +01:00
|
|
|
database](postgresql.md), but it's not required.
|
2019-11-22 18:59:43 +01:00
|
|
|
|
2021-08-20 22:54:08 +02:00
|
|
|
- **RAM:** We recommended more RAM for larger installations:
|
|
|
|
|
2022-01-22 15:29:19 +01:00
|
|
|
- With 25+ daily active users, 4 GB of RAM.
|
|
|
|
- With 100+ daily active users, 8 GB of RAM.
|
|
|
|
- With 400+ daily active users, 16 GB of RAM for the Zulip
|
|
|
|
application server, plus 16 GB for the database.
|
|
|
|
- With 2000+ daily active users 32 GB of RAM, plus 32 GB for the
|
2021-08-20 22:54:08 +02:00
|
|
|
database.
|
|
|
|
- Roughly linear scaling beyond that.
|
2019-11-22 18:59:43 +01:00
|
|
|
|
2021-08-20 22:54:08 +02:00
|
|
|
- **CPU:** The Zulip application server's CPU usage is heavily
|
2019-11-22 18:59:43 +01:00
|
|
|
optimized due to extensive work on optimizing the performance of
|
2021-08-20 21:53:28 +02:00
|
|
|
requests for latency reasons. Because most servers with sufficient
|
2019-11-22 18:59:43 +01:00
|
|
|
RAM have sufficient CPU resources, CPU requirements are rarely an
|
2021-08-20 21:53:28 +02:00
|
|
|
issue. For larger installations with a dedicated database, we
|
2019-11-22 18:59:43 +01:00
|
|
|
recommend high-CPU instances for the application server and a
|
|
|
|
database-optimized (usually low CPU, high memory) instance for the
|
|
|
|
database.
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- **Disk for application server:** We recommend using [the S3 file
|
2021-08-20 21:53:28 +02:00
|
|
|
uploads backend][s3-uploads] to store uploaded files at scale. With
|
2022-01-22 15:29:19 +01:00
|
|
|
the S3 backend configuration, we recommend 50 GB of disk for the OS,
|
2021-08-20 21:53:28 +02:00
|
|
|
Zulip software, logs and scratch/free space. Disk needs when
|
2019-12-13 01:30:22 +01:00
|
|
|
storing uploads locally
|
2019-11-22 18:59:43 +01:00
|
|
|
|
2021-08-20 21:53:28 +02:00
|
|
|
- **Disk for database:** SSD disk is highly recommended. For
|
2022-01-22 15:29:19 +01:00
|
|
|
installations where most messages have <100 recipients, 10 GB per 1M
|
|
|
|
messages of history is sufficient plus 1 GB per 1000 users is
|
2021-08-20 21:53:28 +02:00
|
|
|
sufficient. If most messages are to public streams with 10K+ users
|
2022-01-22 15:29:19 +01:00
|
|
|
subscribed (like on chat.zulip.org), add 20 GB per (1000 user
|
2019-11-22 18:59:43 +01:00
|
|
|
accounts) per (1M messages to public streams).
|
|
|
|
|
2021-11-18 07:25:55 +01:00
|
|
|
- **Example:** When
|
2021-12-09 20:15:18 +01:00
|
|
|
[the Zulip development community](https://zulip.com/development-community/) server
|
2019-12-13 01:30:22 +01:00
|
|
|
had 12K user accounts (~300 daily actives) and 800K messages of
|
|
|
|
history (400K to public streams), it was a default configuration
|
2022-01-22 15:29:19 +01:00
|
|
|
single-server installation with 16 GB of RAM, 4 cores (essentially
|
|
|
|
always idle), and its database was using about 100 GB of disk.
|
2019-11-22 18:59:43 +01:00
|
|
|
|
postgresql: Support replication on PostgreSQL >= 11, document.
PostgreSQL 11 and below used a configuration file names
`recovery.conf` to manage replicas and standbys; support for this was
removed in PostgreSQL 12[1], and the configuration parameters were
moved into the main `postgresql.conf`.
Add `zulip.conf` settings for the primary server hostname and
replication username, so that the complete `postgresql.conf`
configuration on PostgreSQL 14 can continue to be managed, even when
replication is enabled. For consistency, also begin writing out the
`recovery.conf` for PostgreSQL 11 and below.
In PostgreSQL 12 configuration and later, the `wal_level =
hot_standby` setting is removed, as `hot_standby` is equivalent to
`replica`, which is the default value[2]. Similarly, the
`hot_standby = on` setting is also the default[3].
Documentation is added for these features, and the commentary on the
"Export and Import" page referencing files under `puppet/zulip_ops/`
is removed, as those files no longer have any replication-specific
configuration.
[1]: https://www.postgresql.org/docs/current/recovery-config.html
[2]: https://www.postgresql.org/docs/12/runtime-config-wal.html#GUC-WAL-LEVEL
[3]: https://www.postgresql.org/docs/12/runtime-config-replication.html#GUC-HOT-STANDBY
2021-11-20 00:33:41 +01:00
|
|
|
- **Disaster recovery:** One can easily run a warm spare application
|
|
|
|
server and a warm spare database (using [PostgreSQL warm standby
|
|
|
|
replicas][streaming-replication]). Make sure the warm spare
|
2019-11-22 18:59:43 +01:00
|
|
|
application server has copies of `/etc/zulip` and you're either
|
|
|
|
syncing `LOCAL_UPLOADS_DIR` or using the [S3 file uploads
|
|
|
|
backend][s3-uploads].
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- **Sharding:** Zulip releases do not fully support dividing Tornado
|
2019-11-22 18:59:43 +01:00
|
|
|
traffic for a single Zulip realm/organization between multiple
|
|
|
|
application servers, which is why we recommend a hot spare over
|
2021-08-20 21:53:28 +02:00
|
|
|
load-balancing. We don't have an easily deployed configuration for
|
2019-11-22 18:59:43 +01:00
|
|
|
load-balancing Tornado within a single organization, and as a result
|
|
|
|
can't currently offer this model outside of enterprise support
|
|
|
|
contracts.
|
2019-11-22 02:07:17 +01:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Zulip 2.0 and later supports running multiple Tornado servers
|
2019-12-13 01:30:22 +01:00
|
|
|
sharded by realm/organization, which is how we scale Zulip Cloud.
|
2020-05-05 15:52:32 +02:00
|
|
|
[Contact us][contact-support] for help implementing the sharding policy.
|
2019-11-22 02:07:17 +01:00
|
|
|
|
2019-11-22 18:59:43 +01:00
|
|
|
Scalability is an area of active development, so if you're unsure
|
|
|
|
whether Zulip is a fit for your organization or need further advice
|
2020-05-05 15:52:32 +02:00
|
|
|
[contact Zulip support][contact-support].
|
2019-11-22 18:59:43 +01:00
|
|
|
|
2021-02-13 07:24:34 +01:00
|
|
|
For readers interested in technical details around what features
|
|
|
|
impact Zulip's scalability, this [performance and scalability design
|
|
|
|
document](../subsystems/performance.md) may also be of interest.
|
|
|
|
|
2022-02-16 01:39:15 +01:00
|
|
|
[s3-uploads]: upload-backends.md#s3-backend-configuration
|
|
|
|
[streaming-replication]: deployment.md#postgresql-warm-standby
|
2020-05-05 15:52:32 +02:00
|
|
|
[contact-support]: https://zulip.com/help/contact-support
|