paint-brush
Tearing down Reddit’s iOS application - Insights on APIs, Performance, Security, and A/B Experimentsby@hackercm3ebf0le00003b7n7h2a5k7d

Tearing down Reddit’s iOS application - Insights on APIs, Performance, Security, and A/B Experiments

by November 26th, 2024
Read on Terminal Reader

Too Long; Didn't Read

My curiosity lead me to the analyse behind the scenes working of Reddit iOS app and revealed some good insights about Reddit APIs.
featured image - Tearing down Reddit’s iOS application - Insights on APIs, Performance, Security, and A/B Experiments
undefined HackerNoon profile picture

I found Reddit’s iOS app experience better than the web version, so I thought of checking how it loads data so fast. Here is the teardown of Reddit’s iOS app.


Here are some highlights:

  • It uses Token-based authentication.
  • It uses GraphQL APIs for almost everything from configuration & experiments to post info.
  • It monitors the performance of its API system as experienced by its users using an API named w3-reporting.
  • In most of the GraphQL API calls only the operation name is passed without variables, I am assuming they are using middleware to abstract the configuration of the variables from front-end. A backend service is filling in info based on the operation name.
  • Reddit uses Web Socket for the live comments feature.


Here is the detailed teardown of the API calls. I used Requestly’s Desktop App to intercept Reddit’s iOS app, setup instructions are provided here.

Technology Used

Reddit App is created with

  • Reddit’s iOS app uses GraphQL APIs to load all the content.
  • Token-based authentication is used for validating users.
  • Performance Monitoring by reporting the API performance at the user end.
  • Live commenting is supported using WebSocket.
  • Dynamic Configuration to remotely control app behaviour without deploying new versions.
  • Dynamic Experiments to remotely control experiments, not needing new deployment to change the status of an experiment.

Better UX with Preloading

The main question I had was how the app is performing so fast was answered upon checking FeedPostDetailsByIds API’s response. This API is called on the home screen with the ids of the posts shown and comes with detailed info that is shown after clicking the post. This preloading of the top posts helped in instantly showing the post details screen without any loader.


  • Preloading posts are shown on the feed.
  • The response time of the APIs is also very fast.

GraphQL APIs Security

GraphQL queries consist of the data and structure of the response needed. The operation name is generally optional. Most Reddit APIs have only operation names in the queries and variables are available only when there are on-screen variables/filters like feed with hot and latest post options.


This gives less control to frontend developers to make changes independently but more control over misuse of the APIs to fetch unnecessary data after all its user-facing API.

Remote Controlled Experiments

Running experiments on native iOS apps is difficult it needs re-deployments to enable or disable experiments, but Reddit has set-up the app in such a way that experiments can be controlled remotely. All the experiments are loaded in an API along with their values and statuses. The app automatically activates the variant of the experiment it assigned.

Flag-based Features Control

With so many users, experiments and features it's better to control them remotely. Reddit does a great job of controlling these features remotely.

GetAllDynamicConfigs API call as shown in Requestly


At every launch of the app, it will call a configuration API to load 400+ configuration variables. Based on these variables it shows different features and variants of the features.

Configs API response

Secret of Karmas

The API with the operation name GetTopKarmaSubreddits gets the list of top subreddits with karma points earned in each. This API reveals how many comments and post karma we have gained from our activity in each sub-reddit. I could never find this information inside Reddit’s web and mobile UI.


Karma for each Subreddit

Scope of Improvement

While reading the APIs to find what type of data it brings, I found SubredditFeedElements API loads the feed of the selected sub-reddit but with each post, it has a nested JSON of detailed sub-reddit information. This information is redundant and can be removed to reduce the network load of the API and further improve its performance.


Note: SubredditFeedElements API is now replaced by SubredditFeedSdui API and issue is fixed.

Use AI for Insights

I tried using ChatGPT to get some insights from the APIs. So created a file with all the APIs with their curl and their responses in it. Uploaded this file to a CustomGPT so that I can put any type of query. It gave some insights that were evident like what type of use an API might have and the structure of the response but it hallucinated a lot, most likely due to lots of APIs or I am no expert in prompting. Some of the insights given by AI:


  1. GetAllExperimentVariants API — Many experiments have specific "variant" names, including options like enabled, variant_1, control_model, and one_feed_ph_bridge_new_users. This segmentation suggests that Reddit is testing features on particular user segments to determine their impact. For example, the experiment d2x_avatar_in_comments_loggedin has two variants, loggedin, and loggedout, potentially testing the feature based on the user authentication state.
  2. GetAllExperimentVariants API — Experiments include hybrid_video_rollout_android_v2, active_sales, and gql_google_maps_integration, which point to a wide range of feature tests covering video functionality, ad placements, user interface enhancements, and third-party integrations
  3. GetAccountDetails API — The API response contains various fields detailing the user’s account status, such as isSubredditCreationAllowed, isNameEditable, isPasswordSet, and the user's moderator status. Additionally, it includes suspensionExpiresAt and isSuspended, which indicate if an account is currently suspended or restricted

List of APIs

There are the list of GraphQL APIs I studied to understand how Reddit works. There were some other APIs as well like authentication, reporting etc. I didn’t include them in this list.

Screen

GraphQL API
(operation name)

Description

Home

GetAllDynamicConfigs

Loads 400+ config parameters based on which different features of the app works. The configuration is in typical key value format along with type of the value which can be a JSON, float, string etc.


GetAllExperimentVariants

The Request contains information about the app and device to assign experiments meant for the device and app version. Response contains a list of all the experiments with id, experimentName, version & status.


GetAccount

Loads all the details of the logged in user.


HomeFeedSdui

Loads the first few posts with minimum details to show on homepage.


FeedPostDetailsByIds

Preloads the posts using ids with all the details, in case a user clicks on the post.


DiscoverBarRecommendations

Discover bar data.


UserPremiumSubscription

Data related to user premium subscription


GetUserAdEligibility

Gets the ad eligibility of the user and any preferences.


BadgeCounts

Information about the badges earned by the user.




Subreddit Page

SubredditChannels

Loads all the basic details about the community like description, icons, counters, allowed post types, and colours.


SubredditTaxonomyTopics

Loads the category of the community and a display text like if I load the community r/software it will show #20 in Software & Apps.


IsInvitePending

As the name suggests check for a pending invite, but not sure exactly which invite.


SubredditChannels

Loads the chat channels of the sub-reddit, I checked many subreddits but couldn’t find any.


BlockedRedditors

Brings data if user is blocked.


GetModerators

Gets the list of mods.


FetchStructuredStyleAndWidgets

This API brings info about style, rules and details of the community.


FetchRelatedCommunityRecommendations

This API brings related communities.


SubredditMuting

Checks if sub reddit is muted.


SubredditFeedElements

Loads the feed of sub-reddit. It takes the filters & layout options selected for the sub-reddit. Brings in all the details about posts to be displayed in feed.


PostInfoByIdComments

This request preloads the comments of the first post only.




Post Page

GetCustomEmojisStatus

This API was called with the sub-reddit id and loads the status of custom emojis on sub-reddit. Its not very clear about why this API is called, but I have seen it on many occasions. The response was isEnabled: false in all the cases it tested.


GetSubredditAchievementFlairsStatus

Similar to emoji status it takes sub-reddit id and gets a response as isEnabled: false . The purpose of this is not clear to me.


PostInfoByIdComments

This API is used to load comments of the post by using post id passed in the request.


CommentsPageAds

Loads the ad just above the comments.




Profile Page

RedditorByName

Loads the profile details of the logged in user.


PostSetSettings

Number of posts to load.


GetTopKarmaSubreddits

Get the list of top subreddits with karma points on each community, this API reveals about how many comment and post karma we have earned from our activity in each sub-reddit.


UserProfileFeed

The feed for user profile containing comments and posts.


UserPublicTrophies

List of achievements and trophies earned by the user name passed in request with id, name and image to be displayed.


TippingProfileMigrated

Details about the tipping profile, haven’t used this feature much. It showed 0 balance on my profile 😄.

Conclusion

I would like to make couple of points in conclusion of this tear down experiment.

  • Reddit’s APIs are not very fast instead they use preloading to give a better user experience.
  • APIs work is never complete, even Reddit’s engineer have some work to do to further improve it.
  • Keeping app & experiment configurations remotely can give a good control over user experience.
  • Requestly’s engineers did a great job in showing operation name with each GraphQL Request, making life of devs much easier.