エニグモのアドベントカレンダー2025の振り返りと運営の工夫

こんにちは。
エニグモ採用担当の戸井です。

普段は中途採用や採用広報を担当していますが、主にエンジニア採用を担当している関係で、エンジニア組織の「Developer Relations(DevRel)チーム」にも所属しています。
DevRelチームはエンジニア組織のアウトプット促進や勉強会の運営やイベントサポートなどを行っており、その一環としてアドベントカレンダーの運営にも携わっています。

この記事では昨年実施したアドベントカレンダー全体の振り返りと、運営の取り組みについて紹介します。

アドベントカレンダーとは?

元々は、クリスマスまでの日数をカウントダウンするために使われるカレンダーで、12月1日からはじまり、25個ある「窓」を毎日1つずつ開けて中に入っている小さなお菓子やプレゼントを楽しむものです。
その慣習から、12月1日から25日まで毎日ブログ記事を公開するイベントとして、特にWeb業界やエンジニア界隈で広く親しまれています。

2025年のエニグモアドベントカレンダーはこちらです。
https://qiita.com/advent-calendar/2025/enigmo

2025年アドベントカレンダー全体の振り返り

エニグモのアドベントカレンダーは2018年よりスタートし、2025年で開催8回目となりました。
当初はエンジニア・テック系職種を中心とした取り組みでしたが、2022年からは全社イベントとして、職種問わず誰でも参加できる形で運営しています。

参加メンバーの傾向

2025年も、エンジニアを中心にさまざまな職種のメンバーが参加しました。

(内訳)
【エンジニア職種】
サーバーサイドエンジニア、インフラエンジニア、データエンジニア、検索エンジニア、データサイエンティストなど
【ビジネス職種】
マーケティング、データアナリスト、UI/UXデザイナー、管理部門など

技術系職種を中心としつつも、データ・デザイン・コーポレートなど、複数の部門から参加があり、職種横断でのアウトプットの場となりました。

また、参加回数の観点では、初めて参加するメンバーが全体の約4割を占めていました。
一方で、複数回参加しているメンバーや皆勤賞のメンバーもおり、継続的にアウトプットの場として活用されている点も特徴です。
アドベントカレンダーを一年間の振り返りやナレッジの棚卸しの機会として活用しているメンバーも多いです。

記事のテーマ・カテゴリ

記事のカテゴリーを以下の4つに分類し、集計を行いました。

・技術発信
・プロジェクト紹介
・組織・カルチャー
・入社エントリ・自己紹介
2025年は、技術発信の記事が全体の多くを占めており、エンジニアリングに関する知見の共有が中心となりました。
他にも組織やカルチャー、プロジェクト紹介、入社エントリ・自己紹介といったテーマの記事も投稿されています。

技術に限らず、個人の経験や組織の取り組みなど、多様な切り口での発信が行われたことも特徴です。 

「Advent Calendar Award」受賞記事

「Advent Calendar Award」はエニグモのアドベントカレンダーをさらに盛り上げるために実施しており、特に多く読まれた記事を表彰しています。
2025年の受賞記事は以下の通りです。

6位 アジャイルは会社ごとに別物。でも、あるあるは共通だった(BUYMA TRAVEL Webエンジニア)
5位:ローコードAIツールDifyをエンジニアが使ったら?コードブロックでハマった7つの落とし穴(データサイエンティスト)
4位:エニグモのオンボーディング:他部署体験プログラムを紹介します!(採用・採用広報担当)
3位:人事からデータアナリストへ。社内公募で兼務し始めて3ヶ月の振り返り(人事兼データアナリスト)
2位:AWSにおけるコスト削減の考え方(インフラエンジニア)
1位:Ruby on Rails アプリのパフォーマンス最適化10選(バックエンドエンジニア)

運営の取り組み

アドベントカレンダーの運営では、キックオフの実施タイミングや日々のリマインド、ガイドライン整備、執筆・レビューの進め方など、運営に関わる各プロセスを毎年アップデートしています。

また、当社のメイン事業である海外ファッションEC「BUYMA」では、年末に向けた大型セールや需要の高まりにより、12月は特にサイトへのアクセスや取引が増える時期です。
それに伴い、エンジニア側でも重要なリリースや対応が重なるタイミングとなります。

そのため、アドベントカレンダーも参加メンバー・運営側の双方にとって、無理なく継続できるよう運営を設計しています。

ここでは、こうした背景を踏まえつつ、今年特に注力した取り組みについて紹介します。

ここ2〜3年で入社したメンバーの中には、アドベントカレンダーへの参加経験がない方や、テックブログ執筆が初めての方も一定数いました。
そのため、「初めてでも参加しやすい状態をつくること」を意識しました。

具体的には、エニグモで初めてテックブログを書く方向けに、記事のテーマの考え方や執筆の進め方を解説するレクチャー会を実施しました。

レクチャー会では、以下のような内容を扱いました。

  • 記事を書く目的の共有
  • テーマの考え方
  • 記事の構成や書き方

レクチャー会の資料
テーマの考え方を説明した後は、実際に記事を書き進める際の流れについても、画面共有でデモンストレーションを行いました。
テーマ決定から情報整理、構成作成、リード文やタイトル作成までの流れをステップごとに分解し、「どのように記事を組み立てていくのか」をイメージできるようにしています。

また、ワークショップ形式を取り入れ、参加者がチームに分かれてテーマの検討や構成作成に取り組みながら、相談やディスカッションを行う時間を設けました。

ワークの中では、
* どのようなテーマを選んだか
* テーマ設定で悩んだポイント
* 書こうとしている内容や構成
* 書く中で詰まりそうな点
などを共有しながら進めてもらいました。

最後には全体でテーマや悩みを共有する時間も設け、他のメンバーの視点に触れることで、「自分の経験も記事になる」という実感につながるよう設計しました。

また、全体向けのレクチャーに加え、特に入社間もないメンバーに対しては個別に声がけを行い、テーマ設定や執筆の進め方についてフォローを行いました。
ショートミーティングを実施し、これまでの業務や担当プロジェクトを振り返りながら、その中にある技術的な工夫や、入社直後だからこそ気づけた改善点などをテーマとして言語化するサポートを行いました。

運営を通じた振り返り

今回は、例年の運営フローをベースにしながらも、初めて参加するメンバーへのサポートを強化したことが特徴でした。

その結果、新たに参加したメンバーが増えたことは、運営面でも大きな収穫だったと考えています。

レクチャー会に参加したものの、今回のアドベントカレンダーには参加できなかったメンバーも、「自分の経験でも記事を書けそう」「いつか書いてみたい」と感じるきっかけになっていれば、次回以降の参加につながる土台にはなっていると考えています。

アドベントカレンダーは年に一度の期間限定イベントではありますが、こうした毎年の積み重ねが、継続的なアウトプット文化を広げる大きなきっかけになると感じました。

また、今回の運用を通じて、いくつか改善したいポイントもあります。

まず、公開前のレビューが一部のメンバーに集中する場面がありました。
今後は、レビュー観点を整理したテンプレートの整備や、AIを活用したレビュー支援なども検討し、よりスムーズに進められる体制を整えていきたいと考えています。

また、アドベントカレンダーに限らず、継続的に発信しやすい状態をつくることも重要だと感じています。
そのため現在は、日常的なアウトプットを促進する仕組みづくりにも取り組んでいます。

さいごに

2025年もエニグモのアドベントカレンダーは、無事25日完走することができました。
従来の運営フローをベースにしつつ、初めて執筆するメンバーへのサポートを強化したことで、新しい参加の広がりにもつながりました。

今後も、より継続的に情報発信しやすい運営を目指していきます。

これからのエニグモ開発者ブログの発信を、ぜひご覧いただけると嬉しいです。

AI駆動開発とベンチャー回帰で創る次世代エンジニア組織

こんにちはVPoEの木村です。

会社として新年度を迎え少し経ちましたが、先月頭、エンジニア組織の今期以降の運営方針を社内向けに発表しました。今回はその方針について、ブログでもご紹介したいと思います。 テーマは「AIの最大活用〜新開発フロー・体制へ移行〜」「ベンチャー回帰〜ビジネス成果への直接貢献〜」です。

先期の振り返り
 〜再確認した内製エンジニア組織としての存在意義とAIの力〜

先期を振り返る時に欠かせないトピックとしてまず挙げられるのが、大規模メンテナンスを実施し、BUYMAのインフラ基盤をオンプレからAWSへ移行したことです。 事前に最大限リスクを取り除く努力はしたものの、一定のリスクを伴うビッグバン方式での移行になりましたが、やり遂げた後としては、なんとか力技で捩じ伏せることができたようなベンチャー感を思い出す感覚がありました。

長年運営してきたサービスの癖やパターンを知り尽くし、何があってもサービスを動かし続けてきた内製エンジニア組織だからこそ採れたアプローチだと思います。 また、時間的・人員的なリソースも十分とは言えないなかでも、AIをカウントされないプロジェクトメンバーとして、移行日直前に「本当はやりたいけど時間がない」という追い込みの作業を実現したり、移設中・直後の不具合調査の高速化などに活用することができました。

AI活用についてはそれ以外にも業務面、プロダクト面にも進み、リリースできた様々な機能追加や改善を振り返ると、数年分の成果を1年に詰め込んだような実りの多い期だったと感じます。今期はそんな成功パターンを組織全体へスケールさせていくため、「AIの最大活用」と「ベンチャー回帰」をテーマに前年踏襲をやめ、ドラスティックな方針転換を図ります。


方針1:AIの最大活用 〜新開発フロー・体制へ移行〜

「AIに仕事を奪われるのでは?」という漠然とした不安を持つのではなく、「全員でAI武装し『アベンジャーズ』になろう」というのが私たちのスタンスです。AIをフル活用可能な開発フローと体制に移行していきます。

新開発フロー

単なる作業の効率化にとどまらず、再構築された価値提供のパイプラインを生み出すために、下図のとおり全く新しいAI駆動開発フローへの移行を進めます。

AI駆動開発フロー

新開発フローのステップは以下の通りです。

  1. 設計(人間+AI): Notion上でドキュメント作成。Notion AIを活用してPRD、要件定義書、タスク分解・計画を生成します。
  2. 仮実装(AI単独): ドキュメントをコンテキストとして、AIがIssueを立ててブランチ作成、実装、Pull Request作成までを完全自動化します。
  3. 本実装(人間+AI): 仮実装をチェックアウトし、Cursorを活用してローカルで動作確認・仕上げを実施します。
  4. レビュー(AI→人間): AIによる静的解析と事前レビューを通過したものだけを人間がレビューします。

本フローを構築していくにあたり、細かいツールや技術選定は詰めていく必要はあるものの、ナレッジ管理ツールとして利用していたesaと、プロジェクト管理ツールとして利用していたRedmine/JiraはNotionへ移行・統合していきます。また、コード管理・CI/CDの基盤としてセルフマネージドでGitLabを利用してきましたが、生成AIのエコシステムへの統合がより進んでいるGitHubへと移行します。

このフローでは2の仮実装という、AIにより完全自動化されたステップが組み込まれていることがポイントです。これにより下図のように実装時の調整やQAでの不具合はすべてドキュメントにフィードバックされ、ドキュメントの成熟とともにAIで完全自動化されたステップの精度が向上し、全体が省力化され続けるサイクルを構築します。

AI駆動開発成熟の仕組み

新開発体制へ

また、AIの支援により、今後は誰もが「知識のフルスタック化」を実現できる時代です。1人のマネージャーが複数チームをマネジメントするのはもちろん、フロントエンドエンジニアがバックエンドも含めてリードするなど、単独でもユーザーに価値提供できる「PM兼アーキテクト」として振る舞える人材を増やしていきます。

フルスタックへの回帰・フルサイクルへの挑戦

これはこれまで分業化や専門性特化のチームを作ってきた流れからの方針転換となり、個人やチームのフルスタック化フルサイクル化を進めていきます。


方針2:ベンチャー回帰 〜ビジネス成果への直接貢献〜

AIによってデリバリー(実装)が超効率化されていく今後、エンジニアは浮いたリソースで何を目指すべきでしょうか? その答えが「ベンチャー回帰」です(2000年代創業の弊社としては、スタートアップというよりベンチャーという言葉がしっくりきます)。

フィーチャーチームからミッションチームへ

これまで、部としてはプロダクト開発のエンジニアをドメインと呼ばれる3つのチームに分けて運用してきており、それらは単に開発・運用する機能が割り振られた括りでしかありませんでした。 しかし今期からは、すべてのドメインがユーザーに直接届く「ビジネスミッション」を持つ体制へと方針転換します。

  • BUY: 購入者を強力に吸い上げ、集客とCVRを最大化する。
  • SELL: 世界中から商品を力強く吸い上げ、品揃えを最大化する。
  • SERVICE INFRA (SI): 決済や安心補償などの機能を提供し、ユーザーへの提供付加価値を最大化する。

単なる機能開発ではなく、全員が事業のKPIに直結したミッションを追い求める。この構造こそが、私たちの目指す真のベンチャー回帰の姿です。

新キャリアラダーを設計

また、全員がビジネス成果にコミットする組織へ進化するため、エンジニアのキャリアラダー(評価軸)もアップデートしました。従来の「デリバリー」中心の評価から、以下の6つの軸による評価へと拡張しています。

  • アウトカム :事業成果に接続した意思決定ができているか。
  • ディスカバリー :ユーザーの課題を正しく再定義できるか。
  • デリバリー: 設計〜実装〜テスト〜リリースを安定して回せるか。
  • 運用:SLO/障害/コスト/セキュリティを背負えるか。
  • コラボレーション(協働) :チームビルディングや他職種との協働。
  • レバレッジ : 仕組み化・標準化により、組織全体の生産性を引き上げる力。

実はこの6軸は、元々「AI時代に合わせよう」として作ったものではありません。先期の振り返りで再認識した「外部パートナーにはできない、内製エンジニア組織ならではの価値とは何か?」を徹底的に言語化した結果生まれたものです。

しかし興味深いことに、「内製組織の本質」を追求したこの6軸は、AI活用が進む時代にエンジニアに求められると思われるスキルセットとしてみても全く不自然ではありませんでした。

例えば、AIで簡単にモノが作れるようになったからこそ、「どこまでこだわるべきか」を事業成果から逆算するアウトカムや、本質的なユーザー課題を見極めるディスカバリーの重要性が増しています。また、AIには代替できない人間同士の高度なコラボレーションも不可欠です。

中でも「レバレッジ」は、次世代エンジニアのコアとなる概念です。日々の案件を無事にデリバリーするだけでなく、「AI駆動開発を実現し、価値提供のパイプライン自体を自分たちで構築・改善する(仕組みを創る)」ことが求められます。この仕組み作りは専任チームに任せるのではなく、各チーム自らが構築し、組織全体をブーストさせる姿勢を高く評価します。

まとめ

以上が、今期からのエンジニア組織の新しい運営方針です。

今のエニグモの環境で「事業にコミットし、AIで開発パイプライン自体を創り上げる」という経験は、こちらの記事でも語られているどこに行っても通用する非常に高い市場価値につながると確信しています。

この方針は決して理想を描いただけではありません。先期のAI活用の実績という裏付けがあり、NotionやGitHub、AIコーディングエージェントを全社で導入するための予算もしっかり確保してスタートしています。

「いつかできたら」ではなく「今年できる」。今期もこのスローガンを胸に、圧倒的な成果を生み出す1年に していきたいと思います。

AI時代のPdMの武器は「土壌」にある。BUYMAの歴史をレバレッジに、高速で仮説を形にする方法

はじめに

KNと申します。 2025年2月に株式会社エニグモに入社し、プロダクトマネージャー(PdM)として約1年が経過しました。

前職では新卒でWeb系企業にエンジニアとして入社し、3年間従事しました。 文系出身ながらAWSでのインフラ構築・メンテナンスからバックエンド・フロントエンドの開発まで、幅広く経験しました。

その後、社内転職でPdMへとキャリアをシフトし、フィンテックサービスのグロースを担当していました。

私がエニグモへの転職を決めたのは、20年続く「BUYMA」というプロダクトが持つ圧倒的な蓄積に惹かれたからです。

しかし同時に、「歴史があるがゆえに、動きが遅く、部分最適の調整に追われるのではないか」という懸念もありました。

結果として、この1年間で得られたものは予想を遥かに超えるものでした。 この記事では、エニグモで経験した学びと、20年続くプロダクトの「厚み」がもたらす価値について記します。

自身の業務領域

BUYMAは世界180カ国、22.5万人以上のパーソナルショッパー(出品者)が支える、唯一無二の「お買い物代行」プラットフォームです。

現在、私はBUYMA「出品者領域(SELL)」と、決済・配送・基盤を支える「サービスインフラ(SI)」の2つを横断して担当しています。

  • SELL領域: 出品者がいかにストレスなく、質の高い出品を行えるか
  • SI領域: 配送、決済、CS、経理。取引の全工程を支える「心臓部」

この2つを同時に見ることは、一見すると負荷が高いように思えます。

しかし、「出品の仕様変更が、数カ月後の経理処理やCSの問い合わせにどう影響するか」を予見しながら動く経験は、プロダクトを「機能の集合体(点)」ではなく「エコシステム(面)」として捉える視座を私に与えてくれました。

エニグモの組織図

入社の決め手:20年の蓄積がもたらす土壌

転職活動をしていた当時、私が最も重視していたのは「自身の仮説構築や施策立案の精度を向上させること」でした。

前職の新規事業では、スピード感を持って施策を回していましたが、比較対象となる過去データが少なく、「打席には立つが、なぜ当たった(外れた)かの深い洞察」が不足している感覚がありました。

2005年から続くBUYMAには、膨大な成功と、それを上回る「失敗の経験」があるのではないかと仮定していました。それは、自身が望む次の仮説を研ぎ澄ませるために非常に魅力的な場所だと感じました。

あえて歴史のある環境に身を置くことで、中長期的な時間軸での「判断の軸」を手に入れ、今後どのようなフェーズのプロダクトでも通用するPdMになりたいと考えたのが、入社の最大の理由です。

www.buyma.com

入社後の学び

①バランス感覚が求められる

エニグモで最も鍛えられたのは、複数の視点を同時に持ち、全体最適を追求するバランス感覚です。

入社後に手がけた印象的なプロジェクトに、経理が企画を行った出品者に関連する機能開発がありました。 このプロジェクトは、経理、カスタマーサポート、出品者側のマーケティング、エンジニア、デザイナーという多様な職種が集まったチームで進行しました。

プロジェクトの仕様決めの場面で、私は初めて「歴史の重さ」を実感しました。 経理上の運用フローもあり、社内ニーズとユーザーニーズを調和させた運用となっていました。

その上で、機能開発という観点から出品者にとっての使いやすさ(ユーザービリティ)も確保しなければなりません。 さらに、問い合わせが発生した際のカスタマーサポートの対応負荷も事前に検討しておく必要がありました。

このように、1つの意思決定が複数の部署に影響を及ぼします。 そして、20年の歴史があるプロダクトでは、1つのルールを変更するだけでも、システム的にもビジネス的にも背景が膨大にあるため、定点を見て結論を出すことができません。

エニグモでは「出品者・購入者・プラットフォーマーとしてのルール作り・ルールを維持するための運用的可能性」という多面的な視点を同時に持つ必要があります。 この多面的なバランス感覚こそ、今後どのようなプロダクトに関わっても活かせる、PdMとしての生存戦略の核だと感じています。

②組織のノウハウに対するレバレッジ

エニグモには、社歴が長い人が多く在籍しています。 先輩方はBUYMAの歴史を肌で知り、過去の成功と失敗を体験してきています。 ※平均勤続年数は6.3年(2025年10月時点)

入社当初、私は自分がまだ知らない領域について不安を感じていました。 しかし、実際に働いてみて気づいたのは、「自分がすべてを知っている必要はない」ということでした。 重要なのは、知識を持っている人が何を気にしていて、どのようなデータがあり、組織としてどこでバランスを取るべきかを考え、意思決定に繋げることです。

多くのプロジェクトでは、過去の事例やデータが膨大にあるため、各部署の担当者の背景理解や考慮すべき点の想定を事前から広く取ることが可能です。

例えば、カスタマーサポートのメンバーに相談すると、「過去に類似の仕様変更を実施した際、こういった問い合わせが急増した」という実例を教えてくれます。 経理企画のメンバーに相談すると、「この処理フローは○年前にこういう理由で導入された」という背景を共有してくれます。

また、過去の意思決定に関するドキュメントが残っているため、ノウハウの探索がしやすいのも大きな利点です。 考慮しなければならない箇所や、とある対応策を取ろうとした時のメリット・デメリットの整理がしやすくなります。

これらの知見は、組織に蓄積された「ノウハウ」です。 エニグモでは「誰に聞けば良いか」「どのデータを見れば良いか」「過去のどのドキュメントを参照すれば良いか」を知っていれば、圧倒的に速く、精度の高い意思決定ができます。

そして、PdMの役割は、そのノウハウをレバレッジとして活用し、最適な意思決定を導くことです。 この組織知へのアクセス能力は、AIが進化しても決して代替されない、人間ならではの強みだと考えています。

③意思決定の質とスピード

エニグモでは、開発案件に応じてスクラムアジャイルを使い分けながら開発を進めています。 サービスインフラ(SI)領域を例にとる、ビジネスサイドは10〜15名程度、エンジニアが5〜8名程度、PdMが2名程度で進行しており、密に連携しながら施策を推進します。

驚いたのは、意思決定のスピードと質の両立です。 前職では、スピード重視で施策を回していましたが、データが不足しているために「やってみなければわからない」という状況が多くありました。 一方、エニグモでは20年分のデータとノウハウがあるため、「過去の類似施策ではこうだった」「このセグメントのユーザーはこう動く」という根拠に基づいた意思決定ができます。 また、AI活用も積極的に進められています。例えば、BUYMAには「AIでさがす」機能があり、Vertex AI SearchやGeminiを活用し、よりBUYMAらしい商品提案が可能になりました。

『「AIでさがす」サービスのリニューアル』について

このように、歴史という「深い土壌」とAIという「速い道具」が揃っていることで、意思決定の質とスピードが同時に高まっています。 AIによって解決できる課題の量と幅は拡張されていますが、「何を解くべきか」を判断するのは人間の役割です。 そして、その判断の精度を高めるのが、プロダクトの厚みから得られる「物事の見方」と「意思決定プロセスの判断軸」です。

歴史の重さと向き合う難しさ

ここまでポジティブな面を中心に書いてきましたが、正直に言えば、苦労したポイントもあります。

各部署との調整と、歴史の重さを考慮した意思決定は、想像以上に難しいものでした。 1つのルールを変更するにしても、その変更がシステム的にもビジネス的にも背景が膨大にあるため、定点を見て結論を出すことができません。

複数の部署の意見を聞き、過去のドキュメントを読み込み、データを分析し、そして全体最適を追求する。 このプロセスは、スピード重視の新規事業とは異なる難しさがあります。

しかし、この「難しさ」こそが、PdMとしての成長を促してくれていると感じています。 なぜなら、今後どのようなプロダクトに関わっても活きる「面と深さを考えながらプロダクトを進行する」という実践知を経験できているからです。

今後やっていきたいこと

この1年間で、私はプロダクトを「点」ではなく「面」で捉える視座を手に入れました。

SELL領域とSI領域を横断して担当することで、出品者の体験、購入者の体験、そしてそれらを支える基盤(経理・配送・決済)、すべてが繋がっていることを実感しています。

しかし、まだ「面」のすべてを理解しているわけではありません。 今後は、一部門だけでなく、ユーザー体験全体を「面」で捉え、形にしていくことに挑戦したいと考えています。

エニグモには、歴史という「深い土壌」と、AIという「速い道具」が揃っています。 この環境だからこそ、幅広く、深く、そして「形」にして、面としてのプロダクト磨きに取り組めると確信しています。

BUYMAは20周年を迎え、さらなる進化を続けています。私自身も、この蓄積の中で、PdMとしての生存戦略を磨き続けていきたいと思います。

エニグモで働く魅力

最後に、エニグモで働く魅力をまとめます。

プロダクト・人材面でしっかりとした土壌がある

20年分のデータとノウハウ、そして社歴の長いメンバーが持つ知見。これらは、新規事業では決して得られない「厚み」です。 過去の意思決定に関するドキュメントが残っているため、ノウハウの探索がしやすく、考慮すべき点の整理が圧倒的に速くなります。

幅広く・高速にチャレンジができる

AI活用やアジャイル開発により、意思決定のスピードと質が両立されています。 若手でも裁量を持ってプロジェクトを推進できる環境です。 「AIでさがす」機能や類似画像検索の内製化など、最先端の技術を活用した施策に取り組めます。

バランス感覚が磨かれる

経理・出品者・カスタマーサポート・プロダクト全体という多面的な視点を持つことで、どのプロダクトにも通用する「究極のバランス感覚」が身につきます。

 「専門性か、汎用性か」で迷うあなたへ。

エニグモには、専門性を深めながら、汎用性も高められる環境があります。 AIに奪われない組織知をレバレッジとして活用し、プロダクト開発を通じて自己成長できる場所です。 もし、あなたがキャリア形成に不安を感じているなら、エニグモという「最強の土壌」で、一緒にプロダクトを磨いていきませんか。

株式会社エニグモ すべての求人一覧 hrmos.co

【BigQuery】過去データの再作成が超絶楽になる!ループ処理でシャーディングテーブルを一気に作成する方法

こんにちは、エニグモの嘉松です。普段はデータ活用推進室にて、データ分析・データ活用の推進やMAツールを用いたCRM施策などを担当しています。

本記事はEnigmo Advent Calendar 2025の最終日(25日目)の記事です。1ヶ月間にわたり様々なテーマで繋いできたバトンも、いよいよ今回が最終回となります!

最終回は、データ分析・データ活用の裏側を支える技術にフォーカスし、BigQueryに関する(少しディープな)知見を共有します。

時点データとは?

データ分析において、現時点のデータだけでなく「過去のある時点」のデータを保持しておくことは極めて重要です。例えば、ユーザーの注文回数、会員ランク、保有ポイント数、メール購読の有無などが挙げられます。

これらの時点データを毎月1日などのタイミングでスナップショットとして蓄積しておくことで、「過去と現在の比較」や「特定の期間における推移」といった分析が容易になり、分析の幅は劇的に広がります。

しかし、過去に遡ってこれらのデータを作成しようとすると、なかなかの手間が発生します。例えば月次データを5年分作成する場合では60回のクエリ実行が必要となります。

そこで今回は、BigQueryの手続き型言語(Procedural language)を使い、ループ処理で過去分のシャーディングテーブルを一気に作成する方法をご紹介します。

BigQueryのシャーディングテーブルとは?

table_YYYYMMDD という命名規則に基づき、物理的にテーブルを分割して管理する手法です。 例えば、user_summary_20251201 のようにテーブル名の末尾に日付を付与します。

シャーディングを行うことで、必要な期間のデータだけをスキャン対象にできるため、処理に必要なデータ量およびクエリ費用を大幅に抑えることが可能です。

シャーディングテーブル作成の処理フロー

今回の処理の流れは以下の通りです。

  1. 指定した「開始年月」から「現在」まで、1ヶ月ごとにループさせる。
  2. 各月ごとに集計クエリを実行し、table_YYYYMMDD 形式のテーブルを作成(または置換)する。
  3. 処理対象が現在を超えたらループを終了する。
START_MONTH (2022-01-01)
    ↓
[ LOOP開始 ]
    ↓
1回目: 対象 2022-01-01 → CREATE TABLE dataset.table_20220101
2回目: 対象 2022-02-01 → CREATE TABLE dataset.table_20220201
    ...
終了: 対象が「今月」を超えたら LEAVE

サンプルコード

以下は、ループ処理を用いて過去テーブルを作成するスクリプトです。

-- 1. 変数の宣言と初期化
DECLARE START_MONTH DATE DEFAULT DATE '2022-01-01'; -- 開始日を指定
DECLARE CURRENT_MONTH DATE;
DECLARE yyyymmdd STRING;
DECLARE LOOP_CNT INT64 DEFAULT 0;

-- 2. ループ処理の開始
LOOP
  -- 処理対象年月をセット(開始月からLOOP_CNT分だけ月を加算)
  SET CURRENT_MONTH = DATE_ADD(START_MONTH, INTERVAL LOOP_CNT MONTH);

  -- 3. 終了判定:処理対象年月が「今月」を超えたらループを抜ける
  IF CURRENT_MONTH > DATE_TRUNC(CURRENT_DATE('Asia/Tokyo'), MONTH) THEN
    LEAVE;
  END IF;

  -- テーブル接尾辞用にYYYYMMDD形式の文字列を作成
  SET yyyymmdd = FORMAT_DATE("%Y%m%d", CURRENT_MONTH);
  
  -- 4. 動的SQLの生成と実行
  -- EXECUTE IMMEDIATE FORMAT() でSQLを動的に組み立てて実行します
  EXECUTE IMMEDIATE FORMAT("""
    -- ここに実行したいDDL(テーブル作成)を記述
    CREATE OR REPLACE TABLE `your-project.your_dataset.user_summary_%s` AS
    SELECT
      user_id,
      -- 注文回数
      count(*) as purchase_count
    FROM
      `your-project.source_dataset.transactions`
    WHERE
      -- 基準日(CURRENT_MONTH)以前の注文データに絞り込み
      DATE(created_at, 'Asia/Tokyo') < '%s'
    GROUP BY
      1
  """, yyyymmdd, CAST(CURRENT_MONTH AS STRING));

  -- 5. カウンタを進める
  SET LOOP_CNT = LOOP_CNT + 1;

END LOOP;

サンプルコードの解説

実装のポイントは以下の3点です。

1. LOOPLEAVE による制御

BigQueryの手続き型言語には FOR 文もありますが、日付を柔軟に加算しながら処理したい場合は LOOP が適しています。無限ループを防ぐため、必ず IF ... THEN LEAVE; END IF; による脱出条件を記述しましょう。今回は DATE_TRUNC を使い、実行時の年月を超えた時点で停止するように設定しています。

2. EXECUTE IMMEDIATE による動的SQLの実行

通常のSQL文には変数を直接埋め込むことができない箇所(テーブル名など)があります。そのため、クエリ全体を文字列として組み立てて実行する EXECUTE IMMEDIATE を使用します。 FORMAT() 関数を用いると、%s を使って変数値を流し込めるため、文字列結合(||)を繰り返すよりも可読性が高く、メンテナンスもしやすくなります。

3. 文字列のクォート扱いに注意

ここが最も重要なポイントです。動的SQLの中で日付をリテラルとして扱いたい場合、%s の周りをシングルクォートで囲む必要があります。

  • NG: DATE(created_at, 'Asia/Tokyo') < %s
  • 展開後: ... < 2022-01-01 (数値の引き算として処理されてしまう)

  • OK: DATE(created_at, 'Asia/Tokyo') < '%s'

  • 展開後: ... < '2022-01-01' (正しい日付文字列として認識される)

ループ処理活用のススメ

今回はシャーディングテーブルの作成を例に挙げましたが、このループ処理のテクニックは「API制限を回避するために1日ずつ処理する」「リソース枯渇を避けるために重たいクエリを分割実行する」といったシーンでも非常に有効です。

手作業による「温かみのある運用」から卒業し、スマートで快適なデータ基盤ライフを送りましょう!

25日間の感謝を込めて

これにて Enigmo Advent Calendar 2025 は全25記事のバトンが繋がり、無事完走となります!

今年は様々な職域のメンバーが、それぞれの視点から技術や知見を共有してくれました。これらの記事が、皆様の日々の業務や課題解決のヒントとなれば望外の喜びです。

来たる2026年も、エニグモBUYMAをはじめとするサービスを通じて新しい価値を創造してまいります。どうぞよろしくお願いいたします。


株式会社エニグモ すべての求人一覧 hrmos.co

Ruby on Rails アプリのパフォーマンス最適化10選

こんにちは!Webアプリケーションエンジニアのレミーです!

この記事はEnigmo Advent Calendar 2025の24日目の記事です。

Ruby on Rails アプリが遅いと感じるのは、ほぼ次の3の原因になります。

  1. DBクエリが多すぎる(特に N+1、COUNT/EXISTS の使い分けミス、インデックス不足)
  2. 不要なデータを読み込みすぎる(テーブル全て/重いカラム全て取得、あるいは全部を RAM に書き込む)
  3. ビューのレンダリング/コールバックが働きすぎる(partial の多用、重いフォーマット処理、不要なコールバック/バリデーションの実行)

この記事では、効果が見えやすいものに絞って、自分が特によく使う最適化10個をまとめます。

1. includes で N+1 クエリを防ぐ

問題: posts の一覧を取得して、view 側で post.user.namepost.comments.size のように関連を参照すると、20件なら20回(あるいはそれ以上)追加クエリが飛ぶ可能性があります。

解決: includes で関連を事前ロードします。

改善前: N+1 が発生

@posts = Post.order(created_at: :desc).limit(20)

@posts.each do |post|
  post.user.name # 毎回 SELECT users... WHERE id = ? が走る可能性
end

改善後: includes を使用

@posts = Post.includes(:user).order(created_at: :desc).limit(20)

Railsposts に紐づく users を1回のクエリでまとめてロードし、ループ内での追加クエリを防ぎます。

一覧をレンダリングして、ループ内で association を参照する(post.commentspost.userorder.items など)場合ではよく使われます。

重要ポイント: includes には 3 パターンがあり、Rails が状況に応じて選びます。

  • preload: 常に 2 クエリ(postsとusers)
  • eager_load: 常に LEFT OUTER JOIN(大きい 1 クエリ)
  • includes: Rails が自動判断(preload になる場合も join になる場合もある)

2. 必要なカラムだけ取る: select / pluck

問題: User.allUser.where(...).to_a全カラムを引いてきます。bio (text)settings (jsonb)avatar_data のような重いカラムも含まれがちです。実際には idname だけで十分なケースも多いはずです。

解決:

ActiveRecord オブジェクトは欲しい(でも最小限にしたい)

select を使います。

users = User.where(active: true).select(:id, :name)
users.first.name # OK

値の配列だけで十分(高速 + allocations 少なめ)

pluck を使います。

ids   = User.where(active: true).pluck(:id)
pairs = User.where(active: true).pluck(:id, :name) # [[1, "A"], [2, "B"]]

DB処理時間の短縮、返ってくるデータ量の削減、Ruby 側の allocations 削減。

dropdown/select box で idname だけが必要な時とか、バックグラウンドジョブで処理対象 id だけが必要な時などが使われます。

3. 存在するかどうかの確認なら exists? を使う

問題: relation に対して any? / present? で存在チェックをすると、不要にレコードを読み込んだり、最適でないクエリになったりすることがあります。

解決: exists? は EXISTS を使うため、目的に対して効率的になりやすいです。

改善前: 不要なロードが起こり得る

User.where(email: email).any?

改善後: EXISTS を使う

User.exists?(email: email)

メール重複チェック、ユーザーが注文を持っているか、対象レコードが既にあるか、などの場合に使われます。

4. count / size / length を正しく使い分ける

メソッド DB クエリは走る? どんなクエリ レコードをロードする? 使いどころ
count あり(常に) SELECT COUNT(*) なし DB から正確な件数が必要なとき
length 未ロードなら走る SELECT * あり(全件ロード) すでに records がロード済みだと確実できる時だけ
size 状況による COUNT(*) または なし 自動 ActiveRecord / association では基本これが安全

association がロード済みか不明なときは、次のように size が安全です。

comments_count = post.comments.size

view で association の件数を表示するなら、まずは size(または counter cache)を優先。

5. よく絞り込み/ソートするカラムに Index を貼る

問題: WHERE user_id = ... などがインデックスがないと、DB がテーブル全体をスキャンして重くなりがちです。

解決: WHERE / JOIN / ORDER BY によく出てくるカラムに index を追加します。

例:

add_index :orders, :user_id
add_index :users, :email, unique: true
add_index :orders, [:user_id, :created_at]

インデックス選びの目安:

  • WHERE / JOIN によく出るカラム: index を追加
  • ORDER BY と filter がセットでよく出る:複合インデックス(例 [:user_id, :created_at])を追加
  • email/username のようなユニーク値: unique: true

確認方法: ログで遅いクエリを見つける、DB で EXPLAIN を実行して index が使われているか確認。

注意: index は読み込みを速くしますが、書き込みは少し遅くなる傾向があります。

6. 大量データは batch で処理する: find_each / in_batches

問題: User.where(...).each は全件を RAM に書き込む可能性があります。件数が多い(数万〜数百万)と、メモリが不足になって、worker/job が落ちる原因になります。

解決: find_eachバッチ処理します。

find_each は 主キーによるページングで、メモリには 1 バッチ分だけ保持します。

User.where(active: true).find_each(batch_size: 1000) do |user|
  # user を1件ずつ処理
end

バッチ単位で処理したい(特に一括更新)なら in_batches が便利です。

User.where(active: true).in_batches(of: 1000) do |relation|
  relation.update_all(flag: true)
end

rake タスク、データの移行作業、数万件以上のレコードを扱うジョブなどに使われます。

7. コールバックが不要なら bulk update/delete: update_all / delete_all

問題: 1万件を each { update } すると、1万回のクエリに加えて validations/callbacks が走ります。場合によってはメール送信なども巻き込まれて重くなります。

解決: 1クエリでまとめて処理します。

# 一括更新
User.where(id: ids).update_all(active: false)

# 一括削除
Log.where("created_at < ?", 30.days.ago).delete_all

重要: update_all / delete_all は バリデーションとコールバックを完全にスキップします。

フラグを一括変更、単純なデータ修正、ログの削除などに使われます。

8. association の件数表示には counter cache を使う

問題: 一覧で「コメント数」を表示するために post.comments.count を多用すると重くなります。includes(:comments) にしても comments が多いとそれ自体が重くなることがあります。

解決: comments_count のようなカラムに件数を保持します(counter cache)。

# posts に comments_count を追加
add_column :posts, :comments_count, :integer, default: 0, null: false

# counter cache を有効化
class Comment < ApplicationRecord
  belongs_to :post, counter_cache: true
end

以降は post.comments_count を使えます。

これは、一覧ページや管理画面など「件数表示」があちこちに出てくる画面で特に効きます。

注意: 読み込みは非常に速くなりますが、コメント作成/削除時に post 側のカラム更新が 1 回増えます。

9. 高コストな処理は Rails.cache.fetch でキャッシュする

問題: 重いクエリや計算(トップの記事、統計、設定値など)を毎リクエスト再計算してしまう。

解決: TTLと分かりやすい key を持ったキャッシュを使います。

top_posts = Rails.cache.fetch(["top_posts", Date.current], expires_in: 10.minutes) do
  Post.published.order(score: :desc).limit(20).pluck(:id, :title)
end

キー設計は ["feature_name", version, params...] の配列にすると、管理しやすいです。expires_in も付けて意図せず永続化する事故を避けましょう。

10. view をキャッシュする(fragment / collection caching)

問題: DB はそこまで遅くないのに、partial が多い、フォーマット処理が重いなどで view のレンダリングが遅くなる。

解決1: record 単位の fragment cache

<% @posts.each do |post| %>
  <% cache(post) do %>
    <%= render "posts/post", post: post %>
  <% end %>
<% end %>

Railsはレコードのcache key(バージョン付き)を使うので、post が更新されるとキーも変わり、自然に無効化されます。

解決2: collection caching(短くて速い)

<%= render partial: "posts/post", collection: @posts, cached: true %>

レンダリング時間とCPU使用量が大きく減ります。


Rails が遅い原因は、framework そのものというより、余計なことをしてしまっているコードにあることがほとんどです。まずは上の基本最適化から入れるだけで、複雑なキャッシュ設計やサーバー増強をしなくても、速くなるケースが珍しくありません。

明日の記事の担当はエンジニアの嘉松さんです。お楽しみに。

Rails + SQL Server環境でハマったBooleanの罠

こんにちは、WEBエンジニアのChoi(チェ)です。 BUYMAの購入者向け機能を開発するチームで、主にSEO改善の業務を担当しています。

この記事はEnigmo Advent Calendar 2025の23日目の記事です。

Railsを使用する際は一般的にMySQLPostgreSQLが使われますが、BUYMAでは用途に応じてSQL Serverも使用しています。

最初は「どのSQLも大差ないだろう」と思っていましたが、運用を開始するとRails + SQL Server特有のトラブルに遭遇しました。

今回はその中でも、

エラーは一切出ないのに、結果だけが返ってこない

という、かなり気づきにくかったケースをご紹介します。


boolean処理をめぐる誤解

ある APIで、次のようにリクエストパラメータを条件に使っていました。

User.where(active: params[:active])

エラーは発生せず、一見すると問題なさそうに見えました。

しかし実際には、エラーは発生しないものの、条件に一致するデータがまったく返ってこないという現象が起きていました。

SQLログを確認すると、発行されていたのは次のようなSQLです。

WHERE active = 'true'

この時点ではまだ、

「文字列になっているのが問題なんだ」

という程度の認識でした。

しかし「文字列になっていたら、trueに暗黙的に変換されるのではないのか?」という疑問も浮かびました。

RubySQLの違い

Rubyでは、次のようなコードが成立します。

if 'false'
  # 実行される
end

Rubyの条件分岐では、falsenil以外はすべてtruthyとして扱われるため、'false'という文字列も「真」として評価されます。

しかしこれは Rubyレベルでの話です。

ActiveRecordが生成するSQLでは、値は型変換されることなく、そのままバインドされます。

テーブル定義を見て、ようやく原因に気づく

改めてテーブル定義を確認してみると、activeカラムはbooleanではありませんでした。

  • カラム型:CHAR(1)
  • 想定値:'1'(有効) / '0'(無効)

つまりこのコードは、

HTTP パラメータとして受け取った 文字列をそのままSQLの条件に渡していた

という状態だったのです。

SQL Server側では、'true'booleanとして解釈されません。

あくまで 文字列同士の比較として評価されます。

その結果、

  • エラーは出ない

  • 条件にも一致しない

  • 常に0件が返る

という、分かりづらい不具合になっていました。

MySQLPostgreSQLであれば、どうなっていたか

ここで気になったのが、 「もしMySQLPostgreSQLだったら、同じ問題は起きていたのか?」 という点でした。

PostgreSQLの場合

PostgreSQLには明確なboolean型があります。

WHERE active = 'true'

のような条件でも、'true'booleantrueとして解釈します。

そのため、今回のケースでは 意図した通りにデータが返ってきていた可能性が高いです。

結果として、問題に気づかないまま運用が続いていたかもしれません。

MySQLの場合

MySQLでは、booleanは実体としてはTINYINT(1)です。

'true''false'といった文字列は、暗黙的に数値へ変換され、結果が返ることもあります。

ただしこの挙動は、明確な仕様というより暗黙の型変換に依存したものです。

なぜ SQL Server環境で表面化されたのか

この問題自体は、SQL Server固有の文法エラーではありません。

しかし、SQL Serverを採用しているサービスでは

  • レガシーなテーブルでは、有効/無効フラグをCHAR型で管理しているケースが今も存在する

という背景から、Rails + SQL Serverの組み合わせで特に踏みやすい落とし穴だと感じました。

この経験から学んだこと

このトラブルをきっかけに、次の点を強く意識するようになりました。

  • DBのカラム型は「現在のRails の常識」と一致するとは限らない
  • パラメータをそのまま条件に渡さず、ドメイン上の値('1' / '0' など)に変換してから使う
  • 結果が返らない場合は、生成されたSQLを必ず確認する

Rails側で正しく書けていても、DB側の前提が異なるだけで、意図しない挙動にハマることがあると学びました。


明日の記事の担当はWebエンジニアのレミーさんです。お楽しみに。

Rails 8のSolid Queue:Sidekiqに代わる新しい非同期処理システム

こんにちは!Webアプリケーションエンジニアのレミーです!

この記事はEnigmo Advent Calendar 2025の21日目の記事です。

Rails 8がリリースされてから、バックグラウンドジョブシステムである Solid Queue に興味を持ち、調べてみました。

バックグラウンドジョブは、Ruby on Railsアプリケーションに重要な部分です。メール送信、画像処理、データ同期、キャッシュ更新、CSVファイルのエクスポートなど、これらはすべてアプリケーションの高速化とスムーズな動作を維持するために非同期で実行すべきタスクです。

長年、Railsのバックグラウンドジョブにおいて「Sidekiq + Redis」はほぼ基準とされてきました。しかし、Rails 8からは、Railsは公式にSolid Queueを導入しました。これはRedisを必要とせず、補助的なサーバーも不要な、ネイティブなキューシステムです。

この記事では、Solid Queueとは何か、その仕組み、どうしてRails 8以上のプロジェクトでSolid Queueを使用すべきかについて解説します。また、Sidekiqとの比較も行います。

Solid Queueとは?

Solid Queueは、データベースをジョブキューとして使用するバックグラウンドジョブシステムであり、Rails Solid Suite(Solid Cache, Solid Queue, Solid Cableを含む)の一部として開発されました。

Redisを使用するSidekiqとは異なり、Solid Queueはジョブをデータベースのテーブルに保存し、ワーカープロセスがそのジョブを読み取って実行します。

つまり:

  • Redisが不要
  • Sidekiqのインストールが不要
  • 補助サーバーのコストがかからない
  • ActiveJobと深く統合されている
  • インストールが非常に簡単

これは、Railsをシンプルにするために生まれました。特にスタートアップ、小規模〜中規模のプロジェクト、またはコストを抑える必要がある環境に最適です。

仕組みとデータベース構造

Solid Queueは単一のシンプルなテーブルだけではなく、ジョブのライフサイクルを管理し、安全性とパフォーマンスを確保するために複数のテーブルを使用します。

重要なテーブルは以下の通りです:

  • solid_queue_jobs: ジョブのメタデータ(クラス名、引数、キュー名、優先度、遅延ジョブの場合はscheduled_at、ジョブIDなど)を保存します。
  • solid_queue_ready_executions: 「実行準備完了」となったジョブを含みます。つまり、エンキューされたジョブで、ワーカーが拾える状態のものです。
  • solid_queue_scheduled_executions: スケジュールされたジョブを含みます。まだ実行タイミングには達していません。
  • solid_queue_claimed_executions: ワーカーが実行のために確保)したジョブ情報を保存し、複数のワーカーが同じジョブを実行しないためです。
  • solid_queue_blocked_executions: ブロックされており、すぐに実行できないジョブを含みます。
  • solid_queue_failed_executions: 実行後にエラーになったジョブを保存し、監視やデバッグに役立ちます。

このように明確に複数のテーブルに設計されているため、Solid Queueは役割を明確に分離でき、ロジックがクリアになり、管理しやすくなります。

Solid Queueにおけるジョブのライフサイクル

Solid Queueの仕組みと、なぜ複数の異なるテーブルが必要なのかを理解するために、ジョブがエンキューされ、ワーカーに拾われ、実行され、削除されるまでの完全なライフサイクルを説明します。

1. ジョブが呼び出される時(エンキュー)

MyJob.perform_later(args) を呼び出すと、Solid Queueはデータベースに対して2つの書き込み操作を行います:

  • solid_queue_jobs テーブルへの書き込み:ジョブのメタデータ("queue_name", "class_name", "arguments", "priority", "active_job_id", "scheduled_at", "finished_at", "concurrency_key" など)を保存します。
  • すぐに実行するジョブの場合:solid_queue_ready_executions にデータを追加します。このテーブルには、ワーカーが処理可能な準備完了ジョブが含まれます。

2. ワーカーが実行するジョブを探す(ポーリング)

ワーカーは solid_queue_ready_executions テーブルを継続的に「ポーリング」して、新しいジョブを取得します。ワーカーは以下の2つの作業を行います:

  1. 確保: ワーカーが solid_queue_ready_executions からジョブを選択すると、solid_queue_claimed_executions テーブルにレコードを書き込みます。このレコードにより、2つのワーカーが同じジョブを実行することができません。
  2. 実行: クレームした後、ワーカーはジョブクラスの perform メソッドを呼び出して実行します。

3. ジョブ完了時、レコードの削除

ジョブが正常に実行されると、ワーカーは関連するすべてのテーブル(solid_queue_jobs, solid_queue_ready_executions, solid_queue_claimed_executions)からジョブを削除します。

ジョブのライフサイクルの簡単なまとめ

段階 関連テーブル 目的
ジョブのエンキュー solid_queue_jobs ジョブのメタデータを保存
ジョブ準備完了 solid_queue_ready_executions ワーカーが拾える状態
ワーカーによる確保 solid_queue_claimed_executions 1つのジョブを1つのワーカーが実行することを保証
実行 なし ワーカーが perform関数を呼び出す
完了 複数のテーブルから削除 レコードのクリーンアップ

安全性、ジョブの「失う」を防ぐ仕組み

重要な要件の一つは、エンキューされたジョブが少なくとも1回は実行され、失われないことです。Solid Queueは、ワーカーのクラッシュ、強制終了、プロセスの不具合などのケースを以下の形式で処理します:

  • 各ワーカーは起動時に solid_queue_processes にレコードを作成し、定期的に last_heartbeat_at を更新します。
  • ワーカーがジョブをクレームする際、solid_queue_claimed_executions にプロセスIDと共にレコードを書き込みます。
  • デフォルトはスーパーバイザープロセスがバックグラウンドで実行され、processes テーブルをチェックします。許容時間を超えて heartbeatがないプロセス(例:5分以上)が見つかった場合、それを「失敗したワーカー」と見なします。
  • スーパーバイザーはそのプロセスを削除し、そのワーカーが保持していたジョブを ready キューに再エンキューして、他のワーカーが拾えるようにします。

これにより、ワーカーがクラッシュしてもジョブは失われず、データの整合性が保証されます。

Solid Queue と Sidekiq の比較

Solid QueueとSidekiqはどちらもRailsで人気のある非同期処理のシステムですが、以下の表で違いを明確にします。

基準 Solid Queue (Rails 8) Sidekiq
ストレージバックエンド データベース (PostgreSQL / MySQL / SQLite) Redis (インメモリ、非常に高速)
Railsとの統合 ネイティブ、Rails 8からの公式組み込み コアじゃない、gem経由で使用
パフォーマンス 小〜中規模のワークロードに良好 非常に高い、大規模ワークロードに最適
遅延 DB使用のため比較的高い 低い (Redis インメモリ)
インストール 簡単、補助サービス不要 複雑、RedisとSidekiqの設定が必要
運用コスト ほぼゼロ (既存DBを使用) Redisのコストがかかる (特に本番環境)
信頼性 高い (SQLトランザクション + ジョブクレーム) 非常に高いがRedisに依存
リトライのロジック あり、DBに保存 あり、強力かつ柔軟
ダッシュボード 強力なUIはまだない Web UIが充実、リアルタイム監視が可能

いつ Solid Queue を選ぶべきか?

シンプル、軽量、ネイティブ、コスト節約を望むならSolid Queueを選びましょう。

いつ Sidekiq を選ぶべきか?

高速、強力、大規模システムに適したものを望むならSidekiqを選びましょう。

結論

Solid Queueは、インフラを簡素化し、Rails 8の大きな進歩を示しています。バックグラウンドジョブをコアフレームワークに直接統合することで、中小規模のプロジェクトはRedisやSidekiqに依存する必要がなくなり、安定性、信頼性の高いジョブ処理能力を確保しながら、運用コストを大幅に削減できます。

明日の記事の担当はエンジニアの宮川さんです。お楽しみに。