メルペイでの3ヶ月間:非同期処理への移行とASDD開発の学び
メルカリエンジニアリングは、債権残高のホットスポット問題を解決するために非同期処理へ移行し、AI エージェントを活用した ASDD(Agent Spec Driven Development)による開発手法の実践と学習成果を報告している。
キーポイント
グローバル展開に伴う負荷分散の必要性
メルカリ グローバルアプリの展開により、特定行への更新集中(ホットスポット)がロック競合やスループット低下を招くため、債権残高更新処理を非同期化して解決を図った。
DB 駆動型ジョブキューによるアーキテクチャ設計
外部サービスへの依存を避けるため、イベントテーブルと DB を Job Queue として活用し、Worker と Job Processor で非同期処理を実現する独自アーキテクチャを採用した。
ASDD(Agent Spec Driven Development)の実践
AI エージェントが仕様書を作成し、別エージェントが実装を進める ASDD 手法を用い、設計ドキュメント作成は人間が行ったものの、実装工程を AI が短時間で完了させた。
負荷試験の計画とインフラ整備
処理遅延の計測や安定性確認のための負荷試験を予定しており、専用リポジトリによるシナリオ作成と再現性の確保が整っていることを報告している。
影響分析・編集コメントを表示
影響分析
この記事は、大規模金融サービスにおけるスケーラビリティ課題に対する具体的なアーキテクチャ解決策(DB 駆動非同期処理)を示すとともに、AI エージェントを活用した開発プロセス変革の現実的な適用事例を提示しています。特に ASDD の導入により、設計と実装の役割分担が再定義され、開発生産性が向上する可能性を示唆しており、テック業界全体における AI ナティブ開発への参考となる重要な知見です。
編集コメント
大規模システムにおけるホットスポット対策の具体的な実装例と、AI エージェントを駆使した開発フロー(ASDD)の実践報告は、エンジニアリングチームにとって非常に示唆に富んでいます。特に設計ドキュメント作成と実装工程における人間と AI の役割分担の成功事例は、今後の開発プロセス変革の参考になります。
はじめに
こんにちは。メルペイの Balance チームでインターンをしている @minato です。
この記事は、Merpay & Mercoin Advent Calendar 2025 の 18 日目の記事です。
2025 年 10 月からメルペイでバックエンドのインターンを始め、3 ヶ月目になります。
本記事では、インターン期間中に取り組んだタスク、得ることのできた学びについて紹介します。
取り組んだタスク
今回のインターンでは、債権データを管理するマイクロサービスにおいて、これまで同期的に行っていた債権残高の更新処理を非同期処理へと移行するタスクに取り組みました。
以下、非同期処理へ移行するに至った背景、設計、実装、負荷試験について説明していきます。
背景
メルペイでは現在、世界共通のプラットフォームを提供する「メルカリ グローバルアプリ」プロジェクトが進められています。これまで国ごとに限定されていたプロダクトをグローバルに展開するにあたり、これまでになかった量の Transaction(取引)が集中することが想定され、負荷分散機能の検討・開発が必要となりました。
このような理由から、僕は、負荷分散を必要とする機能の一つである債権の作成機能の改善に取り組みました。
債権データの作成プロセスでは、債権を作成した後、該当する債務者の債権残高を更新する必要があります。なので、債権データの作成リクエストが連続して行われた際、特定の行やカラムに更新が集中してしまい、その箇所が hotspot(ホットスポット)となり、以下の問題を起こします。
- 高負荷が特定の行に集中し、ロック競合が多発する
- 更新待ちが発生し、スループットが低下する
この問題を解決するために、債権残高をリクエスト中に同期的に更新するのではなく、非同期で更新することにしました。非同期化することで、本来複数の Transaction(取引)で処理されるはずの複数の Request(要求)による債権残高の更新を、一つの Transaction(取引)でまとめて処理することができ、hotspot(ホットスポット)問題を解決することができます。
設計
大まかな設計としては、債権残高の更新処理が発生した際に債権更新イベントテーブルへレコードを作成し、worker がそのテーブルを取得して Job Queue(ジョブキュー)に push(プッシュ)、Job Processor(ジョブプロセッサ)が Job Queue(ジョブキュー)内のアイテムに基づいてアカウントを更新するという流れとしました。
また、Job Queue(ジョブキュー)については、債権更新イベントテーブルに、Job Queue(ジョブキュー)に入っているかを表すフィールドを設けることで、DB(データベース)を Job Queue(ジョブキュー)として使用できる仕組みとしました。なぜイベントの管理を、外部サービスではなく DB(データベース)で管理としたのかというと、外部サービスへの依存を避けられること、同様の処理を行うマイクロサービスにおいて DB(データベース)で管理する構成で正常に機能しているためになります。
以下の画像は、非同期イベントをどのように処理しているのかについて表したものです。Worker は DB から処理されていないイベントレコードを取得し、server 上のメモリ (以下の図の Queue) に保存します。その後、Job Processor が Queue 内のイベントをまとめて処理するという構成になります。
実装では、Worker、Queue、Job Processor のそれぞれについてカスタマイズしやすい struct を定義し、他の非同期処理において再利用できるようにしました。

実装
今回の実装では、社内で活用が推進されている ASDD(Agent Spec Driven Development) という方法を使用しました。ASDD とは、AI agent が仕様書を作成し、別 agent がその仕様書に基づいて実装を進めるという手法です。詳しくは、pj-double: メルカリの開発生産性向上に向けた挑戦 — AI-Native 化が辿り着いた ASDD とプロセス変革の全貌 の記事をご覧ください。
アカウントの非同期化は、システム全体に関わる非常に大きな機能改善であったため、厳密に設計を Docs として記録すること、レビューのしやすさを考慮し、仕様書自体は僕が手作業で作成したため、時間を消費してしまいましたが、その後の実装はあっという間に AI によって完了し、とても驚きました。
「もし社内の全員が ASDD を使いこなす未来が来たらどうなるのか」 と想像するだけでワクワクする体験でした。
負荷試験
負荷試験については、まだ行っていないため、これから取り組む予定のことを説明します。今回の負荷試験では、想定される平均リクエスト数と最大リクエスト数をテスト環境に対して送信し、システムがどの程度安定して処理できるかを確認する予定です。
また、債権残高の更新イベントが生成されてから、非同期的に実際に更新されるまでの処理時間についても計測しようと思います。というのも、債権残高の更新される速度は、債権の処理を行う上流のサービスにとって非常に重要なものになるためです。
テスト計画を立てる中、驚いたことは、負荷試験のためのリポジトリが整備されていたことです。専用のリポジトリが存在することで、誰でも容易に負荷試験シナリオを作成でき、さらに他者が同じ条件で負荷を再現できるため、検証の透明性と再現性を保つことができます。
インターンを通して得た学び
今回のインターンでは、日常の開発ではなかなか扱うことのできない規模のリクエスト数を処理するシステムの開発を経験することができ、技術的な学びはもちろん、コーディングに対する姿勢やプロダクトへの向き合い方について学びました。
コーディングへの取り組み方
インターンを通じて特に印象的だったのは、コメントを書かなくても関数名やコードから推測がつき、後から読んだ際に一目で何をする処理なのかを理解できるレベルを目指す姿勢です。保守・運用のことも考慮したコードを書くことは普段の開発においても心がけていますが、普段の自分を見つめ直し、コーディングへの姿勢を改めるきっかけになりました。
また、レビューの際には、ファイル内のコメント一つに対しても、どのような意図を持って書いたのか、またそもそもそのファイルは何のためにあるのかといったことを指摘していただき、開発においてメタ的に考えることと具体的に考えることの両方を行うことの重要性を実感しました。
プロダクトのことを第一に考える開発
また、プロダクトに対する心構えについても、非常に刺激を受けました。チームのメンバー一人一人が、プロダクトの未来を考えながら意思決定をしており、「将来的にこう使われる可能性があるから、今の内にこの手法を採用しておく」、「お客さま体験を良くするためにこのデータ構造はこうあるべき」といった議論が開発中だけではなく食事中にも頻繁に行われており、プロダクトへの愛とメルカリの Values の一つである Be a Pro の精神を強く感じました。
その他の活動と経験
インターン期間中は、開発のタスクにのみ取り組むのではなく、Q に 1 回開催されている社内イベントの Tech Talk に登壇してみたり、他のチームの方と 1on1 やランチに行ったり、技術書やテックブログの読み合わせ会に参加したりと、いろいろな活動をしました。
ランチではバックエンドエンジニアの方だけではなく、セキュリティエンジニアの方とも話す機会をいただき、なぜその職種を選んだのかというキャリアの話から、最近の攻撃手法、日々の開発で意識すべきセキュリティ観点まで、バックエンドに閉じない視点を得ることができました。
また、Tech Talk や読み合わせ会に参加し、メルカリは、自発的に技術を学びに行ったり、技術について情報発信する環境が本当に整っていることを強く実感し、エンジニアにとって最高の環境だと思いました。
さいごに
インターンを通して、タスクに取り組む中で技術的な学びだけではなく、AI の活用方法、エンジニアとしての姿勢についても多くの学びを得ることができました。特に、エンジニアとしての姿勢は、これからの働き方に活かしていこうと思います。インターンとして参加できる残りの期間では、負荷試験までやり切り、可能であればリリースまで完了させたいと考えています。
今回の開発をリードしてくださった@yutaro さん、メンターの@kobaryo さん、そしてチームの皆さんを始め関わってくださった全ての方々、本当にありがとうございました!
明日の記事は@komatsu さんです。引き続きお楽しみください。
原文を表示
はじめに
こんにちは。メルペイの Balance チームでインターンをしている @minato です。
この記事は、Merpay & Mercoin Advent Calendar 2025 の18日目の記事です。
2025年10月からメルペイでバックエンドのインターンを始め、3ヶ月目になります。
本記事では、インターン期間中に取り組んだタスク、得ることのできた学びについて紹介します。
取り組んだタスク
今回のインターンでは、債権データを管理するマイクロサービスにおいて、これまで同期的に行っていた債権残高の更新処理を非同期処理へと移行するタスクに取り組みました。
以下、非同期処理へ移行するに至った背景、設計、実装、負荷試験について説明していきます。
背景
メルペイでは現在、世界共通のプラットフォームを提供する「メルカリ グローバルアプリ 」プロジェクトが進められています。これまで国ごとに限定されていたプロダクトをグローバルに展開するにあたり、これまでになかった量の Transaction が集中することが想定され、負荷分散機能の検討・開発が必要となりました。
このような理由から、僕は、負荷分散を必要とする機能の一つである債権の作成機能の改善に取り組みました。
債権データの作成プロセスでは、債権を作成した後、該当する債務者の債権残高を更新する必要があります。なので、債権データの作成リクエストが連続して行われた際、特定の行やカラムに更新が集中してしまい、その箇所が hotspot となり、以下の問題を起こします。
- 高負荷が特定の行に集中し、ロック競合が多発する
- 更新待ちが発生し、スループットが低下する
この問題を解決するために、債権残高をリクエスト中に同期的に更新するのではなく、非同期で更新することにしました。非同期化することで、本来複数の Transaction で処理されるはずの複数の Request による債権残高の更新を、一つの Transaction でまとめて処理することができ、hotspot 問題を解決することができます。
設計
大まかな設計としては、債権残高の更新処理が発生した際に債権更新イベントテーブルへレコードを作成し、worker がそのテーブルを取得して Job Queue に push、Job Processor が Job Queue 内のアイテムに基づいてアカウントを更新するという流れとしました。
また、Job Queue については、債権更新イベントテーブルに、Job Queue に入っているかを表すフィールドを設けることで、DB を Job Queue として使用できる仕組みとしました。なぜイベントの管理を、外部サービスではなく DB で管理としたのかというと、外部サービスへの依存を避けられること、同様の処理を行うマイクロサービスにおいて DB で管理する構成で正常に機能しているためになります。
以下の画像は、非同期イベントをどのように処理しているのかについて表したものです。Workerは DB から処理されていないイベントレコードを取得し、server上のメモリ(以下の図の Queue) に保存します。その後、Job Processor が Queue 内のイベントをまとめて処理するという構成になります。
実装では、Worker、Queue、Job Processor のそれぞれについてカスタマイズしやすい struct を定義し、他の非同期処理において再利用できるようにしました。

実装
今回の実装では、社内で活用が推進されている ASDD(Agent Spec Driven Development) という方法を使用しました。ASDD とは、AI agent が仕様書を作成し、別agentがその仕様書に基づいて実装を進めるという手法です。詳しくは、pj-double: メルカリの開発生産性向上に向けた挑戦 — AI-Native化が辿り着いたASDDとプロセス変革の全貌 の記事をご覧ください。
アカウントの非同期化は、システム全体に関わる非常に大きな機能改善であったため、厳密に設計をDocsとして記録すること、レビューのしやすさを考慮し、仕様書自体は僕が手作業で作成したため、時間を消費してしまいましたが、その後の実装はあっという間にAIによって完了し、とても驚きました。
「もし社内の全員が ASDD を使いこなす未来が来たらどうなるのか」 と想像するだけでワクワクする体験でした。
負荷試験
負荷試験については、まだ行っていないため、これから取り組む予定のことを説明します。今回の負荷試験では、想定される平均リクエスト数と最大リクエスト数をテスト環境に対して送信し、システムがどの程度安定して処理できるかを確認する予定です。
また、債権残高の更新イベントが生成されてから、非同期的に実際に更新されるまでの処理時間についても計測しようと思います。というのも、債権残高の更新される速度は、債権の処理を行う上流のサービスにとって非常に重要なものになるためです。
テスト計画を立てる中、驚いたことは、負荷試験のためのリポジトリが整備されていたことです。専用のリポジトリが存在することで、誰でも容易に負荷試験シナリオを作成でき、さらに他者が同じ条件で負荷を再現できるため、検証の透明性と再現性を保つことができます。
インターンを通して得た学び
今回のインターンでは、日常の開発ではなかなか扱うことのできない規模のリクエスト数を処理するシステムの開発を経験することができ、技術的な学びはもちろん、コーディングに対する姿勢やプロダクトへの向き合い方について学びました。
コーディングへの取り組み方
インターンを通じて特に印象的だったのは、コメントを書かずとも、関数名、コードから類推がつき、後から読んだ際に一目で何をする処理なのかを理解できるレベルを目指す姿勢です。保守・運用のことまで考えたコードを書くことは普段の開発においても、心掛けているのですが、普段の自分を見つめ直し、コーディングへの姿勢を改めるきっかけになりました。
また、レビューの際に、ファイル内のコメント一つに対しても、どのような意図を持って書いたのか、また、そもそもそのファイルは何のためにあるのかといったことを指摘していただき、開発においてメタ的に考えることと具体的に考えることの両方を行うことの重要性を実感しました。
プロダクトのことを第一に考える開発
また、プロダクトに対する心構えについても、非常に刺激を受けました。チームのメンバー一人一人が、プロダクトの未来を考えながら、意思決定をしており、「将来的にこう使われる可能性があるから、今の内にこの手法を採用しておく」、「お客さま体験を良くするためにこのデータ構造はこうあるべき」といった議論が開発中だけではなく食事中にも頻繁に行われており、プロダクトへの愛とメルカリの Values の一つである Be a Pro の精神を強く感じました。
その他の活動と経験
インターン期間中は、開発のタスクにのみ取り組むのではなく、Qに1回開催されている社内イベントのTech Talkに登壇してみたり、他のチームの方と1on1やランチに行ったり、技術書やテックブログの読み合わせ会に参加したりと、いろいろな活動をしました。
ランチではバックエンドエンジニアの方だけではなく、セキュリティエンジニアの方とも話す機会をいただき、なぜその職種を選んだのかというキャリアの話から、最近の攻撃手法、日々の開発で意識すべきセキュリティ観点まで、バックエンドに閉じない視点を得ることができました。
また、Tech Talk や読み合わせ会に参加し、メルカリは、自発的に技術を学びに行ったり、技術について情報発信する環境が本当に整っていることを強く実感し、エンジニアにとって最高の環境だと思いました。
さいごに
インターンを通して、タスクに取り組む中で技術的な学びだけではなく、AIの活用方法、エンジニアとしての姿勢についても多くの学びを得ることができました。特に、エンジニアとしての姿勢は、これからの働き方に活かしていこうと思います。インターンとして参加できる残りの期間では、負荷試験までやり切り、可能であればリリースまで完了させたいと考えています。
今回の開発をリードしてくださった@yutaroさん、メンターの@kobaryoさん、そしてチームの皆さんを始め関わってくださった全ての方々、本当にありがとうございました!
明日の記事は@komatsuさんです。引き続きお楽しみください。
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み