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

대규모 트래픽을 처리하는 프론트 개발자의 전략

대규모 트래픽을 처리하는 프론트 개발자의 전략

2025년 7월 26일 Google IO Extended 인천 행사에서 발표한 자료입니다.

Next.js 와 Supabase 를 이용해 사이드 프로젝트로 티켓팅 사이트 티켓타코를 만들었습니다.
티켓팅 사이트에서 기술적으로 중요한 것은 오픈했을 때 순간 트래픽을 대응하는 것입니다.
한달 50달러 비용으로 큰 인프라 없이 1000명의 동시 접속자를 대응할 수 있었던 여러 전략들을 소개합니다.

Avatar for Seungmin 마량

Seungmin 마량

July 26, 2025
Tweet

More Decks by Seungmin 마량

Other Decks in Programming

Transcript

  1. Google I/O Extended 25 (അ) ীয೐ۨ޷ই ەझ ೐ۿ౟ ౵౟੢ (੹)

    ߛ௼࢟۞٘ ೐ۿ౟ ݒפ੷ (੹) ܻݯߡ উ٘۽੉٘ ѐߊ੗ ੉थ޹
  2. Google I/O Extended 25 ౭௄౴ ೒ۖಬ੉ ӝࣿ੸ਵ۽ Ҋ۰೧ঠ ೡ Ѫ

    ࣻ۝ ୊ܻ য়ߡࠗఊ ߑ૑ ੿೤ࢿ ࠁ੢ (੉ࢶઝ)
  3. Google I/O Extended 25 ౭௄౴ ೒ۖಬ੉ ӝࣿ੸ਵ۽ Ҋ۰೧ঠ ೡ Ѫ

    ࣽр ౟ې೗ ۽Ӓੋ/ഥਗоੑ ੉߮౟/઱ޙ ઑഥ ࣻ۝ ୊ܻ য়ߡࠗఊ ߑ૑ ੿೤ࢿ ࠁ੢ (੉ࢶઝ)
  4. Google I/O Extended 25 ౭௄౴ ೒ۖಬ੉ ӝࣿ੸ਵ۽ Ҋ۰೧ঠ ೡ Ѫ

    ࣽр ౟ې೗ ۽Ӓੋ/ഥਗоੑ ੉߮౟/઱ޙ ઑഥ ࣻ۝ ୊ܻ য়ߡࠗఊ ߑ૑ ੿೤ࢿ ࠁ੢ (੉ࢶઝ)
  5. Google I/O Extended 25 DB, Function, S3, Auth, Scheduler Analytics,

    Crashlytics, Hosting, Deploy, DynamicLink, Experiment, etc…
  6. Google I/O Extended 25 💦 DB, Function, S3, Auth, Scheduler

    Analytics, Crashlytics, Hosting, Deploy, DynamicLink, Experiment, etc… 😫
  7. Google I/O Extended 25 நद੄ ੄޷ ઺р ੷੢ࣗܳ فযࢲ ࠳ۄ਋੷

    நद ࢲߡ நद ࢲߡ, DBী ب׳ೞח ਃ୒ ࣻܳ ઴੉੗
  8. Google I/O Extended 25 ࠳ۄ਋੷ நद ೠݺ੄ ࢎਊ੗о ೠߣ੄ ࣁ࣌ীࢲ

    நद ࢎਊ ࠳ۄ਋੷ చਸ Սݶ நद ؘ੉ఠо ࢎۄ૓׮ Session Storage, Memory ࠳ۄ਋੷ܳ ઺р ੷੢ࣗ۽ ഝਊ
  9. Google I/O Extended 25 ࠳ۄ਋੷ நद நद ؘ੉ఠ ߈ജ நदо

    ੓ਸ ٸ ࠳ۄ਋੷ ௿ۄ੉঱౟ ࢲߡ ਃ୒ ࣻ ੺ড!
  10. ࠳ۄ਋੷ நद ࢎਊೞӝ const { data, isLoading, error, refetch }

    = useQuery({ queryKey: ["dashboard", eventId, user?.id], queryFn: () => EventService.fetchDashboard(eventId), }); const useUserStore = () => { return useContext(UserStoreContext); }; API ਽׹ நय ௿ۄ੉঱౟ ஹನք౟ ؘ੉ఠ ҕਬ React Query Context
  11. Google I/O Extended 25 ઺р ࢲߡܳ ੷੢ࣗ۽ ഝਊ ࠳ۄ਋੷ܳ ԉ׮

    ெب நद ؘ੉ఠо թই੓׮ ৈ۞ݺ੄ ࢎਊ੗о ৈ۞ߣ੄ ࣁ࣌ীࢲ நद ࢎਊ ࢲߡ੄ ഋకח ׮নೞ׮ ࢲߡ நद (CDN, Redis, Spring ١)
  12. Google I/O Extended 25 நद ؘ੉ఠ ߈ജ நदо ੓ਸ ٸ

    நद ੷੢ࣗ ௿ۄ੉঱౟ ࢲߡ ਃ୒ ࣻ ݆੉ ੺ড! ࢲߡ நद ௿ۄ੉঱౟ ௿ۄ੉঱౟ …
  13. Next.js۽ ࢲߡ நद const res = await fetch(`/events/${id}`, { next:

    { revalidate: EnvUtil.isDev ? 0 : 300 }, }); 1.fetchܳ ॵ׮ 2.next { revalidate } ২࣌ਸ ળ׮ 3.Server Componentীࢲ ഐ୹ೠ׮ 5࠙ நद
  14. Google I/O Extended 25 Cache Control۽ ࢲߡ நद API ਽׹

    ೻؊ী Cache Control ୶о Cache-Control: max-age=<seconds>
  15. Google I/O Extended 25 Cache Control য۰਑ ഐ୹ࠗ ࢲߡ நदܳ

    ೞҊ रয நद ੿଼ Ѿ੿ Context ܻ࠙ (Cache-Control) நदܳ ੷੢ೞח Ҕҗ ੿଼ਸ Ѿ੿ೞח Ҕ੉ ׮ܰ׮ ௏٘ ൒ܴ੉ ૒ҙ੸੉૑ ঋ׮
  16. Google I/O Extended 25 Cache Control য۰਑ நदܳ ੷੢ೞח Ҕҗ

    ੿଼ਸ Ѿ੿ೞח Ҕ੉ ׮ܰ׮ ഐ୹ࠗ ࢲߡ நदܳ ೞҊ रয நद ੿଼ Ѿ੿ Context ܻ࠙ (Cache-Control) ഐ୹ࠗী ٮۄ ੷੢ ߑߨ੉ ׮ܰ׮
  17. Google I/O Extended 25 ࠳ۄ਋੷ Next.js Vercel, CF Spring ੷੢

    ഋక ޖद CDN ޖद ࠳ۄ਋੷ ۽ஸ நद ഐ୹ ਤ஖ (response ߉ח Ҕ)
  18. Google I/O Extended 25 ࠳ۄ਋੷ Next.js Vercel, CF Spring ੷੢

    ഋక ޖद CDN ޖद ࠳ۄ਋੷ ۽ஸ நद ੿੸ ౵ੌ(html, css, js, ੉޷૑ ١) நद ഐ୹ ਤ஖ (response ߉ח Ҕ) ࠳ۄ਋੷ -> Vercel -> Origin ীࢲ Cache-Control ߈ജ
  19. Google I/O Extended 25 Vercelਸ ࢎਊೠ׮ݶ ੗ز ࠳ۄ਋੷ Next.js Vercel,

    CF Spring ੷੢ ഋక ޖद CDN ޖद ࠳ۄ਋੷ ۽ஸ நद ഐ୹ ਤ஖ (response ߉ח Ҕ) ੿੸ ౵ੌ(html, css, js, ੉޷૑ ١) நद ࠳ۄ਋੷ -> Vercel -> Origin ীࢲ Cache-Control ߈ജ
  20. Google I/O Extended 25 ࠳ۄ਋੷ীࢲח React Query, Context ࢲߡীࢲח next

    revalidate Vercelਸ ా೧ CDN Cache Control API ױਤ۽ நय நदо ೙ਃೠ API৬ ೙ਃೞ૑ ঋח APIܳ ܻ࠙
  21. Google I/O Extended 25 ੉߮౟ ಕ੉૑ীࢲ ೙ਃೠ ੿ࠁ ഐ୹ࣻܳ ઴੉ӝ

    ਤ೧ ೞա੄ API۽ ҳࢿೞҊ நय ੉߮౟ ղਊ ౭௄ ࣻ۝
  22. Google I/O Extended 25 ഐ୹ࣻܳ ઴੉ӝ ਤ೧ ೞա੄ API۽ ҳࢿೞҊ

    நय ੉߮౟ ಕ੉૑ীࢲ ೙ਃೠ ੿ࠁ ੉߮౟ ղਊ ౭௄ ࣻ۝ पदр ࣻ۝੉ ઺ਃೠ ౭௄ ੿ࠁ ߡӒ
  23. Google I/O Extended 25 staticೠ ੉߮౟ ղਊ API पदр ౭௄

    ࣻ۝ API ؘ੉ఠ ࢿѺী ٮۄ API ࢸ҅ நद ࢎਊ நद ޷ࢎਊ ࢲߡ ೐ۿ౟
  24. Google I/O Extended 25 staticೠ ੉߮౟ ղਊ API पदр ౭௄

    ࣻ۝ API ؘ੉ఠ ࢿѺী ٮۄ API ࢸ҅ நद ࢎਊ நद ޷ࢎਊ ࢲߡ ೐ۿ౟
  25. Google I/O Extended 25 Origin நय (Origin) நद ੷੢ࣗ ௿ۄ੉঱౟

    ࢲߡ ਽׹ ؘ੉ఠ ੷੢ ੷੢ࣗী ؘ੉ఠо হਵݶ Origin(ࢲߡ)ী ਃ୒ೞח ߑध
  26. Google I/O Extended 25 Origin நय੄ ೠ҅ ੜޅػ ؘ੉ఠ ߈ജ!

    5ѐ թ਺ 0ѐ թ਺ पदр ੿ࠁܳ நयೞ૑ ޅೠ׮ (Origin) நद ੷੢ࣗ ௿ۄ੉঱౟ ࢲߡ
  27. Google I/O Extended 25 पदр ؘ੉ఠ நयೞӝ நद ੍ӝ৬ ॳӝܳ

    ܻ࠙ೠ׮ நद ੷੢ࣗ ౭௄ ઑഥ ࢲߡ ౭௄ ҳݒ/ஂࣗ ؘ੉ఠ ߈৔ ؘ੉ఠ ߸҃ पदр ؘ੉ఠ ઑഥ
  28. Google I/O Extended 25 पदр ؘ੉ఠ நयೞӝ நद ੍ӝ৬ ॳӝܳ

    ܻ࠙ೠ׮ நद ੷੢ࣗ ౭௄ ઑഥ ࢲߡ ౭௄ ҳݒ/ஂࣗ ؘ੉ఠ ߈৔ ؘ੉ఠ ߸҃ ࢲߡ ਃ୒ ࣻ ੺ড! पदр ؘ੉ఠ ઑഥ
  29. Google I/O Extended 25 APIח ӝࠄ੸ਵ۽ Client Componentীࢲ ഐ୹ ֎౟ਕ௼

    ࠗ׸ਸ ਃӘ হח ࢎਊ੗ ӝӝী ਤ੐ API ഐ୹ ਤ஖ Next.js੄ SSR, API Route Next.js ࢲߡ (Vercel) ࠗ׸!
  30. Google I/O Extended 25 ঱ઁ Server Componentܳ ࢎਊೡө? SEO ઺ਃ

    Next Cache ࢎਊ ۪؊݂ द੼ী ؘ੉ఠ ࠁ੢ (ࢎਊ੗ ੿ࠁ) (੉߮౟, ઱ޙ) API ഐ୹ ਤ஖
  31. SDK const { data, error } = await this.supabase .from("event_tickets")

    .select("*") .eq("event_id", eventId) .eq("status", EventTicketStatus.PUBLIC); ௿ۄ੉঱౟ীࢲ Supabase DB API ૒੽ ഐ୹ ࢲߡܳ Ѣ஖૑ ঋই ֎౟ਕ௼ ࠺ਊ ੉ٙ
  32. Google I/O Extended 25 Edge Function AWS੄ Lambda Firebase੄ Cloud

    Function ࢲߡܻझ API ௿ۄ੉঱౟ীࢲ APIਸ Ѣ୛ Supabase DB APIܳ ഐ୹ API Ѣ஖ח ֎౟ਕ௼ ࠺ਊ ೙ਃ
  33. Google I/O Extended 25 ۽૒ ܻ࠙ ઁಿ ਬোࢿҗ ߔূ٘ ౱

    ࢤ࢑ࢿਸ ਤ೧ ৉ೡ ҳ࠙ Edge Function ੢੼ Admin ӂೠ
  34. Edge Function ࢎਊೞӝ const { error: organizerError, count: organizerCount }

    = await supabaseAdmin .from("organizers") .select("*", { count: "exact", head: true }) .eq("organization_id", organization_id) .eq("user_id", userData.user.id); if (!organizerCount) throw new Error("ӝҙ੄ ӂೠ੉ হणפ׮."); const { data: tickets, error: ticketsError } = await supabaseAdmin .from("order_tickets") .select("*") .eq("order_ticket_number", orderTicketNumber) .in("status", [OrderTicketStatus.PAID, OrderTicketStatus.CANCELED]); ӂೠ Ѩࢎ റ ઑഥ Edge Functionীࢲ Supabase DB API ഐ୹
  35. Google I/O Extended 25 Database Function SDK, Edge Functionب DB

    API ౵ۄ޷ఠ۽ SQL ࢎਊ ৵ ೙ਃೡө? SQLਸ ૒੽ ࢎਊೞח Function
  36. Google I/O Extended 25 Database Function Transaction ࠁ੢ Database 1ഥ

    োѾ۽ ׮઺ ௪ܻ ࣻ೯ (Spring੄ Transactional য֢ప੉࣌җ э਷ ৉ೡ) SQLਸ ૒੽ ࢎਊೞח Function
  37. Database Function ࢎਊೞӝ create function tickets_cancel(p_ticket_id bigint, p_refund_amount numeric) begin

    -- 1. ஂࣗೡ ౭௄ оઉয়ӝ (with lock) select ot.event_ticket_id, ot.status, ot.order_id from public.order_tickets ot where ot.id = p_ticket_id for update; -- 2. ౭௄ ࢚క ߸҃ update public.order_tickets set status = 'CANCELED', canceled_at = now() where id = p_ticket_id; -- 3. ౭௄ ࣻ۝ ࠂਗ update public.event_tickets set sold_count = sold_count - 1 where id = v_event_ticket_id; -- 4. ജࠛ Әঘ ־੸ update public.orders set refund_amount = refund_amount + p_refund_amount where id = v_order_id; end; $$; 1ߣ੄ DB োѾ۽ 4ѐ੄ ௪ܻ ࣻ೯ Transaction/ਗ੗ࢿ ࠁ੢ (ೞա݅ पಁ೧ب ݽف ܀ߔ) ௿ۄ੉঱౟ - Edge Function - DB Function (࠺ਊ ੉ٙ)
  38. Google I/O Extended 25 ௿ۄ੉঱౟ীࢲ Database Function ഐ୹ೞݶ ୭ࣗ ࠺ਊ?

    Database Function (֎౟ਕ௼ ࠺ਊ ੺ড) (DB োѾ ੺ড)
  39. Google I/O Extended 25 Edge Functionਸ Ѣ஖૑ ঋҊ ഐ୹ೞݶ ࠁউ

    ޙઁ Database Function (ࢎਊ੗ Ѩૐ / DB ૒੽ ࣻ੿ ١) ௿ۄ੉঱౟ীࢲ Database Function ഐ୹ೞݶ ୭ࣗ ࠺ਊ?
  40. Google I/O Extended 25 ࠺ਊ, উ੿ࢿਸ ݽف ੟ח API ഐ୹

    ߑߨ ੿ܻ Ӓ ৻ DB ઑഥ SDK ӂೠ ೙ਃহח DB ઑഥ Edge Function Database Function Edge Function ীࢲ Transaction ೙ਃ / ׮઺ ௪ܻ ࢎਊ
  41. Google I/O Extended 25 ࠺ਊ, উ੿ࢿਸ ݽف ੟ח API ഐ୹

    ߑߨ ੿ܻ Ӓ ৻ DB ઑഥ SDK ӂೠ ೙ਃহח DB ઑഥ Edge Function Database Function Edge Function ীࢲ Transaction ೙ਃ / ׮઺ ௪ܻ ࢎਊ
  42. Google I/O Extended 25 ੿ӏച DB table ࢸ҅ ࠺੿ӏച ઺ࠂ

    ؘ੉ఠ ੷੢ೞ૑ ঋӝ ઺ࠂ ؘ੉ఠ ੷੢
  43. Google I/O Extended 25 ੿ӏച orders.purchaser_id ੉ܴ, ੹ചߣഐ, ੉ݫੌ਷ users

    ప੉࠶ ઑੋਵ۽ ઑഥ э਷ ੿ࠁܳ orders, users ઺ࠂਵ۽ о૑૑ ঋח׮
  44. Google I/O Extended 25 ࠺੿ӏച purchaser_id purchaser_name purchaser_phone ଵо੗ Ѩ࢝

    द order_tickets݅ ઑഥ ઑഥ ࢿמ ೱ࢚ order_tickets
  45. Google I/O Extended 25 ੿ӏച vs ࠺੿ӏച Order OrderTicket purchaser_name

    purchaser_id ҕр vs ࢿמ যڃ Columnਵ۽ ঴݃ա ੗઱ ઑഥೞջী ٮۄ ׮ܰѱ ࢸ҅ purchaser_id purchaser_phone
  46. Google I/O Extended 25 ؘ੉ఠܳ ࡅܰѱ ઑഥೡ ࣻ ੓ب۾ ذח

    ੗ܐҳઑ DB ੋؙझۆ? id name price status 1 Event1 50,000 PAID 2 Event2 30,000 CANCELED orders table orders index id 1 2
  47. Google I/O Extended 25 ੋؙझо হਵݶ ઑഥ द ೦࢚ ಽझப

    ೙ਃহח ؘ੉ఠ ઑഥ ࠺ਊ խ࠺ ੋؙझ ೙ਃࢿ id name price status 1 Event1 50,000 PAID 2 Event2 30,000 CANCELED select * from orders where status=‘PAID’ ੉Ѫ݅ ೙ਃೠؘ ׮ झபೠ׮
  48. Google I/O Extended 25 ੋؙझо ੓ਵݶ ೙ਃೠ Column݅ ઑഥ ੋؙझ

    ೙ਃࢿ id name price status 1 Event1 50,000 PAID 2 Event2 30,000 CANCELED status PAID CANCELED ޷ઑഥ! select * from orders where status=‘PAID’
  49. Google I/O Extended 25 ਬפ௼ Column਷ ੗زਵ۽ ࢤࢿػ׮ ੋؙझ ҕध

    - Unique email text not null unique, constraint unique_organizer unique (org_id, user_id) id bigint generated always as identity primary key,
  50. Google I/O Extended 25 ੋؙझ ҕध - ৻ېః ৻ېః Column਷

    ੋؙझܳ ୶оೞ੗ event_id bigint not null references public.single_events(id), create index idx_orders_event_id on public.orders(event_id);
  51. Google I/O Extended 25 ੋؙझ ҕध - Status Status Column਷

    ੋؙझܳ ୶оೞ੗ status public.order_status not null, create index idx_orders_status on public.orders(status);
  52. Google I/O Extended 25 ੋؙझ ҕध - ৻ېః + Status

    ਬפ௼ೞ૑ ঋ਷ ৻ېః৬ Statusח ࠂ೤ ੋؙझܳ ୶оೞ੗ create index idx_orders_event_id_status on public.orders(event_id, status);
  53. Google I/O Extended 25 NOT ௪ܻ ೖೞӝ ੋؙझܳ ࢎਊೞח ௪ܻ

    ੘ࢿೞӝ ੋؙझܳ উఎ оמࢿ੉ ֫׮ where status != 'PAID';
  54. Google I/O Extended 25 pg_stat_user_indexes ੋؙझ ୭੸ച ੿ࢳ ੋؙझ ࢎਊ

    ా҅ ݆੉ ࢎਊೞ૑ ঋח ੋؙझ ࢏ઁ ੋؙझ৬ ҙ۲ػ ௪ܻ ࠙ࢳ
  55. Google I/O Extended 25 ஹೊఠ ࢎন਷ ࡅܰѱ ߸҃੉ য۵׮ ஹೊఠ

    ѐࣻח ࡅܰѱ ઑ੿੉ оמೞ׮ ࣽр ؀ӏݽ ౟ې೗ਸ х૑೮ਸ ٸ അ੢ ؀਽਷ ઱۽ Scale Out
  56. Google I/O Extended 25 ಣӐ ౟ې೗ী ݏח ੸੺ೠ ࢎন ࢸ੿

    ઺ਃ (Scale Up) ࢿמب উաয়Ҋ ࠺ਊب ؊ ࠺व ࣻ ੓׮ ࢎনਸ ୭੷۽ ೞҊ ѐࣻ۽݅ ؀਽ೞݶ?
  57. Supabase੄ Scale up 1.fetchܳ ॵ׮ 2.next { revalidate } ২࣌ਸ

    ળ׮ 3.Server Componentীࢲ ഐ୹ೠ׮ 5࠙ நद
  58. Vercel੄ Scale Up 1.fetchܳ ॵ׮ 2.next { revalidate } ২࣌ਸ

    ળ׮ 3.Server Componentীࢲ ഐ୹ೠ׮ 5࠙ நद
  59. Vercel੄ Scale Out 1.fetchܳ ॵ׮ 2.next { revalidate } ২࣌ਸ

    ળ׮ 3.Server Componentীࢲ ഐ୹ೠ׮ 5࠙ நद
  60. SSG, ISR export async function generateStaticParams() { const posts =

    await fetch(‘https://.../posts'); return posts.map((post) => ({ slug: post.slug, })); } export const revalidate = 60; ࠽٘ ٸ ޷ܻ ࢤࢿೞח Static Site Generation ࠽٘ ٸ ޷ܻ ࢤࢿೞҊ, ੌ੿ рѺਵ۽ ୭नചೞח Incremental Static Regeneration ੿ࠁо ߄Շ૑ ঋח Static ಕ੉૑ী ਬਊ
  61. Google I/O Extended 25 ab ࠗೞ పझ౟ ೞӝ ab -n

    100 -c 10 http://localhost:3000 siege wrk siege -c 10 -r 10 http://localhost:3000 wrk -t4 -c20 -d10s http://localhost:3000 ݺ۸઴۽ рױೞѱ ࣻ೯
  62. ࠗೞ పझ౟ ೞӝ export const options = { vus: 1000,

    // زद о࢚ ࢎਊ੗ ࣻ duration: "30s", // పझ౟ दр }; export default function () { const url = “https://www.ticketa.co/events/1”; const params = { timeout: "10s", // ਃ୒ ఋ੐ইਓ }; const res = http.get(url, params); check(res, { "status is 200": (r) => r.status === 200, }); } k6 झ௼݀౟۽ ࣻ೯ k6 run k6.js
  63. Google I/O Extended 25 ౭௄ఋ௏ ࠗೞ పझ౟ Ѿҗ 30ୡ 28550ߣ

    ചݶ ૓ੑ 10s ੉࢚ ࣗਃ द पಁ 95% ࢿҕ
  64. Google I/O Extended 25 Cache, API, Database, Scale with Next.js,

    Supabase ؀ӏݽ ౟ې೗ਸ ୊ܻೞח ೐ۿ౟ ѐߊ੗੄ ੹ۚ
  65. Google I/O Extended 25 Auth, Lock, Webhook, Scheduler Cache, API,

    Database, Scale with Next.js, Supabase ؀ӏݽ ౟ې೗ਸ ୊ܻೞח ೐ۿ౟ ѐߊ੗੄ ੹ۚ