Kaigi on Rails 2025に参加してきました
こんにちは!
株式会社ココナラのマーケットプレイス開発部 Web開発グループ バックエンド開発チーム所属のさいぴーです。
今回は、2025年9月26日(金)〜27日(土)に開催されたKaigi on Rails 2025に、さいぴー、とーる、よるま、こうやの4名で参加してきました!

この記事では、私たちが今回のカンファレンスで学んだことや感じたことをレポートしていきます!
Kaigi on Rails 2025とは
Kaigi on Rails 2025は、Ruby on Railsを中心としたWeb技術に焦点を当てた技術カンファレンスです。
「初心者から経験豊富なプロフェッショナルまで、誰もが参加しやすい」をコンセプトに、今年はハイブリッド形式(オフライン+オンライン)で開催されました。
開催概要
- 日程: 2025年9月26日(金)〜27日(土)
- 会場: JP TOWER Hall & Conference(東京駅近く)
- 形式: ハイブリッド開催(オフライン+オンライン)
今回のテーマは「動的(dynamic)」。継続的に変化し続けることについて、Ruby、Rails、そしてプロダクトのスケーリングという観点から議論されました。
ココナラでもバックエンド領域の主要部分にRuby on Railsを開発言語/FWとして採用しているため、最新の技術動向を知る貴重な機会となりました。
印象に残ったセッション
ここからは、メンバーそれぞれが特に印象に残ったセッションを紹介していきます!
さいぴーが選ぶセッション
あなたのWebサービスはAIに自動テストしてもらえる?アクセシビリティツリーで読み解く、AIの『視点』
Yusuke Iwakiさんのセッションに参加してきました。
実は先日、社内のQAチームメンバーからAIを使ったテストケース生成について取り組んでいるという話を聞いたばかりで、
Browser UseやPlaywright MCPなど、ブラウザをAIで操作する手段が増えていく中で、実際にAIがどういう要素をもとにページ構造を分析しているのかに興味をもっていました。
このセッションで取り上げられていた、Browser UseとPlaywright MCPが自然言語の指示やUI要素をどう解釈し、処理するのかという内容はとても学びが多かったです。
特に印象的だったのは、AIがアクセシビリティノードを使ってページを分析しているという事実で、私は今回の発表を聞いて初めて知りました。
さらに、独自実装でUIコンポーネントを作成した場合、アクセシビリティノードが生まれず、AIがページを分析できない状態に陥るリスクがあるという点も非常に重要だと感じました。
このセッションを通じて、「ユーザーに対するアクセシビリティ向上」と「システム運用面でのテストケース生成」という、今まで自分の中では遠かった2つの領域がグッと近づいた印象を持ちました。
アクセシビリティ対応を進めることが、AIによる自動テストの精度向上にもつながるという、領域同士の大きな相乗効果を生み出していきたいですね。
登壇者ご本人によるブログ記事もぜひご覧ください:
2分台で1500examples完走!爆速CIを支える環境構築術
Hayato OKUMOTOさんのセッションでは、RSpecのテストを並列実行で高速化する技術について紹介していました。
AI活用が進むにつれて、コード生成のスピードは飛躍的に上がった一方で、それに対して他のステップの実行速度に目を向ける必要性が出てきています。
コンテナの起動に必要な時間、単体テスト・統合テストの実行時間、デプロイといったCI/CDにかかる時間を併せて削減しないと、開発フロー全体のリードタイムは短縮されません。
このセッションでは、ただ並列化するだけではなく、プロセスごとの実行時間を均すことやディスクアクセス負荷を低減するためにディスクキャッシュを使用するなど、具体的なアプローチが紹介されました。
そして最も面白かったのは、最終的にクラウド上ではなく物理マシンに移行したことが最もインパクトがあったという結論です。様々な最適化手法を試した上での、この大胆な選択は非常に印象的でした。
ココナラ、というより個人的にはテストの実行時間がAI活用の課題になることがあります。このセッションで学んだ最適化手法も含め、すぐにチームに持ち帰り課題シートに起票したので、これから検討を進めていきたいですね。
SpeakerDeckに登壇資料が公開されています:
2重リクエスト完全攻略HANDBOOK
Webサービスを運用する上で、通信路における障害やリトライの可能性を事前に考慮することはとても重要です。
特にココナラでは、サービスの購入や電話相談機能など、多重リクエスト・多重処理が発生するとユーザーのお金や満足度に直結する機能が多くあります。
社内で試行している取り組み以外に新しい知見を得るため、Shohei Mitaniさんのセッションに参加しました。
このセッションでは、対策をクライアント側とバックエンド側で大別し、さらにバックエンド側ではHTTPリクエストレベル、DB、セッションなど、複数の層で多重リクエストを回避する方法を紹介していました。
冪等性の確保、悲観的/楽観的ロック、ワンタイムトークンなど、様々な防止手法が体系的に整理されていて非常に分かりやすかったです。
Railsに限らず、言語やフレームワークに依存しない汎用的な知識が得られたことも大きな収穫でした。この知識は、自社プロダクトに適用するだけでなく、外部APIの調査時にも活きてきます。
このセッションで学んだ知識を、決済周りなどの重要な機能を実装する際の設計レビューでも活かしていきたいと思いました。
SpeakerDeckに登壇資料が公開されています:
「技術負債にならない・間違えない」権限管理の設計と実装
最後に紹介するのはnaro143 (Yusuke Ishimi)さんのセッションです。
権限管理は、システムが成長するにつれて複雑化しがちな領域です。私も最初は単純にadmin?のような条件分岐で作っていたロジックが、いつの間にか条件が複雑になり、修正が怖くてパンドラの箱になる...という過去の苦い経験があります。
このセッションでは、ModelsとPoliciesを1対1で対応させるRails Wayに従うことで、権限管理の仕組みが明瞭になるという手法が紹介されていました。
特に重要だと感じたのは、エンジニアでない方でも、英語が読めれば「誰が何をできるか」を正確に理解できる状態をコード上に作るという点です。
ただ機能として動くものを作るのではなく、CSや運用担当者でも機能名と権限とポリシーをもとにその挙動が正しいかを判断できるという状態を作ることは、プロダクトとしての堅牢性、運用容易性を向上させることに直結します。
ココナラでも、出品者、購入者、コンテンツ執筆者など複数のロールがあり、それぞれができることが異なります。
随所に存在する権限管理機能を整備することで、新たな機能追加を行う際の考慮事項を減らすとともに、誰でも一目で理解できる権限管理の仕組みを構築できる、そのヒントを得られた発表でした。
SpeakerDeckに登壇資料が公開されています:
こうやが選ぶセッション
そのpreloadは必要?──見過ごされたpreloadが技術的負債として爆発した日
mugiさんのセッションでは、N+1対策で多用されるpreloadメソッドを使う際の注意点について、実例を用いて解説されていました。
preloadメソッドはN+1対策として便利ですが、関連データの階層の深さや件数を考慮せずに使うと、不要な大量のActiveRecordインスタンスを取得してしまいます。
プロダクトの成長により、不必要なインスタンスが大きくなりすぎて、Out Of Memoryが発生したという内容でした。
こちらのセッションを拝聴して一番最初に思い浮かんだことは、同様の事例が弊社でも発生しうるということでした。
例えば、弊社ではユーザーが複数のサービスやコンテンツを出品しており、それらが購入された際の決済履歴などがアソシエーションで繋がっています。
ユーザーインスタンスに関連する子インスタンス・孫インスタンスをpreloadで一気に取得しようとすると、Out Of Memoryが起きそうだと思いました。
セッションで学んだ知見に基づき、個人レベルでの対策としては、自分がpreloadを使う際には取得前にデータサイズを見積もったり、preload以外でN+1が回避できるかといったことを考えながらコードを書くようにしたいと思いました。
また、会社としての仕組みでこのような事態を防止するには、オーソドックスなやり方ではありますが、モニタリングをサボらないといったことが必要であると思いました。
SpeakerDeckに登壇資料が公開されています:
Railsによる人工的「設計」入門
こちらはYasuko Ohba (nay3)さんのセッションでした。
内容としては、初心者エンジニアにどのように設計を教えていくかというものでした。
このセッションの中で出てくる初心者エンジニアの事例が、1年くらい前の自分と重なる部分が多かったので、初めて設計にチャレンジしてみる新人君がハマってしまうところは大体同じなのだろうと思いましたw
初心者の傾向として、抽象的な設計をせずに、いきなりテーブル設計やモデル内での具体的なメソッドを考えてしまうということが挙げられていました。
設計に慣れたエンジニアであれば、完成像を先に想定し、そこから機能設計や基本設計、詳細設計という順で設計を進めていくと思います。
しかし、過去の私も含め、初心者エンジニアはその逆の流れで設計しようとしていきます。
完成したシステムやそのシステムがどのように利用されるのかが思い浮かばず、テーブルにどんなカラムを用意するかや、モデルに定義するインスタンスメソッドが先に思い浮かんでしまい、それを積み上げて全体像や設計書を作り上げるという順番で進めてしまいがちです。
結論としては、完成したシステムを先に思い浮かべて、そこから逆算して設計を進めていくというのが対応策でした。
完成したシステムを先に想像して、そのシステムに対する疑問や課題を洗い出していき、それらに対応できるように設計を進めるというのは、慣れていれば当たり前ですが、初心者エンジニアにとっては未知の設計方法です。
シニアクラスやミドルクラスの先輩エンジニアの方は、自分たちが考える設計と初心者エンジニアが考える設計では流れが逆になっているということを認識することから始めないといけないのかもしれません。
その上で、レビューなどでフォローしてあげることが、初心者エンジニアたちの設計力向上に繋がっていくのだと思いました!
SpeakerDeckに登壇資料が公開されています:
とーるが選ぶセッション
もう並列実行は怖くない コネクション枯渇とデッドロック解決の実践的アプローチ
こちらはkatakyoさんのセッションです。
サービス規模の拡大に伴い、大量データ処理のバッチを並列化した際に直面したDBコネクションプール枯渇の問題についての知見共有が行われていました。
スレッド数を増やした結果、DBへの接続要求が急増し、設定されていたActiveRecordのコネクションプールサイズを超過、それに伴いアプリケーション全体でDB接続待ちが発生したというのが起きた問題の全体像でした。
この発生した問題に対して、具体的な対処方法やパラメータ設定の考え方についての内容が発表内で詳細に語られています。
スレッド数 > コネクションプール数 という状況から問題が発生し、問題発生後は下記のようなプロセスを踏んで適切な設定を行うよう改善されたとのことでした。
- DB側の最大コネクション数(max_connections)の確認
- 実行環境(ECS/Sidekiqなど)のタスク数・プロセス数から必要なコネクション総数を算出
- 各設定値の見直し
自分自身も普段から細かい設定値まで意識できていなかったので設定値の算出の話などはとても参考になりました。
また、発表の後半ではバッチ処理や非同期処理のボトルネック特定に役立つツールとしてrack-lineprofというGemが紹介されていました。
このツールによって処理を行単位でプロファイリングし、どの処理がボトルネックになっているのかまでが特定でき、改善に繋がったという学びが共有されています。
業務の内容によってはすぐに活用でき、1つの知見として自分自身の学びにもなりました。
このセッションでは、処理の並列化に関する具体的な失敗例と解決策から、設計、実装時に考慮しておくべきことについて学ぶことができました。
SpeakerDeckに登壇資料が公開されています:
運用力こそがFintechを支える鍵:ohbarye氏が語る5年間のRails実践と高信頼性システムの築き方
こちらはohbaryeさんのセッションです。
Fintech企業における 「運用」 ってどんな取り組みをされているんだろうと気になり、このセッションに参加しました。
とても印象的だったのが 信頼性の定義でした。
システムが落ちないことではなく、ビジネスを可能にすることと定義付けていた点です。
Fintech系の事業を扱う上で処理の遅延、停止はユーザの信用失墜、事業継続の危機に直結する可能性があり、利用者へサービスを提供し続けられる状態を保つ運用力が不可欠であるとのことでした。
この信頼性を実現するために実際の運用に関しても様々な工夫がなされていました。
基本に忠実なアーキテクチャ設計
システム全体は、モノリス(単一リポジトリ)を前提として開発が進められており、
機能単位でnamespace(module)を切り、内部でコードの秩序を保つ工夫が徹底されているようでした。
これにより、数十人体制の開発規模でも責任分界点がわかりやすく維持されているとのことでした。
異常検知と迅速な対応フローの徹底
高信頼性を支えるために「障害は必ず起きる」という前提に立ち、
もしもデータがこうなったらビジネスが毀損されるという視点で異常検知の仕組みが整備されているようでした。
必要なタイミングで必要な情報が得られるような異常検知の仕組みを整えることで速やかに検知、対応が行われ、
高信頼性に繋がっているのだろうなということを感じました。
Runbookの整備
発表の後半で個別の事例、運用に対処するための手順書を強化する取り組みが行われているという話がありました。
Slackの投稿に特定のリアクションを付けるとRunbookがサジェストされる仕組みが用意されていたりなど、
問題発生後、速やかに収束させるために必要な準備もなされているようでした。
自分がこのセッション全体を通して感じたのは基本に忠実な運用が徹底されているということでした。
特に異常検知の仕組みやRunbookの整備の話などは実際の業務にも取り込めそうな話も多く、とても勉強になりました。
SpeakerDeckに登壇資料が公開されています:
よるまが選ぶセッション
2重リクエスト完全攻略HANDBOOK
Shohei Mitaniさんのセッションに参加しました。
Webサービスを運用していると、ネットワークの不安定さやユーザーの操作ミスによって、同じリクエストが複数回送信されてしまうケースに必ず遭遇します。
これはココナラでも起こり得る可能性があり、他人事ではないとセッションを聞きながら感じていました。
本セッション参加後の目線で現状のコードを見ると、潜在的なリスクも洗い出すことができ、非常に有意義でした。
このセッションでは、二重リクエスト対策を8つの手法に体系的に分類して解説していました。
クライアント側では、サブミットボタンのdisabled制御やPRG(Post-Redirect-Get)パターンによるブラウザバックでの再送信防止。
サーバー側では、悲観的ロック(with_lock)や楽観的ロック(lock_version)によるDB層での排他制御、さらにIdempotency-Keyを使ったアプリケーション層での冪等性保証、レートリミットによる連続リクエストの抑制、ワンタイムトークンによるCSRF対策を兼ねた重複防止など、それぞれの手法の特徴と使いどころが明確に整理されていました。
特に重要だと感じたのは、各層での多層防御を前提とした設計思想です。
実際の運用では、単一の対策では不十分なケースが多々あります。例えば、モバイルネットワークの不安定な環境では、ユーザーの意図しないところでブラウザやHTTPクライアントがリトライを実行することがあり、フロントエンドのボタン制御だけでは防ぎきれません。
また、リバースプロキシやCDNがタイムアウトでリトライするケース、決済ゲートウェイ側のレスポンス遅延によるアプリケーション側のリトライなど、複数の経路から重複リクエストが発生しうるため、HTTP層、アプリケーション層、データベース層それぞれで防御する必要があります。
セッションで特に学びになったのが、Idempotency Keyの実装における注意点です。
フォーム表示時にUUIDを生成してhiddenフィールドに埋め込み、サーバー側ではそのキーでユニーク制約を持つカラム(idempotency_key)を用意するという基本的な実装方針は理解していましたが、データベースのユニーク制約違反をキャッチする際の細かい考慮点までは意識できていませんでした。
例えば、ActiveRecord::RecordNotUnique例外をキャッチして既存のレコードを返す実装では、トランザクション分離レベルによってはレースコンディションが発生する可能性があり、確実に既存レコードが取得できることを保証する設計が必要だと学びました。
このような実装レベルの落とし穴を知ることができたのは大きな学びでした。
また、外部の決済APIやWebhookとの連携においても冪等性の保証が重要です。
決済サービスからのWebhookイベントは、ネットワーク障害やタイムアウトにより同じイベントIDで複数回送られる可能性があるため、処理済みイベントIDをテーブルに記録して重複実行を防ぐ設計が不可欠です。
この際、イベント処理とイベントID記録のアトミック性を保証するため、両者を同一トランザクション内で実行する設計が望ましいと学びました。
APIリクエスト時にIdempotency Keyを渡すことで、API側でも重複処理を防げるという二重の防御が可能です。
このセッションで学んだ多層防御の考え方と具体的な実装パターンを用いて、ココナラの決済フローを見返し適用できる箇所には適用していきたいです。
技術的負債として放置すればするほどリスクが高まるため、優先度を上げてチームで取り組むのが良さそうです。
SpeakerDeckに登壇資料が公開されています:
サービスクラスについて考える - Fat Modelからの脱却
Tomohiro HashidateさんのRails開発における設計パターンについてのセッションにも参加しました。
ココナラのコードベースを見ていると、UserモデルがかなりのFatで、ドメインの異なる複数の機能と責務が混在というよくある構造です。
決済関連のメソッド、統計・分析メソッド、外部サービス連携のロジックなどなどが同じモデルに同居しており、外部APIとの密結合も発生しています。
単に行数が多いだけでなく、変更時の認知負荷が高く、予期せぬ副作用が発生しやすいという本質的な課題を抱えています。
一つのメソッドを修正する際に、他の無関係なメソッドへの影響を考慮しなければならず、結果としてテストカバレッジを上げてもリグレッションのリスクが残り続けます。
このセッションでは、レイヤードアーキテクチャの導入によってビジネスロジックを適切に分離する手法が紹介されていました。
重要なのは、単なる「きれいなコード」ではなく、変更の局所化とテスタビリティの向上です。
フォームクラス(パラメータハンドリングとバリデーション)、サービスクラス(ビジネスロジックの実行)、クエリオブジェクト(複雑なクエリロジック)という3つの層に分けることで、それぞれの変更理由が明確になり、修正時の影響範囲を予測しやすくなる、ということを説明していました。
フォームクラスはActiveModel::Modelを使い、コントローラーから受け取ったパラメータのバリデーションと初期処理を担当します。
この層を分離することで、パラメータの検証ロジックとビジネスロジックを独立してテストできるようになります。
サービスクラスは外部APIとの連携やトランザクション管理、ドメインルールの適用を行い、クエリオブジェクトは複雑な検索条件やスコープを切り出します。
特に実感したのは、「外部APIとの密結合を避ける」ことの重要性です。
現在のモデルには決済処理や外部サービス連携のロジックが直接書かれており、外部サービスのAPIバージョンアップやサービス変更の際に、ドメインロジックまで影響を受けるリスクがあります。
サービスクラスに外部APIとの連携を切り出すことで、ドメインロジックとインフラストラクチャを分離し、外部サービスの変更をサービスクラス内で吸収できます。
また、テスト時にはモックを使って外部API呼び出しをスタブ化でき、テストの実行速度と安定性が大幅に向上します。
実装時の注意点として、過度な抽象化を避けることも重要です。
例えば、サブスクリプション管理を担当するサービスクラスを作る際、「将来的に別の決済サービスに切り替えるかもしれない」という理由で複雑なインターフェースを設計すると、かえってチームの認知負荷が上がります。
まずは具体的な実装から始め、実際に変更が必要になったタイミングで抽象化を検討する方が、実用的なアーキテクチャになります。
コントローラーはフォームクラスにパラメータを渡してバリデーションし、フォームがサービスクラスを呼び出すという流れにすることで、各層の責務が明確になります。
さらに長期的には、モジュラーモノリス設計として境界付けられたコンテキスト(Bounded Contexts)を導入する可能性も感じました。
決済、コンテンツ、認証・認可、通知などのコンテキストを明確に分け、コンテキスト間の通信はイベント駆動で行うことで、各コンテキストが独立して進化できるようになります。
ただし、これも段階的なアプローチが重要で、いきなり全体を再設計するのではなく、新機能開発や大きなリファクタリングのタイミングで徐々に適用していく戦略が現実的です。
まずは小さく始めて、重要度の高い機能から段階的にリファクタリングを進め、チーム全体でアーキテクチャ改善を進めて行くのが良さそうです。
このセッションで得た知見は、ココナラの技術的負債解消とコード品質向上、そして開発生産性の向上に大きく貢献できるものと考えています。
SpeakerDeckに登壇資料が公開されています:
全体を通じて
Kaigi on Rails 2025は、初心者から経験豊富なプロフェッショナルまで幅広い参加者層が集まるカンファレンスでした。オフライン会場ではリアルタイム翻訳(日本語→英語)の仕組み(このイベント専用に作ったとのこと!)が導入されており、聴衆体験への配慮が多く見られました。
全体のセッションを通じて感じたのは、AIが広く普及した今の開発現場では、コーディング以外のステップにも目を向ける重要性が高まっているということです。CI/CDの高速化、テスト自動化、アクセシビリティ対応など、開発周辺領域の最適化が競争力を左右します。今後は企画やデザイン、QA、運用といった領域を含めてシームレスに開発を進められる企業が生き残っていくでしょう。私たちココナラのエンジニアも、日々の業務の中で越境を意識した動きを取り入れていきたいと思います。
最後に
ココナラでは、一緒に事業のグロースを推進していただける様々な領域のエンジニアを募集しています。
Ruby on Railsを使った開発だけでなく、フロントエンド領域・インフラ領域などでも積極的にエンジニア採用を行っています。
少しでも興味を持たれた方がいましたら、エンジニア採用ページをご覧ください。
Discussion