What's coming
I've spent seven years writing backends for systems where mistakes cost money. Payment flows, crypto, high load. Along the way I collected a list of techniques I first saw in large systems and later used in my own work.
That's what I'm going to write about.
Every breakdown follows the same shape. First the problem, then the solution any decent developer would write. Then I show at what scale it stops working and what to do instead. I always end with what the technique costs you, because none of them are free.
Most breakdowns come with a repository. You can run it and watch the naive version fall apart under load.
Я семь лет пишу бэкенды для систем, где ошибка стоит денег. Платёжные контуры, крипта, высокие нагрузки. За это время накопился список приёмов, которые я подсматривал у больших систем и потом применял у себя.
Про них и буду писать.
Каждый разбор строю одинаково. Сначала задача, потом решение, которое напишет любой нормальный разработчик. Дальше показываю, на каком объёме оно перестаёт работать, и что делать вместо. В конце всегда говорю, чем вы за это платите, потому что бесплатных приёмов не бывает.
К большинству разборов будет репозиторий. Можно запустить и посмотреть, как наивная реализация ломается под нагрузкой.
The first six posts
I'm starting with techniques I picked up from Telegram. The reason is simple: there they run for hundreds of millions of users, not in a diagram from someone's slide deck. I spent five years writing a server-side implementation of their protocol, so I know where the hard parts actually are.
-
Your client was offline for a day. Now what?
Everyone building mobile apps, dashboards or integrations runs into this. We'll look at five implementations: Telegram, Binance, Bybit, VK, X. All different, each with its own price. And we'll talk about why duplicates during recovery are unavoidable no matter which one you pick.
-
Idempotency: what the reference model leaves out
Everyone knows how Stripe does it. But it says nothing about what happens when the response never reaches you and never will. The operation may have gone through, or not. Let's see how that gap gets closed.
-
Channels vs. chats
Why broadcasting to a million subscribers is built completely differently from a conversation between two people. Plus why you can link to a message in a channel but not to one in a private chat.
-
Upload once, send a hundred times
About files. Uploading separated from sending, deduplication, resumable transfers. And a neat trick: serving content through someone else's CDN so the CDN operator can't read it.
-
The API changes, the clients don't
The whole schema gets versioned, not the endpoint paths. That's how dozens of client versions coexist for years without anyone maintaining three parallel APIs.
-
Request batches and dependencies between them
You send ten requests, the third depends on the first. The server will run them in whatever order it likes. There's a way to say “this one after that one”, and you rarely see it in REST.
After that
Techniques from other systems: exchanges, social networks, payment gateways.
Hybrid fan-out and the question of where to draw the line between a regular author and a popular one. The check-then-insert race and three ways to kill it. Counters you can't count exactly, and how to explain that to your product manager. Rate limits measured in weights instead of request counts. Request signing with a validity window. Absolute values instead of deltas.
Assembled modules
Not isolated techniques but working pieces in full. I'll put them on GitHub, feel free to fork.
File service. Post feed. Chat. Payment module.
One caveat: these will be references, not libraries. I can't maintain them for years and won't pretend otherwise. But you can see how they're built and take what you need.
In parallel
I'm writing an open MTProto implementation. Telegram published the protocol and the clients but not the server, and there still isn't an open one.
Doing it layer by layer: schema codegen first, then crypto, transport, and the server itself. Progress goes in the channel, code on GitHub.
The order isn't fixed
Nothing here is set in stone. If you need a specific topic sooner, say so in the comments or in the chat. I'll move it up.
And if you're working on something similar right now and a breakdown is missing a piece, tell me. I'll add it.
Первые шесть статей
Начинаю с приёмов, которые подсмотрел в Telegram. Причина в том, что там это работает на сотнях миллионов пользователей, а не в схеме из чьей-то презентации. Я пять лет писал серверную реализацию их протокола, так что знаю, где там на самом деле сложно.
-
Клиент отключился на сутки. Что ему прислать?
Задачу решают все, кто делает мобильные приложения, дашборды и интеграции. Посмотрим на пять реализаций: Telegram, Binance, Bybit, VK, X. Все разные, и у каждой своя цена. Отдельно поговорим о том, почему дубли при восстановлении неизбежны в любой схеме.
-
Идемпотентность. Чего не хватает эталону
Схему Stripe знают все. Но она молчит о том, что делать, если ответ до вас так и не дошёл и уже не дойдёт. Операция могла пройти, а могла и нет. Разберём, как эту дыру закрывают.
-
Каналы против чатов
Почему рассылка миллиону подписчиков устроена совсем иначе, чем переписка двоих. Заодно разберёмся, почему на сообщение в канале можно дать ссылку, а на сообщение в личке нельзя.
-
Залить один раз, отправить сто раз
Про файлы. Загрузка отдельно от отправки, дедупликация, докачка. И красивый трюк: как раздавать контент через чужой CDN так, чтобы владелец CDN не мог его прочитать.
-
API меняется, а клиенты старые
Версионируется схема целиком, а не адреса методов. Так десятки версий клиентов живут одновременно годами, и никто не поддерживает три параллельных API.
-
Пачки запросов и зависимости между ними
Отправили десять запросов, третий зависит от первого. Сервер выполнит их в любом порядке. Есть способ сказать «этот после того», и в REST такого почти не встретишь.
Дальше
Приёмы из других систем: биржи, соцсети, платёжные шлюзы.
Гибридный fan-out и вопрос, где провести границу между обычным автором и популярным. Гонка «проверил, потом вставил» и три способа её убрать. Счётчики, которые невозможно посчитать точно, и как объяснить это продакту. Лимиты, которые считаются в весах, а не в запросах. Подпись запроса с окном валидности. Абсолютные значения вместо дельт.
Собранные модули
Не отдельные приёмы, а работающие штуки целиком. Выложу на GitHub, форкайте.
Файловый сервис. Лента постов. Чат. Платёжный модуль.
Сразу оговорюсь: это будут референсы, а не библиотеки. Я не смогу поддерживать их годами, и обещать этого не буду. Зато можно посмотреть, как оно устроено, и взять к себе.
Параллельно
Пишу открытую реализацию MTProto. Телеграм выложил протокол и клиенты, но не сервер, и открытых серверов до сих пор нет.
Делаю по слоям: сначала генератор типов из схемы, потом криптография, транспорт, и в конце сам сервер. Показываю процесс в канале, код на GitHub.
Порядок можно поменять
Список не высечен в камне. Если какая-то тема нужна вам раньше, напишите в комментариях или в чат. Подниму.
И если разбираете похожую задачу прямо сейчас, а в разборе чего-то не хватает, тоже пишите. Дополню.