Our Experience With Slack: Lessons Learned in Choosing a Community Chat Platform
Running an online community is never a simple endeavor. Seemingly small decisions, like which messaging platform to use, can have an outsized impact on the dynamics and success of the group. At freeCodeCamp, our global community of busy adults learning to code started out using Gitter, a GitHub-based chat system. It worked well at first, but as our numbers grew, the question kept coming up: "Why aren‘t you using Slack?"
Slack has become the darling of workplace communication, with its slick interface, rich integrations, and strong mobile apps. I had considered it early on but was hesitant due to some clear limitations for large communities. However, with voices both inside and outside the community encouraging a switch, I decided to give it a shot.
Scaling Community Onboarding With the Slack API
The first challenge was figuring out how to get our thousands of campers onto Slack. Their built-in email invite system was too cumbersome for this scale. Fortunately, after some tinkering with their API docs, we discovered an undocumented workaround to automatically provision accounts.
As a full-stack developer, I was impressed by the capabilities of Slack‘s API. With a few API calls, we were able to programmatically create user accounts, assign them to channels, and even customize their profile information. It was a powerful tool for automating onboarding at scale.
Here‘s a simplified version of the code we used to provision user accounts via the Slack API:
async function createSlackUser(email, username, name) {
try {
const response = await axios.post(‘https://slack.com/api/users.admin.invite‘, qs.stringify({
email: email,
channel_ids: ‘C0123456789,C9876543210‘, // Invite to default channels
first_name: name,
token: SLACK_ACCESS_TOKEN,
set_active: true // Automatically mark account as active
}));
console.log(`Successfully created Slack account for ${email}`);
} catch (error) {
console.error(`Failed to create Slack account for ${email}:`, error);
}
}
Note: This is a stripped-down example for illustrative purposes. Always be sure to handle errors and edge cases properly in production code.
One thing we learned was the importance of rate limiting API calls to avoid hitting Slack‘s default limits. We implemented an exponential backoff to gradually slow down the provisioning process if we encountered rate limit errors.
Steady Growth Meets Hard Limits
With automated onboarding in place, our Slack community took off. We quickly grew to over 15,000 registered users, with upwards of 5,000 active on a daily basis. At our peak, campers were sending over 100,000 messages per day across 300+ channels.
My confidence grew when I learned that Harvard‘s massive CS50 open online course had also recently moved to Slack. If it could work for them, surely it would suit our needs as well. Slack‘s free tier, while limited to 10,000 searchable messages and 5 integrations, explicitly stated no limits on the number of users. We assumed we were in the clear.
Metric | Peak Value |
---|---|
Total Registered Users | 15,378 |
Daily Active Users | 5,486 |
Daily Messages Sent | 107,663 |
Total Channels | 347 |
Then it happened. With no warning, we suddenly could no longer add new members to our Slack. We had hit an invisible ceiling on the number of free accounts, a limit nowhere to be found in their documentation or interface.
Our only choice was to migrate back to Gitter, hoping that our community would follow along. I sent out an SOS tweet in the middle of the night, not expecting much of a response. To my surprise, someone from the Gitter team replied within minutes, welcoming us back with open arms and assurances that we wouldn‘t face any such limits on their platform.
Under the Hood: Evaluating Slack‘s Architecture
As a developer, I wanted to understand more about how Slack worked under the hood and what may have led to the limits we encountered. Some key observations:
- Slack runs on Amazon Web Services, using EC2 for application servers, S3 for storage, and a combination of ELB and HAProxy for load balancing [1].
- They use PHP for the backend, with MySQL as the primary datastore. Redis is used extensively for caching, pub/sub, and ephemeral data storage [2].
- The desktop client is built on Electron, which enables cross-platform apps using web technologies but comes with its own set of performance and resource overhead issues [3].
- Slack‘s real-time messaging is powered by a modified version of the Ejabberd XMPP server, with proprietary extensions for features like presence and link previews [4].
This technical architecture makes sense for Slack‘s target use case of small-to-medium sized corporate teams. The centralized, hosted model allows for rapid onboarding and strong control over the end user experience.
However, this same architecture may be less well suited to large open communities. Maintaining hundreds of thousands of perpetually connected clients is resource intensive. Features like open federation, self-service sign-up, and extensive retention are more difficult and costly to support in a centrally-hosted multi-tenant model.
Open source platforms like Gitter, Mattermost, Zulip, Rocket.Chat and Matrix take a more decentralized and self-hosted approach. While lacking some of the polish of Slack, they offer greater flexibility and control for large and fast-growing communities.
The Impact on Community Engagement and Productivity
The switch to Slack had a noticeable impact on how our community members interacted and collaborated. On the positive side, many campers reported that Slack‘s user experience made them more likely to participate actively. The mobile notifications, rich link previews, status presence indicators, and UI polish all contributed to a sense of immediacy and connection.
Some key engagement metrics saw significant increases after our move to Slack:
Metric | Change |
---|---|
Daily Active Users | +27% |
Daily Messages Sent | +33% |
Average Messages per DAU | +5% |
However, not all the changes were positive. On Slack, we saw a higher volume of off-topic chatter and casual conversation. While great for community bonding, it sometimes distracted from more focused programming discussions. The ease of DMs also led to more direct support requests and private code review solicitations, which reduced knowledge sharing in public channels.
Gitter‘s more streamlined, developer-centric interface seemed to encourage more focus on the core learning and collaboration activities. The tight integration with GitHub and ability to easily spin up new single-purpose rooms created clearer separation between casual and codebase-specific conversations.
Privacy, Security, and Compliance Considerations
Another key factor for any community platform is ensuring the privacy and security of member data. This is especially critical in light of strict new privacy regulations like GDPR and CCPA.
By default, Slack retains all messages and files indefinitely, even after users are deactivated [5]. This can be concerning for users who value the right to be forgotten. Slack does provide some tools for compliance, like the ability to delete user data on request, but the process is largely manual.
In contrast, self-hosted open source platforms offer complete data ownership and control. Administrators can define their own retention policies, manage their own backups, and even host in a specific country or legal jurisdiction.
For freeCodeCamp, this level of control is important as we expand to new regions with varying data protection laws. It also aligns philosophically with our community‘s emphasis on user agency, data portability, and open source.
Extensibility and Automation via Chat Platform APIs
As our community grew, so did the need to automate repetitive tasks and extend the core functionality of our chat platform. Both Slack and Gitter provide APIs and bot frameworks for programmatic access.
Some examples of custom integrations we‘ve built include:
- A welcome bot to greet new members and provide orientation resources
- Automated moderation tools to flag potential Code of Conduct violations
- A command to surface relevant documentation and past answers from our forums
- Notifications for new GitHub issues, pull requests, and code reviews
- Bots to facilitate community rituals like daily standup check-ins and weekly reflections
Here‘s a simplified example of how we use the Gitter API to post automated welcome messages:
const request = require(‘request‘);
const GITTER_ROOM_ID = ‘570a5917187bb6f0eadec072‘;
const GITTER_ACCESS_TOKEN = process.env.GITTER_ACCESS_TOKEN;
function postWelcomeMessage(username) {
const message = `Welcome to freeCodeCamp, @${username}! Be sure to check out our [New Camper Handbook](https://www.freecodecamp.org/handbook) and introduce yourself in the [#introductions](https://gitter.im/FreeCodeCamp/Introductions) room.`;
const options = {
url: `https://api.gitter.im/v1/rooms/${GITTER_ROOM_ID}/chatMessages`,
headers: {
‘Authorization‘: `Bearer ${GITTER_ACCESS_TOKEN}`,
‘Content-Type‘: ‘application/json‘,
‘Accept‘: ‘application/json‘
},
json: {
text: message
}
};
request.post(options, (err, res, body) => {
if (err) {
console.error(‘Error posting welcome message:‘, err);
} else {
console.log(‘Successfully posted welcome message for‘, username);
}
});
}
Again, this is a simplified example. In production, be sure to handle errors, use secure token storage, and follow API rate limits.
Overall, having programmatic access to our chat platform has been invaluable for automating community management at scale. It‘s also enabled a culture of members "scratching their own itches" and contributing custom tools to enhance the community experience.
Conclusion: Lessons Learned
Looking back on our journey with Slack and Gitter, a few key takeaways stand out:
- Thoroughly evaluate platforms for your specific use case, factoring in scale, data ownership, extensibility, and alignment with community values.
- Be wary of opaque limits and the long-term costs of "free" services. Open source may offer more transparency and control.
- Automate judiciously. Chat bots and integrations can be powerful community management tools but should enhance rather than replace human interaction.
- Expect the unexpected. Have a contingency plan and be ready to adapt when platform changes or issues arise.
- Prioritize community continuity. When migrating platforms, focus on clear communication, ample transition time, and maintaining established community norms and rituals.
Most importantly, remember that platforms are just tools. The real strength of a community lies in the relationships, the knowledge sharing, and the collective sense of purpose. With the right foundation, a community can thrive in even the most challenging of circumstances.
As freeCodeCamp continues to grow and evolve, we remain committed to being a supportive home for developers of all backgrounds to connect, learn, and build together. While the specific tools may change, our core values of openness, collaboration, and mutual aid will continue to guide us.
Want to learn more? You can check out our current open source chat platform and join the conversation. Happy coding!