Upgrade to Pro — share decks privately, control downloads, hide ads and more …

そのpreloadは必要?見過ごされたpreloadが技術的負債として爆発した日

Avatar for mugi mugi
September 27, 2025

 そのpreloadは必要?見過ごされたpreloadが技術的負債として爆発した日

Kaigi on Rails 2025

Avatar for mugi

mugi

September 27, 2025
Tweet

Other Decks in Programming

Transcript

  1. 自己紹介 1 麦倉 柊太(Shuta Mugikura) / mugi ⚫ X: @mugi_1359

    ⚫ GitHub: @mugitti9 ⚫ Kaigi on Rails オーガナイザー ⚫ 株式会社ギフティ
  2. preloadのメモリコスト 11 Article ID: 1 Article ID: 2 Article ID:

    3 SELECT * FROM comments WHERE article_id IN (1, 2, 3) Article.pluck(:id) SELECT * FROM likes WHERE comment_id IN (1, 2, 3, ...)
  3. preloadのメモリコスト 12 Article ID: 1 Comment ID: 1 Comment ID:

    2 Comment ID: 3 Article ID: 2 Comment ID: 4 Comment ID: 5 Comment ID: 6 Article ID: 3 Comment ID: 7 Comment ID: 8 Comment ID: 9 Like ID: 1 Like ID: 2 Like ID: 3 Like ID: 4 Like ID: 5 Like ID: 6 Like ID: 7 Like ID: 8 Like ID: 9 Like ID: 10 Like ID: 11 Like ID: 12 Like ID: 13 Like ID: 14 Like ID: 15 Like ID: 16 Like ID: 17 Like ID: 18
  4. preloadのメモリコスト 13 Article ID: 1 Article ID: 2 Article ID:

    10 ・ ・ ・ Comment ID: 1 Comment ID: 2 Comment ID: 3 Comment ID: 100 ・ ・ ・ Like ID: 1 Like ID: 2 Like ID: 3 Like ID: 100 ・ ・ ・
  5. preloadのメモリコスト 14 Article ID: 1 Article ID: 2 Article ID:

    10 ・ ・ ・ Comment ID: 1 Comment ID: 2 Comment ID: 3 Comment ID: 100 ・ ・ ・ Like ID: 1 Like ID: 2 Like ID: 3 Like ID: 100 ・ ・ ・ 約100MB
  6. preloadのメモリコスト 15 Article ID: 1 Article ID: 2 Article ID:

    10 ・ ・ ・ Comment ID: 1 Comment ID: 2 Comment ID: 3 Comment ID: 100 ・ ・ ・ Like ID: 1 Like ID: 2 Like ID: 3 Like ID: 100 ・ ・ ・ もしこれが 使われないpreloadだったら?
  7. 障害時に何が起きていたか 17 children.sizeをするためpreload Parent parent.children_countを持つ 設計の方針変更 (例: counter_cacheの導入) parent =

    Parent.preload(:children).first parent.children.each { p it.do_some } scopeの追加 (例: activeのscopeの絞り込みを追加) parent = Parent.preload(:children).first parent.children.active.each { p it. do_some } Parent Children
  8. 障害時に何が起きていたか 20 content_tag_groups.preload( content_tag: { contents: { content_publish_permission: { content_registrations:

    :available_content_selections } } } ) content_tag_groups.preload(:content_tag) 約 400 MB ↓ 80%削減
  9. まとめ 35 ⚫ 些細な負債の積み重ねが大きな障害へとつながる ⚫ 不要なpreloadという些細な問題から、プロダクトの成長によって、その 負債が蓄積し、全社的な障害へとつながった ⚫ Railsにおいても銀の弾丸は存在しない ⚫

    常にトレードオフが存在し、これを入れたら全てが解決するというような 手法は存在しない ⚫ 例えばpreloadの場合は、N+1を防げる一方で、不要なものを放置すると 多大なメモリ利用等につながる