Using Real-time Messaging at Peloton

By Douglas Crossley and Chris Mohr

As our user base at Peloton continues to grow we’ve found some interesting opportunities to connect members to each other. We think that creating more opportunities for shared, real-time workout experiences is an important initiative and something we wanted to invest in. The first large feature based around this goal was something we called Working Out Now, which involved letting members know in real-time that another member they had followed on our platform was currently working out. To support this, we wanted a mechanism that could easily notify members anywhere in the product. We wanted it to be minimally invasive while still providing detailed information when needed.

Working Out Now Dialog

Real-Time Messaging Integration

We were already using PubNub to send real-time updates for our user activity feed, which shows members their friends’ activity. We decided to continue using PubNub for our real-time messaging and simply expand on what we had in place.

For each member we create a PubNub channel that their device subscribes to upon login. Whenever we need to send a real-time update to that member, we publish a message on that member’s channel. Each message has a type which we use to identify the schema of the payload. This allows us to easily create and consume new messages types.

On the client side, we encapsulate the ability to connect to PubNub and receive messages in our Messaging Service, which can easily be injected throughout the app for use. This Service exposes a Rx Observable that supports filtering the message stream by type. This gives clients a simple way to only get messages they care about and know how to consume.

Know When Your Friends Are Working Out

In order to know which of a member’s friends are currently working out, we need to know every time one of those members joins or leaves a workout. We defined two types of messages: “Someone you follow joined a workout” and “Someone you follow left a workout”. Whenever a member joins or leaves a workout, the Peloton API publishes a message to the PubNub channel of each of the member’s followers.

After defining these message, we hooked up the client to receive them in our bottom navigation component. We decided to build a cache that would update every time we received one of these messages from the server and then request additional information as needed. This worked well while a member was on their Bike or Tread, but we still needed a way to know who was in a workout when the member first started their session.

Messaging Data Flow

We created a new API endpoint that allowed us retrieve all the data for a member’s followers that we could leverage when our cache was stale or needed to be initialized. There was also a risk that the client’s local list of friends who were working out got out of date for a number of reasons. Instead of the client incrementally updating their local list, they request the full list of friends in classes each time they receive a message. Once the client has this information we use it render our Working Out Now dialog that members see when clicking on a notification.


As we added more types of messages that were used by different parts of the app, it became more important to document the schema of these messages. We use an OpenAPI specification to document the schema of our REST API and applied this same pattern to real-time messages by treating them like endpoints. This allowed for all client teams to easily consume any new messages that were added and understand how they could be used.

After allowing members to see which classes their friends were in, we built on top of this by allowing them to see their friends while they were in any class, including On Demand classes. We were then able to work with our Leaderboard team to provide an experience that better connected members to friends in class as well. This real-time messaging infrastructure gives us a base to expand upon for new features in the future.




The official Blog for Engineering @ Peloton

Recommended from Medium

AWS Joins CNCF, Asserts its Commitment to Technology Standards — Zerone Consulting

Amazon web services

Behind the Scenes: Creating a New Phoenix LiveView Application

Make objects rotate around the head in Spark AR

Make objects rotate around the head in Spark AR

Installing Kubernetes Cluster using Containerd on Mac Book Pro

What is new in Android Studio 3.6

How I Created My Own ‘’ site for Free

Automate your test pipeline and infrastructure life cycle using Oracle Developer Cloud

Notorious C++ : Array

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Peloton Engineering

Peloton Engineering

More from Medium

Using Secrets in Circle Ci and Local

DynamoDB Gotchas

How to Fix React Native JVM out of Memory Once & For All

Redux-Saga UnitTesting