В июле этого года компания Meta* выпустила своё новое мобильное приложение Threads* — сервис микроблоггинга, ставший новым конкурентом X (бывшего Twitter). В первые пять дней после выпуска приложение скачали больше ста миллионов раз — новый рекорд для компании. Предыдущий рекорд Meta* в установке нового приложения за первые пять дней был равен одному миллиону. Вот как выглядит кривая роста для количества пользователей:

Рост приложения Threads* за первую неделю. Так как в момент выпуска Threads* был приложением только для мобильных, это число также равно числу установок приложений

Это огромные числа для нового приложения, даже учитывая то, что более чем установка нового приложения рекламировалась двум миллиардам ежемесячно активных пользователей Instagram*. Когда я узнал эту статистику, то первым делом задался вопросом, как же команда разработчиков осилила этот выпуск. Похоже, особых проблем при этом у пользователей не возникало. Особенно учитывая то, что команда Threads* сдвинула выпуск на более ранние сроки после того, как Twitter ограничил просмотры бесплатных пользователей до 600 постов в день; это решение создало прекрасную возможность для конкурента Twitter. Threads* был выпущен спустя считаные дни после введения в Twitter ограничений просмотров: и, похоже, что приложение правильно подобрало момент.

Но как всё это выглядело изнутри, с точки зрения разрабатывавших приложение инженеров? За ответами я обратился к команде разработки Threads*, которая с радостью поделилась подробностями.

Джесси Чен (менеджер по разработке Threads*) и Захан Малкани (ведущий серверный инженер приложения) рассказали мне историю создания Threads*.

1. Разработка Threads*


Насколько «типичным» был проект Threads* по сравнению с выпуском других приложений?

Threads* отличался от большинства выпусков. Обычно при появлении нового интересного приоритета мы используем культуру открытости компании, привлекая сотрудников к вступлению и формированию коллектива.

Однако в этом случае мы намеренно сохраняли малый размер и конфиденциальность команды. Мы обратились к одним из самых сильных наших инженеров, продакт-менеджеров и дизайнеров Instagram*, предложив поработать над этим, и нас регулярно контролировал глава Instagram* Адам Моссери. Мы знали, что основным приоритетом был срок вывода продукта на рынок, и хотели защитить команду от внешних помех.

▍ Выпускающая команда


Насколько большой была изначальная команда, и какую её часть составляли разработчики?

Команда была небольшой, с горизонтальной иерархией и с очень большой долей разработчиков, что стало намеренным выбором организационной модели. У нас был чёткий дедлайн и мы хотели максимизировать скорость принятия решений и минимизировать бюрократию.

Мы считали, что компактная организация поможет нам выпускать продукты быстрее и высоким качеством, и оказались правы.

Мы начали с очень маленькой команды, порядка дюжины человек. Подавляющее большинство участников команды пришло из Instagram*. Все, кто присоединялся к созданию Threads* позже, тоже переводились из внутренних отделов, то есть все они уже работали в Meta*.

Самый большой штат команды собрался за неделю до выпуска. В тот момент состав команды был таким:

  • 3 продакт-менеджера
  • 3 дизайнера
  • Примерно 60 инженеров

Я (Джесси) работал с руководителями разработки в разных отделах Instagram* над тем, чтобы выявить ключевых сеньор-разработчиков, которых нужно привлечь к проекту. Уровень опыта команды был перекошен в сторону сеньоров, потому что у нас была относительно маленькая команда и требовались инженеры, способные работать автономно и отвечать за собственные части приложения без внешнего контроля.

Команда Threads* на праздновании выпуска в июле 2023 года (Сан-Франциско, Калифорния)

▍ Планирование и работа с остальной частью Meta*


Насколько формальным или неформальным было планирование, как быстро вы перешли к прототипированию/кодингу?

Вначале мы немного поработали над высокоуровневым планированием, обсуждая, какой объём кодовой базы Instagram* мы хотим использовать. Однако по большей части мы сразу переходили к прототипированию и кодингу.

Мы воспользовались одним из первых принципов Meta*: «код побеждает в спорах».

Мы активно придерживались этого принципа. Даже ещё до того, как мы получили официальное одобрение, инженеры уже прототипировали идею текстовой ленты, чтобы убедиться в её реализуемости!

Насколько тесно вы работали с другими внутренними командами Meta*, например, с инфраструктурным, платформенным или продуктовым отделами?

У нас было уникальное сотрудничество с программой «Bug Bounty» — мы пригласили исследователей безопасности протестировать приложение на баги перед выпуском. Цель этой программы заключалась в защите данных пользователей и в выявлении багов безопасности или конфиденциальности на ранних этапах. Благодаря этой программе, мы обнаружили несколько серьёзных багов.

Мы работали втайне.

До выпуска основная команда разработки была изолирована от остальной структуры разработчиков Instagram*. Работая втайне, мы дискретно добавляли наш код к общей кодовой базе и обращались к командам-партнёрам только когда сталкивались с проблемами, требовавшими их опыта.

Тем не менее, мы бы не выпустили это приложение вовремя, если бы работали в изоляции. Мы активно пользовались внутренним инструментарием и фреймворками. И использовали множество элементов других внутренних команд, например:

  • Фреймворки UI
  • API
  • Инфраструктура логинов, конфиденциальности, безопасности и целостности
  • Серверная инфраструктура
  • … и многое другое!

Чтобы двигаться максимально быстро, мы повторно использовали как можно больше кода. Наша высокая скорость разработки и стабильность в момент выпуска стали свидетельствами того, насколько потрясающей была организация разработки. Благодаря поддержке платформенного/инфраструктурного отделов, мы могли быстро масштабироваться и создавать новые продукты.

▍ График


Мы написали первую строку кода для приложения в конце января 2023 года. Окончательную релизную версию мы отправили в магазины приложений в июне 2023 года.

Усилия по разработке от начала до выпуска заняли пять месяцев.

2. Технологические решения и подходы к разработке


Какие технологии вы выбрали для бэкенда и мобильных приложений?

Бэкенд работает на стеке Instagram* — нашем специализированном Python с Django, который общается со специальным REST API. Также мы общаемся с большим монолитным бэкендом Meta* через GraphQL, который работает в HHVM — виртуальной машине для исполнения программ, написанных на Hack (языке, напоминающем PHP).

Приложения в большой степени нативны, в них используется смесь Swift на iOS (и немного Objective C) и Jetpack Compose на Android (с Kotlin и Java). Для нескольких простых случаев используются общие экраны с рендерингом на сервере, но в норме применяется нативный подход.

▍ Использование внутреннего стека


Какие решения вы принимали, выбирая, между повторным использованием уже имеющихся частей стека (библиотек и фреймворков) и созданием собственных?

Так как в приоритете был срок вывода продукта на рынок, мы по возможности использовали технологический стек Instagram*. Сам Instagram* создан на основе разнообразных библиотек и фреймворков, многие из которых разрабатывались внутри компании.

Мы воспользовались преимуществом «чистого листа», чтобы попробовать технологии, которых раньше использовать не имели возможности.

На iOS все новые части приложения были разработаны на Swift, а на Android мы в большой степени использовали Jetpack Compose. Благодаря выбору нового языка (Swift) и фреймворка (Jetpack Compose) мы двигались максимально быстро.

Мы решили активно использовать готовый технологический стек Instagram*, построенный на инфраструктуре Meta*, что сильно повлияло на скорость нашей разработки. Поэтому нам не пришлось решать неопределённый спектр задач «Как создать с нуля новую текстовую соцсеть?».

Вместо этого задача была более концентрированной:

«Как нам использовать строительные блоки ленты Instagram* для постов, которые в основном состоят из текста?»

Уже после выпуска приложение Threads* ощущалось быстрым. Какой приоритет вы отдавали производительности на стороне клиента и как измеряли или тестировали её?

В момент выпуска приложение не было достаточно быстрым! У нас есть внутренние инструменты, профилирующие время, затрачиваемое на разные задачи, и после выпуска нам пришлось их активно использовать, ведь самые популярные посты внезапно испытали всплеск популярности, обеспечив неожиданную для нас нагрузку на сеть уже в день выпуска.

У нас есть внутренние фреймворки, позволяющие замерять разнообразные критичные метрики производительности. Вот некоторые примеры:

  • «Время до нового контента» — метрика времени, которое требуется от холодного запуска до отображения контента в ленте
  • Производительность скроллинга, проверяется при помощи отслеживания пропуска кадров

▍ Методика тестирования Threads*


Каков был ваш подход к тестированию, в частности, к автоматизированным тестам?

На этот счёт есть две точки зрения:

  • А) разработать и получить быструю обратную связь. Заниматься автоматизированными тестами, только когда есть product-market fit (PMF.)
  • Б) Создавать всё с нуля с учётом PMF, а затем реализовать тесты для удобства сопровождения и так далее.

Мы были в лагере А и занимались автоматизированными тестами после PMF для тестов фронтенда/UI. Из-за важности срока вывода продукта на рынок мы дисциплинированно отказывались от вещей, не помогавших нам двигаться к этой цели.

Разумеется, автоматизированные тесты важны; однако нет никакого смысла писать тесты для UI, который постоянно меняется. Для контекста скажу, что некоторые потоки пережили от трёх и более редизайнов, прежде чем мы пришли к чему-то, что нас устраивало!

Автоматизированные тесты не помогают продукту без product market fit.

Вместо них, мы активно использовали догфудинг и QA. Догфудеры скачивали мастер-сборки, дополнявшиеся каждые несколько часов новыми изменениями. Быстрый цикл обратной связи позволял нам переходить от макетов в Figma до устанавливаемых на телефоны мастер-сборок всего за несколько часов.

Тем не менее, бизнес-логика бэкенда следовала практике разработке через тестирование (test-driven development, TDD), которую мы стимулировали при помощи peer review. У нас есть отличные внутренние фреймворки тестирования, позволяющие задать состояние и достаточно легко выполнять реальную бизнес-логику, не касаясь баз данных в продакшене. Это позволило команде бэкенда двигаться быстро, потому что мы могли вносить изменения с уверенностью, без необходимости сквозного тестирования каждого изменения.

3. Планирование выпуска


Какие наибольшие трудности с нагрузкой вы ожидали для Threads*?

Мы знали, что сложности с масштабированием создаст конкретная функция — возможность перетаскивать граф пользователей из Instagram*.

Одна из сложностей запуска новой социальной сети заключается в проблеме «холодного старта», с которой сталкиваются пользователи. Каждому из ваши новых пользователей нужно найти на платформе интересующих их людей и выбрать подписку на них или дружбу. Мы хотели упростить эту задачу, добавив включаемую одним касанием функцию «подписаться на всех, на кого ты уже подписан в Instagram*».

Однако при этом возникает серьёзная проблема масштабирования! Подумайте о самых популярных аккаунтах, регистрирующихся в Threads*, очередь на подписку к которым составляет уже порядка миллионов пользователей. Нам нужно было обрабатывать такие крупные аккаунты за разумное время.

После выпуска мы осознали, что масштаб, с которым нам приходится иметь дело, намногопревзошёл наши ожидания. С момента выпуска нам пришлось менять архитектуру системы с совершенно иным набором допущений.

▍ Догфудинг


Как долго применялся догфудинг Threads* и приблизительно для какого количества человек? Как команда занималась сбором обратной связи и реагированием на неё?

Мы выполняли догфудинг [прим. пер.: догфудинг — практика использования собственных продуктов или услуг] самого начала, но намеренно оставляли группу обратной связи маленькой. Наша цель заключалась в получении важной обратной связи, чтобы при этом команду не перегружали баг-репорты.

Мы постепенно расширяли догфудинг с ядра команды до всего Instagram*. При малой группе догфудинга инженеры задействовались напрямую и выполняли отладку вместе с коллегами, что обеспечивало очень компактный цикл обратной связи.

▍ Нагрузочное тестирование


Как вы готовились к выпуску и обрабатывали изначальную нагрузку? Например, выполняли ли вы заранее нагрузочные тесты или другое тестирование?

Разумеется, тщательное тестирование входило в наши планы. Однако из-за внешних обстоятельств мы перенесли выпуск на более ранний срок.

Нам приходилось масштабировать свои ресурсы и поддержку выпуска на лету. Это было вызвано переносом срока выпуска; из-за изменения графика мы не могли выполнять нагрузочные тесты заранее. Это был один из самых напряжённых выпусков в компании за долгое время!

Насколько вы были уверены (или не уверены), что справитесь с потенциально большой нагрузкой на момент выпуска? Мне кажется необычным, запуск продукта на весь мир без ограничения регистраций или списка ожидания.

Мы знали, что нас поддерживает опыт Instagram* и Meta*, поэтому мы были достаточно уверены в выпуске. И изначально мы считали, что в масштабах Meta* это будет малой каплей.

Оглядываясь назад, мы можем сказать, что реальность регистрации такого количества пользователей с такой скоростью оказалась беспрецедентной для Meta*. Однако нам помогли десятки лет инвестиций в надёжную и высокопроизводительную инфраструктуру Meta*:

  • Базы данных
  • Системы индексации графов
  • Системы ранжирования
  • Системы обеспечения целостности
  • Системы уведомлений

Все эти системы согласованно и без особых проблем поглощали всю нагрузку.

4. Выпуск


Снаружи процесс выпуска выглядел на удивление плавным, за первую неделю произошло лишь несколько кратковременных неполадок. А как он происходил изнутри?

Начиная за неделю до выпуска и ещё несколько недель после, для команды это была ситуация «общего сбора».

Мы проводили регулярные видеосозвоны, на которых в прямом эфире обсуждали проблемы и команда круглосуточно работала над их решением.

Нас тронуло то, что это определённо было не только «проблемой команды Threads*». В важный момент выпуска мы получили поддержку от наших команд-партнёров в Instagram* и во всей Meta*. Разработчики, работавшие над компонентами инфраструктуры, сотрудничали с инженерами продакшена, поддерживающими работу систем, а те взаимодействовали с продуктовыми инженерами, отлаживающими свои фичи.

Именно при таких запусках можно наблюдать преимущества культуры открытости. Открытая кодовая база оправдала себя, потому что новые люди могли быстро вливаться и приносить пользу, даже если это была новая для них область.

▍ Измерение показателей выпуска


На каких KPI или метриках разработки вы фокусировались, чтобы проверить соответствие работы Threads* ожиданиям?

Мы использовали следующие инструменты мониторинга:

  • ODS – высокопроизводительный движок хранения временных последовательностей; Scuba – система управления данными, которую мы применяли для анализа в реальном времени. Эти инструменты помогали нам отслеживать нагрузку и тому подобное.
  • Развитая экосистема extract-transform-load (ETL) хранилища данных, ежечасно предоставлявшая нам ключевые метрики продукта.

Мы активно применяли инструменты PREQ (performance, reliability, efficiency, quality). Наша команда положилась на огромный опыт Meta* в поддержке инструментов PREQ, которые были встроены в клиентское приложение и интегрированы в серверные фреймворки.

Мы обращали внимание на следующие метрики:

  • Производительность и нагрузка на стороне серверов
  • «Время до отображения нового контента» — наша метрика холодного запуска приложения
  • QPS/показатель успеха на наших ключевых конечных точках
  • Длина очередей в наших асинхронных задачах, выполняющих основную работу
  • Наше общее потребление ресурсов в основном монолите бэкенда Instagram*

Кроме того, уведомления на уровне конечных точек давали нам понять, когда у конкретных конечных точек возникали проблемы, если мы недостаточно хорошо учитывали масштабирование.

▍ Статистика выпуска


Предыдущий рекорд самого быстрорастущего приложения Meta* составлял один миллион пользователей за пять дней. А вот как рос Threads*:

  • 1 миллион пользователей: за 1 час
  • 30 миллионов: 1 день
  • 70 миллионов: 2 дня
  • 100 миллионов: 5 дней

5. Выводы и следующие шаги


Какие серьёзные трудности у вас возникали?

Самой большой стало создание привлекательной ленты Threads*. На сайте микроблоггинга самое релевантное — это то, что происходит прямо сейчас. Он должен отражать то, о чём говорят все и давать выбор, к какому обсуждению присоединиться.

Существует баланс между срочностью и помощью пользователю в том, чтобы он нашёл контент источника, который будет для него самым интересным. В то же время, другие приложения из этой сферы показали, что для показа релевантного и интересного контента необязателен обширный граф связей.

Мы обсуждали с командой Threads* то, что хотим снизить нашу зависимость от пользователей, вручную курирующих графы подписок. Однако чтобы снизить зависимость от ручного курирования, нужно понимать, о чём эти посты, и знать, что происходит в мире, и обе эти задачи очень сложны!

▍ Уроки для команды разработчиков


Что с точки зрения разработки прошло хорошо в этом проекте и при выпуске?

Важны два пункта:

  • Скорость, с которой мы смогли реализовать готовый продукт для выпуска
  • Относительно малый размер команды получил одобрение как внутри, так и снаружи.

До выпуска приложения на рынке имелся большой интерес к нему, что дало людям причину скачать приложение и попробовать его. Наша задача как инженеров заключалась в устранении помех. Это огромное достижение, которого мы смогли добиться относительно без проблем.

Какие ценные уроки получила команда разработчиков?

Фокус: это ключевое различие между продуктами, готовыми найти product-market-fit, и теми, которые к этому не готовы. Фокус необходим, но самого по себе его недостаточно. Разработчики Threads* смогли достичь фокуса, агрессивно урезая фичи продукта до самых необходимых. С самого начала мы решили сосредоточиться на реализации собственных milestone.

Каждый собственный milestone должен был стать абсолютно идеальной и готовой к выпуску фичей приложения, но с ограниченной функциональностью.

Эти milestone внесли ясность в то, что нам абсолютно необходимо разработать, потому что ни на что другое оглядываться у нас времени не было.

Какой была самая интересная часть проекта для разработчика?

Процесс понимания всей широты кодовой базы Instagram*. Было принято техническое решение использовать большую часть технического стека Instagram*, а это значило, что создание этого приложения стало упражнением по исследованию кодовой базы Instagram*, чтобы мы могли вносить точечные изменения под наш сценарий использования.

Редко можно получить возможность изучения Instagram* на таком высоком уровне, одновременно погружаясь в подробности критичных подсистем Instagram*!

Это походило на головоломку: нам нужно было понять, в какие системы Instgram нужно внести большинство целенаправленных изменений, которые бы принесли наибольшую выгоду и обеспечили минимальный риск. Эта задача оказалась самой интересной частью проекта.

▍ Дальнейшие шаги


Какое влияние оказал выпуск Threads* на способ разработки приложений в Meta*?

Многие люди из других отделов обращались к нам с целью изучения Threads* как примера для выпуска будущих продуктов. Нас выделяет скорость, с которой была выпущена первая версия Threads* — вся работа над приложением началась лишь в этом году.

Наличие маленькой, но опытной команды разработчиков, выпустившей популярное уникальное приложение всего за пять месяцев — это свидетельств важного изменения в культуре. Мне бы хотелось видеть, что другие команды вдохновятся этим и будут создавать более быстрые коллективы!

Какими будут новые приоритеты для команды и планы роста?

Наряду с закрыванием пробелов в базовой функциональности, мы также активно вкладываемся в активное модифицирование инфраструктуры Threads*, чтобы сделать её более надёжной.

Статистика выпуска намного превзошла наши ожидания. Наше руководство с оптимизмом смотрит на траекторию развития приложения, поэтому мы вкладываемся в рост команды разработки.

Threads* начиналась как маленькая команда-инкубатор в рамках организации Instagram*. Благодаря успеху выпуска мы ожидаем, что она будет расти и станет более формальной.

Выполнение каких задач предвкушает команда разработчиков в будущем?

Мы работали над максимально быстрым добавлением в Threads* новых возможностей. Одна из таких функций — долгожданная веб-версия Threads*, которую мы выпустили в прошлом месяце. Ещё одна — это расширение тестирования поиска контента на новых пользователей в Канаде, США, Индии и Великобритании.

Я рад, что наша команда продолжит выпускать функции, повышающие удобство пользователей Threads*.

Также мне нравится наша приверженность Fediverse и поддержка протокола ActivityPub. При наших масштабах это невероятно интересная сложная задача с технической и юридической точки зрения. Мы будем продолжать стремиться к участию в Fediverse и созданию совместимости с другими сетями для реализации более разнообразной и развивающейся экосистемы общения.

Meta Platforms*, а также принадлежащие ей Facebook**, Instagram** и Threads:
* признана экстремистской организацией, её деятельность в России запрещена;
** запрещены в России.

Telegram-канал с розыгрышами призов, новостями IT и постами о ретроиграх ????️

Комментарии (3)


  1. little-brother
    27.09.2023 13:22
    +6

    Все было круто на старте, но дальше статьи вида: От успеха к забвению: названы причины падения аудитории Threads с заголовками "Удачный старт, но сырой продукт".


  1. Ravager
    27.09.2023 13:22

    Сейчас на каждом собеседовании просят спроектировать Твиттер или инстаграмм за 50 минут. Решения уже давно известны и обмусолены. В чем тут должно быть восхищение?


    1. event1
      27.09.2023 13:22
      +1

      Так на собеседовании это надо в одно лицо делать. А тут 60 старших инженеров.