Migrate from Slack to Zulip

Moving a Slack workspace to self-hosted Zulip, what the importer carries across, how channels become streams and topics, and how the export plan decides what comes along.

On this page

Migrate from Slack to Zulip: what the move involves

Moving a Slack workspace to self-hosted Zulip is a data and configuration project more than a software install. The export plan and the channel mapping decide most of the outcome: which conversations come across, how they land in Zulip, and whether users can find their history after cutover. Standing up the Zulip server is usually the smallest part of the work, so plan the migration around the export and the mapping first. The work is normally run by an internal platform or IT team, often with an implementation partner who handles server build, identity integration and the import runs. Zulip's Slack importer is documented in the Zulip help center, which gives a supported starting point, but the import still needs a test workspace, a review of the results and a decision on what to leave behind. Confirm with Zulip's current documentation which Slack export types its importer accepts before you request the export from Slack, because the export is the input you cannot easily change later.

Effort and risk depend on three things your team should check early. First, confirm which Slack plan you are on and whether an approved export includes private channels and direct messages, since public channel data is not enough for most regulated teams. Second, decide how each Slack channel becomes a Zulip stream and how topics will be used, because Zulip's threading model differs from Slack's and a poor mapping makes history hard to read. Third, inventory integrations, bots and user groups now, since a Slack export does not carry them and they must be rebuilt or retired. Before cutover, run the import into a staging realm, have a sample of users check their conversations and identities, and agree on a freeze date for Slack posting. Ask any implementation partner to put the import steps, the mapping decisions and the rollback plan in writing before work starts, so the team can review what will and will not move.

Which Slack capabilities map cleanly to Zulip

This table maps each Slack capability in a migration to its nearest Zulip equivalent and marks it clean, needs rework or gap. Read the status as the amount of planning needed before cutover, not as a verdict on either product. The main takeaway is that identity and directory settings carry over well, while message structure, private history, files and integrations need decisions and checks in your own environment.

Slack capabilityZulip equivalentStatus
Public channelsStreams, with channel membership and archive state to confirm after importClean
ThreadsTopics, which group messages by subject, so replies may need restructuring for readersNeeds rework
Private channelsPrivate streams, but only if the Slack export plan included them (Business+ or Enterprise)Needs rework
Direct messages and group DMsDirect messages and group direct messages, only if the export plan included themNeeds rework
Files and uploadsUploads, but Free exports carry file links, so confirm what Zulip imports and re-uploadsNeeds rework
Users and profilesImported user accounts, with email matching and deactivated accounts to check before cutoverClean
SSOSAML with IdP-initiated SSO and Single Logout, documented for Keycloak and AuthentikClean
Directory sync and provisioningLDAP with Active Directory data sync and SCIM, both in production documentationClean
Slack apps, huddles and Slack ConnectNo equivalent confirmed in our sources; check Zulip documentation for each before planningGap

What the Slack export carries and what you rebuild

The Slack export sets the ceiling for what reaches Zulip, and the export plan decides how much of that ceiling you get. Each card below covers one part of the gap between what the importer brings across and what your team still has to recreate, account by account and integration by integration.

Public channel messages on every plan

Every Slack plan can export messages and file links from public channels, so this is the baseline your Zulip history can rely on regardless of your subscription. Check which public channels exist, their date ranges and whether any were archived, because the export only reflects what Slack still holds. Confirm with the Zulip help center which message types the Slack importer converts, including threads and edits.

Private channels and DMs need Business+

Exporting private channels and direct messages requires Business+ or Enterprise, and custom exports by member or conversation are Enterprise-only. If your Slack plan is lower, private conversations will not reach Zulip through the documented path, so decide early whether that history matters for compliance or continuity. Request the approved export before planning the cutover, because the approval process is controlled by Slack and can take time you do not control.

File links rather than file contents

The Slack export carries file links for attachments rather than the files themselves, so the bytes stay on Slack's side unless you download them separately. Inventory the files your teams rely on, especially those referenced in old threads, and decide whether to fetch them before Slack access ends. Confirm with Zulip how imported attachment links behave once your Slack workspace is no longer available.

Re-map Slack users to Zulip accounts

Slack user IDs do not map to Zulip accounts automatically, so you need a list linking each Slack member to the email address and identity your directory uses. Plan to provision these accounts through SAML or LDAP, including Active Directory, so that Zulip logins match the identity provider your staff already use. Decide how to handle former employees, bots and guest accounts before import, because each one changes the user list you load.

Integrations, bots and apps need rebuilding

Slack apps, custom bots, slash commands and incoming webhooks do not come across through the import, so every workflow that posted into Slack needs a new home in Zulip. Build an inventory from the Slack admin pages and from the teams that own each integration, then decide which ones to re-create with Zulip's bot and webhook tooling and which to retire. Test each rebuilt integration against a staging server before the cutover date.

Confirm the importer's exact coverage

The Zulip importer documents its own list of supported Slack data, and that list decides what you must recreate by hand. Read the import guide closely, then run a test import of a sample export into a staging realm and compare the results against your Slack channels. Record every gap in writing so that stakeholders sign off on what is missing before the cutover.

How Slack channels map to Zulip streams and topics

Zulip organizes conversation in two levels: streams hold conversations, and each stream is divided into topics, which are labeled threads. A Slack channel does not map cleanly onto this model. A busy channel may hold dozens of unrelated discussions in one flat timeline, and Slack threads hang off individual messages rather than carrying a name. Before any import runs, the team has to decide which Slack channels become streams, which ones merge, and which long threads should become named topics. Make these decisions during the inventory step, record them in a shared mapping sheet, and have channel owners sign off. Changing the mapping after the import means reworking names by hand.

Three patterns cover most cases. The simplest is one stream per Slack channel, which keeps the migration legible to people who know the old workspace. Related small channels, such as several project or regional channels with few messages each, can be grouped into one stream and separated by topic. The third pattern uses topics to replace long Slack threads: a recurring incident or release channel becomes one stream, with each incident or release as a topic. Name streams after the subject, not the team, and keep topic names short and stable, because asynchronous readers scan topic lists rather than timelines. Confirm in a test import how the Slack importer assigns topics to imported threads, since the result determines how much manual renaming follows.

The mapping also changes how people read. In Slack, a reader who was away scrolls the channel and hopes the relevant thread is visible. In Zulip, a reader checks the streams they follow and then the topics with unread messages, so a well-named topic is a better summary than a long channel. Consider which streams need to be narrow and which need to be broad, and whether private Slack channels become invite-only Zulip streams with the same membership. Ask the owners of high-traffic channels to review the proposed topic structure with a sample of real messages before cutover.

The migration sequence from inventory to decommission

This sequence moves a Slack workspace to self-hosted Zulip in five controlled phases, so each team confirms what arrived before it stops relying on Slack. Each phase closes with a written output that the next phase depends on.

  1. Inventory channels, members, integrations and retention needs

    Start by listing every public and private channel, every direct message group your organization is allowed to export, every member and guest account, and every app, webhook and bot connected to Slack. Record which Slack plan the workspace is on, because the plan decides whether private channels and DMs can be exported at all. Compliance owners should state retention and legal hold obligations in writing at this stage. The output is a channel-to-stream map draft, an integration inventory and a signed retention requirements note. Confirm the export scope with your Slack administrator before anything else moves.

  2. Run a pilot import into a staging Zulip server

    Build a staging Zulip server in your own infrastructure, using the self-hosting options Zulip documents, and import a representative export through Zulip's Slack importer. Use a copy of the export that includes at least one private channel, a thread-heavy channel and a channel with file attachments, so edge cases surface early. Compare the imported streams, topics, users and files against the channel-to-stream map from the first step. The output is a validated import report with every mismatch logged and an owner assigned to each open item.

  3. Map Slack channels to Zulip streams and topics

    Decide how each Slack channel becomes a Zulip stream, and how threads and conversational sub-topics become Zulip topics. Zulip threads sit inside streams, so channels with very broad scope may need splitting or merging, and this decision belongs to the team owners rather than the migration engineer alone. Set stream privacy and membership to match the Slack channels they replace, and review who can administer each stream. The output is a signed stream design document that lists every stream, its visibility, its members and its owner.

  4. Run Zulip and Slack in parallel

    Open the production Zulip server to pilot teams while Slack stays fully available. Teams work in both tools for an agreed period, and the migration lead tracks which conversations happen where, plus any messages that still rely on Slack-only apps or workflows. Rebuild or replace the integrations from the inventory during this phase, and check that alerts and bots reach the right Zulip streams. The output is a parallel-run log with open issues, a list of rebuilt integrations and a sign-off from each pilot team lead that their daily work runs in Zulip.

  5. Cut over on a defined date and redirect new messages

    Set a cutover date in writing and announce it to every member, with instructions on where new conversations should start. On that date, post a final notice in each Slack channel that points to the matching Zulip stream, restrict posting in Slack where your plan and admin settings allow it, and freeze the final import run so no history is missed. Confirm that login, notifications and admin access work for every user group. The output is a signed-off cutover checklist that records the date, the final import outcome and the owner of each channel redirect.

  6. Decommission Slack access after the retention period

    Keep Slack readable for an agreed retention period so people can look up older messages, and keep your own exported copy under the retention policy from the first step. When that period ends, remove remaining Slack members, revoke connected app tokens and cancel or downgrade the subscription according to the contract terms. Keep the final export and the signed cutover checklist in your records system. The output is a decommission record that confirms access removal, token revocation, the archived export location and the date the Slack workspace was closed to members.

What drives the cost and duration of the move

This table lists the main drivers of effort and cost when moving a Slack workspace to self-hosted Zulip, and separates one-time migration work from recurring hosting and support. Read each row as a question to answer in your own environment before asking for a quote. The main takeaway is that the Slack export plan and the identity design usually matter more to the schedule than the raw message volume.

DriverWhy it changes cost or effortHow to keep it down
Export plan and approval lead timePrivate channels and DMs only come out of a Business+ or Enterprise export, and that request needs approval from Slack before anyone can start the importConfirm your Slack plan and submit the export request early, and agree in writing which conversations are in scope
Workspace size and channel countMore channels, members and files mean more mapping decisions, more import batches and more verification, even though Zulip's importer handles the bulk transferArchive dead channels before export and decide the stream and topic mapping per channel group, not one channel at a time
SAML or LDAP identity mappingMatching Slack accounts to Zulip users by email and linking them to your identity provider adds design and testing work before the first importSettle the identity source, email addresses and account owners before export, and test login with a pilot group
Integrations and bots to rebuildSlack apps, webhooks and slash commands are not carried into Zulip, so each one needs an inventory, a replacement and a testList every integration in Slack, mark which ones still matter and rebuild only those through Zulip's bot and webhook options
Retention and compliance requirementsLegal hold, retention periods and audit exports must be designed on the Zulip side and confirmed against what the Slack export containsWrite the retention rules and evidence list first, then check each against the export output and your own Zulip configuration
Zulip hosting and support choiceYour team runs the server, backups and upgrades, or pays for a support plan; the Zulip plans page lists a Basic plan at $3.50 per user per month billed monthly and a Business plan at $6.67 per user per month billed annually (Zulip plans page)Compare the free self-hosted Community plan with paid support tiers, and count mobile push notification users, which the Community plan limits to 10 for most organizations
One-time migration workCovers planning, the export and import runs, mapping review, pilot testing, cutover and user communication, all priced in the written scopeAsk for fixed deliverables per phase, with a named list of conversations and users included
Recurring hosting, upgrades and supportServers, storage, backups, Zulip version upgrades and any support plan continue after cutover and scale with user countAsk for an upgrade calendar and a clear split of which tasks the client and the provider each own

What usually goes wrong with Slack to Zulip moves

Most Slack to Zulip problems start before any data moves: the export is narrower than the team expects, identities do not line up, or channels are remapped without anyone explaining the new model. The cards below name the risks that recur and the checks that catch them while there is still time to adjust.

Export scope discovered too late

Private channels and DMs are often missing from the first export because the workspace plan decides what can be exported. Slack's export help states that private channels and direct messages need a Business+ or Enterprise plan, and Enterprise is needed for custom exports by member or conversation. Confirm the plan, submit the export request early, and check that the file contains the conversations you expect before the migration project is scheduled.

Missing private history

Teams often assume that old messages will be available in Slack and carry across. On Slack's Free plan, history older than one year is permanently deleted, so content that a team expects to migrate may already be gone. Ask owners of private channels which history they need, record what is unavailable, and tell stakeholders before cutover so the gap is a decision rather than a surprise.

User identities that do not match

Zulip matches imported users to accounts by email address, so people who use different addresses in Slack and in your identity provider can end up as duplicates or orphaned messages. Build a mapping table from the Slack export to your directory before the import, and check a sample of users, bots and former employees. Plan how SAML or LDAP accounts will be created so that imported authors link to the correct people.

Topic mapping that confuses readers

Zulip places each message in a stream and a topic, so a Slack channel with many threads becomes one stream with many topics. Without a naming convention, topics titled with dates or single words make history hard to follow for new readers. Decide in a pilot how Slack channels become streams, how threads are named, and which channels are archived instead of imported, then review a sample of converted conversations with the people who use them.

Integrations silently stopping

Slack exports leave bots, apps and webhooks behind, so alerts and workflows that depended on them stop without an error at the moment of cutover. Inventory every integration that posts into Slack, note the owner and the schedule, and rebuild each one against Zulip's incoming webhook or API before the old Slack feed is switched off. Assign someone to watch for missed alerts during the first weeks after cutover.

Mobile push limits on the free plan

The free self-hosted Community plan includes all features, but mobile push notifications are limited to 10 users for most organizations. Teams that move more people than this will see notifications stop for the rest unless they pay for a Basic plan or higher. Before choosing the free plan, count the users who need mobile notifications, and check the current limits and pricing on Zulip's plans page with the vendor.

How the move differs by team size and starting point

A small team on Slack Free usually has a short, informal history and few administrative controls to carry over. The main scope question is what history is still visible: Slack Free keeps 90 days of messages and file history, and content older than one year is permanently deleted, so anything the team wants to keep should be exported before it ages out. Identity is simple, since local accounts or a single shared sign-in method are often enough, and cutover can be a short, announced switch after a trial import.

  • Export early: Public channel content is available on every Slack plan, but Free workspaces cannot export private channels or direct messages, so decide now which history is worth keeping.
  • Keep identity simple: Set up Zulip accounts with the sign-in method the team already uses, and add SAML or LDAP only if they are actually needed.
  • Run one trial import: Import the export into a test realm first, check how channels became streams and topics, and confirm that member accounts matched.
  • Plan the cutover window: A small team can usually switch in one announced step, with Slack kept read-only for reference.
  • Check the mobile notification limit: Zulip's free self-hosted plan limits mobile push notifications to 10 users for most organizations, so confirm the team size against that limit.

Confirm with Zulip's plans page which features and notification limits apply to your team size before you commit to a rollout date.

Questions buyers ask before moving from Slack to Zulip

How much effort does a Slack to Zulip migration take?

The effort depends mostly on the size and age of the export, how many channels need to become streams, and how much integration work sits behind the workspace. Zulip's documented Slack importer moves the workspace data, but the team still has to review the result, decide how channels map to streams and topics, and confirm which users were matched. Ask any implementation partner for a written breakdown of these activities before agreeing a scope, because each one adds a distinct amount of work. Your own inventory of channels, users and integrations is the input that sets the effort.

How long does a Slack to Zulip cutover take?

The timeline is set by how many workspaces and channels you move, how much history you keep, how long your staff need to learn topic-based threading, and how many integrations must be rebuilt before cutover. No duration is fixed by the Zulip documentation, so treat any number you see from a vendor or partner as a claim to verify against your own inventory. A practical plan runs a test import on a copy of the export, reviews the results with a pilot group, and only then schedules the production import and the switch of users. Ask for milestones and dependencies in writing.

Do private channels and direct messages come across from Slack?

Whether they come across depends on the Slack plan that produced the export. Every Slack plan can export public channels, but private channels and direct messages require a Business+ or Enterprise plan, and custom exports by member or conversation are limited to Enterprise. If your export lacks these conversations, Zulip cannot import them because they were never provided. Confirm the export scope with your Slack administrator before the project starts, and check the Zulip import guide for the exact data types the importer handles.

What does our internal team need to supply for the migration?

The internal team supplies the decisions and access that only your organization can give. That includes a Slack administrator who can request and deliver the export, a named owner for the channel-to-stream mapping, people who can confirm which users map to which accounts, and an identity contact if you plan to use SAML or LDAP with Zulip. Your team also needs to name who approves the cutover date and who answers questions from staff during the first weeks. Ask any partner to list these inputs in the written scope so the dependency is visible.

Can our own IT team run the Slack to Zulip migration without a partner?

Yes, an experienced platform team can run it, provided it owns the Zulip server, has time for testing, and accepts the operational work that comes with self-hosting. Zulip is licensed under Apache 2.0 and its self-hosted server has the same features as the cloud version, so there is no feature gate to clear. The main risks for an in-house team are underestimating the review of imported data, skipping a pilot, and leaving integrations unplanned. A partner can take on any of these steps under a fixed scope, and the choice is a question of internal capacity and skills.

How do Slack and Zulip run side by side during cutover?

Most teams keep Slack read-only or active for a defined period while Zulip receives the imported history and a pilot group starts working there. Clear rules matter more than the tooling: publish which tool is the system of record for each team, set a date after which new messages stay in Zulip, and tell staff where to find older history. Zulip's documentation covers the import itself, so the coexistence plan is a process you design and test. Ask for a written rollback path in case the pilot reveals a blocking problem.

What happens to Slack integrations, bots and webhooks after the move?

Slack exports carry channel and message data but do not rebuild integrations, so bots, apps and webhooks must be inventoried and recreated or replaced in Zulip. Start by listing every Slack app, its owner, the channels it posts to and the business process it supports. Then decide, for each one, whether Zulip's own integrations, a webhook, or an automation tool covers the need. Some integrations will be retired rather than rebuilt, and that decision should be documented before cutover so no workflow fails silently.

How DeployOpen scopes and runs the migration

DeployOpen is a Chainscore Labs company that plans, implements, integrates, hardens, backs up and documents self-hosted open-source platforms inside your own infrastructure, including your cloud accounts, data centers or air-gapped networks. For a Slack to Zulip move, that work covers the Zulip server itself, the identity link to your directory, the import runs, the Slack channel-to-stream mapping decisions, the backup regime and the written runbook your admins will use after handover. The scope is shaped by facts you need to gather first: which Slack plan you are on, whether your export includes private channels and direct messages, how many users and streams you will bring across, and which bots and integrations must be rebuilt, since Zulip's documented Slack import does not carry those over.

Most engagements are fixed-scope. Before work starts, scope, deliverables and timelines are agreed in writing, so you know what is included and what is out. A written scope for this migration typically lists the target environment, the Zulip version to deploy, the authentication method (SAML, LDAP or SCIM, as your identity setup requires), the import test passes and sign-off criteria, the cutover window, the period in which Slack stays readable for reference, and who on your side approves the export request and the mapping. A quote follows from that written scope. Ask for it to show costs by component: infrastructure you pay for directly, DeployOpen's implementation effort, any testing or hardening, and the recurring items such as Zulip plan fees if you choose a paid tier for mobile push notifications or support. Ask us to state which items are one-time and which recur.

Ongoing support, version upgrades and continuous testing are available as retainers after the initial scope is delivered. Zulip publishes new server releases on a regular cadence, so a retainer is the natural place to agree who applies upgrades, who tests them against your SSO and backup jobs, and how quickly security fixes are rolled out. DeployOpen does not issue audit reports, attestations or certifications. If your organization needs evidence for a compliance assessment, DeployOpen can prepare the configuration, logs and runbooks that an independent auditor will review, and you should confirm the assessment requirements with that auditor before scope is signed.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.