Durable Objects แก้ปัญหาอะไรที่ Redis แก้ไม่ได้

คำตอบสั้น: Durable Objects ไม่ใช่ Redis ที่เร็วกว่า สำหรับ caching ล้วน ๆ Redis เร็วกว่า มีโครงสร้างข้อมูลมากกว่า และมี ecosystem ที่ใหญ่กว่ามาก สิ่งที่ Durable Objects ให้แล้ว Redis ให้ไม่ได้ คือ หนึ่ง instance ที่มีอำนาจตัดสินจริงต่อหนึ่ง key ทั่วทั้งโลก โดยมีโค้ดของคุณรันอยู่ติดกับ state นั้น นี่คือสิ่งที่ทำให้ rate limiter ที่ต้องเป๊ะข้ามภูมิภาค ห้องแชท หรือเอกสารที่แก้ร่วมกัน เป็นไปได้โดยไม่ต้องเขียน distributed lock เอง

คำอธิบายที่นิยมที่สุดของ Durable Objects คือ Redis ที่มี compute ติดมาด้วย ซึ่งพอจะเข้าใจได้แต่ทำให้ตัดสินใจผิด เพราะมันชวนให้คุณเอา Durable Objects ไปทำงานที่ Redis ทำได้ดีกว่า แล้วคุณจะผิดหวัง

ความต่างที่แท้จริงอยู่ลึกกว่านั้น Redis คือ data structure server มันเก็บข้อมูลให้ และคุณเขียน logic ไว้ที่อื่น Durable Objects คือ compute กับ storage ที่หลอมรวมอยู่ใน instance เดียว ที่มีเพียงตัวเดียวในโลกต่อหนึ่ง ID และมันเป็น single-threaded

บทความนี้จะอธิบายว่าความต่างนี้สำคัญตรงไหน กรณีไหนที่มันเปลี่ยนสถาปัตยกรรมของคุณจริง ๆ และกรณีไหนที่ Redis ยังเป็นคำตอบที่ดีกว่า ตัวเลขทั้งหมดมาจากเอกสารทางการของ Cloudflare ตรวจสอบ ณ กรกฎาคม 2026

Redis กับ Durable Objects ไม่ใช่ของประเภทเดียวกัน

Redis เก็บข้อมูล คุณส่งคำสั่งไปแล้วมันตอบค่ากลับมา โค้ดของคุณรันอยู่คนละเครื่องกับ state เสมอ ถ้าคุณต้องการ read-modify-write ที่ซับกว่าหนึ่งคำสั่ง คุณต้องเขียน Lua script หรือสร้าง distributed lock เอง ทั้งสองทางมีต้นทุนด้านความถูกต้องที่คุณต้องแบกเอง

Durable Objects กลับด้าน โค้ดกับ state อยู่ด้วยกัน และ Cloudflare รับประกันว่าทุก request ที่มาที่ ID เดียวกันจะไปที่ instance เดียวกัน ไม่ว่าจะมาจากสิงคโปร์ แฟรงก์เฟิร์ต หรือซิดนีย์ และ instance นั้นเป็น single-threaded นั่นแปลว่า race condition แบบที่คุณต้องเขียน lock มากันใน Redis มันหายไปโดยโครงสร้าง

สิ่งที่ Redis แก้ไม่ได้

Rate limiting ที่ต้องเป๊ะข้ามภูมิภาค

สมมติคุณขาย API ที่คิดเงินตาม request และสัญญาระบุว่าลูกค้ายิงได้ 10,000 ครั้งต่อนาที ลูกค้ายิงมาจากไทย สิงคโปร์ และเยอรมนีพร้อมกัน

ถ้าคุณวาง Redis replica ไว้ทุกภูมิภาคเพื่อให้อ่านเร็ว คุณจะไม่มี counter ที่มีอำนาจตัดสินตัวเดียวอีกต่อไป การ replicate เป็นแบบ asynchronous แปลว่าสองภูมิภาคอาจอนุมัติ request ที่ควรจะถูกบล็อกพร้อมกัน ลูกค้าที่จ่ายค่า quota 10,000 จะยิงได้ 12,000

ถ้าคุณแก้ด้วยการใช้ Redis primary ตัวเดียวทั่วโลก คุณก็ได้ความถูกต้องกลับมา แต่ตอนนี้คุณมี single point ที่ต้องดูแลเอง มี failover ต้องเขียน มี latency ข้ามทวีปที่ทุก request ต้องจ่าย และเมื่อมันล่ม rate limiter ทั้งระบบก็ล่ม กล่าวคือคุณทำสิ่งที่ Durable Objects ทำอยู่แล้ว โดยที่คุณต้องดูแลเองทั้งหมด

ใน Durable Objects คุณใช้ customer ID เป็น key ของ object เท่านั้น ทุก request ของลูกค้ารายนั้น ไม่ว่ามาจากที่ไหนในโลก จะไปหา instance เดียวกัน ซึ่ง single-threaded โค้ด increment counter ตรง ๆ นั้นจึงเป็น atomic โดยอัตโนมัติ ไม่มี lock ไม่มี Lua script ไม่มี race

Coordination กับ state ที่ทำงานร่วมกัน

เอกสารที่หลายคนแก้พร้อมกัน ห้องเกมที่มีสถานะการเล่นร่วมกัน kanban board ที่ทุกคนเห็นการ์ดขยับเรียลไทม์ งานเหล่านี้ต้องการสองอย่าง หนึ่งคือ state ที่เชื่อถือได้ สองคือที่ทางให้ logic ของการรวม (merge) รันติดกับ state นั้น

Redis ให้ข้อแรกได้ แต่ไม่ให้ข้อสอง โค้ด merge ของคุณต้องรันอยู่บนเซิร์ฟเวอร์สักเครื่องที่ต้อง fetch state จาก Redis มาก่อน เขียนกลับ แล้ว broadcast ออกไปหาทุกคน ขณะที่ request อื่นกำลังทำอย่างเดียวกันอยู่บนเครื่องอีกเครื่อง นี่คือจุดที่ lock เข้ามาอยู่ในชีวิตคุณ

ใน Durable Objects ห้องหนึ่งคือ object หนึ่ง โค้ด merge รันอยู่ใน object นั้น state ก็อยู่ใน object นั้น ทุกคนในห้องต่อ WebSocket เข้า object เดียวกัน ไม่มีการ fetch state ข้ามเครือข่าย ไม่มี pub/sub fan-out ข้ามเซิร์ฟเวอร์ ไม่มี lock

WebSocket ที่หลับได้ (Hibernation)

Redis ไม่ได้ถือ connection ของผู้ใช้เอง คุณต้องมีเซิร์ฟเวอร์จริง ๆ คอยถือ WebSocket อยู่ และเซิร์ฟเวอร์นั้นต้องจ่ายค่า RAM ตลอดเวลาที่ connection เปิดอยู่ แม้จะไม่มีข้อความวิ่งเข้ามาเลยก็ตาม

Durable Objects มี WebSocket Hibernation API ที่ตัดค่า duration ออกเมื่อ object ว่างและเข้าเงื่อนไข hibernation ได้ เอกสารระบุชัดว่า Durable Object ที่ idle และเข้าเงื่อนไข hibernate จะไม่ถูกคิดเงินค่า duration เลย แม้ก่อนที่ runtime จะ hibernate มันจริง ๆ ความต่างของตัวเลขอยู่ในหัวข้อตัวอย่างข้างล่าง

เปรียบเชิงสถาปัตยกรรม

ประเด็น Durable Objects Redis
มันคืออะไร Compute + storage ที่ผูกกันเป็น instance เดียวต่อ key Data structure server โค้ดอยู่ที่อื่น
Consistency ต่อ key หนึ่ง instance ที่มีอำนาจตัดสินทั่วโลก single-threaded Primary เดียว (strong) หรือ replica หลายตัว (eventual)
Read-modify-write Atomic โดยโครงสร้าง ไม่ต้องมี lock ต้องใช้ Lua script, MULTI/EXEC หรือ distributed lock
ถือ WebSocket ได้ พร้อม Hibernation API ไม่ได้ ต้องมีเซิร์ฟเวอร์แยกต่างหาก
ความเร็ว cache hit ใน region เดียวกัน ช้ากว่า เพราะ request ต้องวิ่งไปหา instance ที่อาจอยู่คนละทวีป เร็วกว่า in-memory ในเครือข่ายเดียวกัน
โครงสร้างข้อมูล SQLite หรือ key-value ต่อ object String, hash, list, set, sorted set, stream, HyperLogLog
Throughput ต่อหนึ่ง key Soft limit ประมาณ 1,000 request ต่อวินาทีต่อ object สูงกว่ามากต่อหนึ่ง key
Ecosystem และคนที่รู้ ใหม่ เฉพาะ Cloudflare กว้างมาก มีไลบรารีทุกภาษา วิศวกรทุกคนเคยใช้
การดูแล ไม่มี เป็น managed เต็มตัว ต้องตั้งเอง หรือจ่าย managed service

ข้อจำกัดและราคา (ราคา ณ กรกฎาคม 2026)

ตัวเลขที่คุณต้องจำ ตัวหนึ่งคือ soft limit ประมาณ 1,000 request ต่อวินาทีต่อ object หนึ่งตัว อีกตัวคือ duration ถูกคิดเงินตาม wall-clock เมื่อ object ยัง active หรือ idle แต่ hibernate ไม่ได้ โดยคิดจากหน่วยความจำ 128 MB ที่จัดสรรให้ ไม่ว่าคุณจะใช้จริงเท่าไหร่

รายการ Workers Free Workers Paid
Requests 100,000 / วัน 1 ล้าน / เดือน ส่วนเกิน 0.15 ดอลลาร์ / ล้าน
Duration 13,000 GB-s / วัน 400,000 GB-s / เดือน ส่วนเกิน 12.50 ดอลลาร์ / ล้าน GB-s
SQL rows read 5 ล้าน / วัน 25,000 ล้าน / เดือน ส่วนเกิน 0.001 ดอลลาร์ / ล้านแถว
SQL rows written 100,000 / วัน 50 ล้าน / เดือน ส่วนเกิน 1.00 ดอลลาร์ / ล้านแถว
SQL stored data 5 GB รวม 5 GB-month ส่วนเกิน 0.20 ดอลลาร์ / GB-month
พื้นที่ต่อ object รวมทั้งบัญชี 5 GB 10 GB ต่อ object (รวมทั้งบัญชีไม่จำกัด)

ข้อสำคัญเรื่อการคิดเงิน WebSocket คือ Cloudflare ใช้อัตรา 20:1 กับข้อความขาเข้า แปลว่า 100 ข้อความขาเข้าจะคิดเป็น 5 request ส่วนข้อความขาออกไม่คิดเงินเลย และ outbound connection ที่เปิดค้างจะกันไม่ให้ object hibernate และทำให้เกิดค่า duration ได้นานถึง 15 นาทีต่อ connection แม้จะไม่มี request เข้ามาเลย

ตัวอย่าง: แอปแชทที่มี 10,000 WebSocket พร้อมกัน

สมมติคุณทำแอปแชทสำหรับองค์กร มีห้องแชท 100 ห้อง แต่ละห้องมีคนอยู่ 100 คน รวมเป็น 10,000 WebSocket ที่เปิดค้างพร้อมกัน แต่ละคนส่งข้อความนาน ๆ ครั้ง ประมาณนาทีละข้อความ

โครงสร้าง

หนึ่งห้องแชทคือหนึ่ง Durable Object ทุกคนในห้องต่อ WebSocket เข้า object เดียวกัน เมื่อมีข้อความเข้ามา object ก็ broadcast ออกไปทุก socket ในห้อง ไม่มี pub/sub ข้ามเซิร์ฟเวอร์ ไม่มี sticky session ที่ต้องจัดการ เพราะ request ที่มาที่ room ID เดียวกันจะไปที่ object เดียวกันเสมอ

สิ่งที่ต้องทำให้ถูกคือใช้ WebSocket Hibernation API ไม่ใช่ accept() ธรรมดา เอกสารของ Cloudflare ระบุชัดว่าการเรียก accept() บน WebSocket จะทำให้เกิดค่า duration ตลอดเวลาที่ WebSocket เชื่อมอยู่

ตัวเลขจริงจากเอกสาร Cloudflare

Cloudflare คำนวณเคสนี้ไว้ให้เรียบร้อยแล้วในเอกสารราคา กรณี 100 Durable Objects ที่มี hibernatable WebSocket อย่างละ 100 ตัว คลิกออกหนึ่งข้อความต่อนาที โดยใช้เวลาประมวลผล 10 มิลลิวินาทีต่อข้อความ ตลอด 24 ชั่วโมง ทุกวัน ตลอดเดือน ค่าใช้จ่ายโดยประมาณอยู่ที่ 10.00 ดอลลาร์ต่อเดือน (request 3.09 ดอลลาร์ บวก duration 1.91 ดอลลาร์ บวกค่าขั้นต่ำ 5 ดอลลาร์)

ทีนี้เทียบกับอีกเคสหนึ่งในเอกสารเดียวกัน 100 Durable Objects ที่มี WebSocket อย่างละ 50 ตัว (คือ 5,000 connection เท่านั้น และเปิดแค่ 8 ชั่วโมงต่อวัน) แต่ไม่ใช้ hibernation ค่าใช้จ่ายอยู่ที่ประมาณ 138.65 ดอลลาร์ต่อเดือน โดย duration กินไป 133.24 ดอลลาร์

กล่าวอีกแบบคือ connection มากกว่าสองเท่า เปิดนานกว่าสามเท่า แต่จ่ายน้อยกว่าสิบสี่เท่า เพราะ hibernation ตัดค่า duration ของเวลาที่ object นั่งเฉย ๆ รอข้อความออกไป นี่คือความแตกต่างระหว่างคนที่อ่านเอกสารกับคนที่ไม่อ่าน

Rate limiter ที่ต้องเป๊ะ

ในระบบเดียวกันนี้ ถ้าคุณต้องจำกัดจำนวนข้อความต่อนาทีต่อผู้ใช้อย่างเคร่งครัด คุณสร้าง Durable Object อีกตัวที่ key ด้วย user ID ก่อน broadcast ทุกครั้ง Worker จะเรียก object นั้นเพื่อเช็ค quota เพราะ object เป็นจุดเดียวทั่วโลกสำหรับ user นั้น ตัวเลขจึงเป๊ะโดยไม่มีเงื่อนไข ไม่ว่า request จะเข้ามาที่เอเชียตะวันออกเฉียงใต้หรือยุโรปก็ตาม

ราคาที่ต้องจ่ายคือ latency เพราะ request จากสิงคโปร์ต้องวิ่งไปหา object ซึ่งอาจอยู่ที่ไหนก็ได้ในโลก นี่คือต้นทุนของความเป๊ะ และมันเป็นต้นทุนเดียวกันกับที่คุณจะจ่ายถ้าใช้ Redis primary ตัวเดียวทั่วโลก ต่างกันตรงที่คุณไม่ต้องดูแลเซิร์ฟเวอร์ตัวนั้น

เมื่อไหร่ที่ Redis ชนะ

ส่วนนี้สำคัญมาก เพราะคนที่เพิ่งอ่านเรื่อง Durable Objects มักอยากเอามันไปแทน Redis ทุกที่ ซึ่งเป็นความคิดที่แพง

Cache ล้วน ๆ

ถ้าสิ่งที่คุณต้องการคือ cache ที่อ่านเร็ว ๆ อยู่ข้างเซิร์ฟเวอร์ของคุณ Redis ชนะขาดลอย มันเป็น in-memory store ที่อยู่ใน VPC เดียวกับแอปของคุณ ส่วน Durable Object คือ instance ที่อาจอยู่คนละทวีปกับ request ของคุณ การเอา DO มาทำ cache คือการจ่าย latency เพื่อซื้อ consistency ที่คุณไม่ได้ต้องการ

โครงสร้างข้อมูลและ ecosystem

Redis มี sorted set ที่ทำ leaderboard ได้ในคำสั่งเดียว มี stream สำหรับ event log มี HyperLogLog สำหรับนับ unique แบบประมาณ มี pub/sub มี pipeline มีไลบรารีที่เขียนมา 15 ปี มี Redis Insight มี redis-cli และมีวิศวกรที่เคย debug มันมาแล้ว ใน Durable Objects คุณเขียนเองหมด นี่เป็นต้นทุนที่จริง ๆ แม้จะไม่มีในใบแจ้งหนี้ก็ตาม

Throughput ต่อ key เดียว

เอกสารของ Cloudflare ระบุ soft limit ที่ประมาณ 1,000 request ต่อวินาทีต่อ Durable Object หนึ่งตัว ถ้า key ของคุณมี hot spot เช่น counter ตัวเดียวที่ทุกคนในระบบยิงเข้ามา คุณจะชนเพดานนั้น และ object จะคืน error overloaded กลับมา Redis รับได้มากกว่านั้นต่อ key เดียว

ทีมที่รู้ Redis อยู่แล้ว

ถ้าทีมคุณมี Redis ที่ทำงานดี มี monitoring มี runbook และไม่มีปัญหาเรื่อง consistency ที่เจ็บจริง การย้ายมา Durable Objects คือการเสียเวลา ให้เอา Durable Objects ไปแก้เฉพาะเคสที่ Redis แก้ไม่ได้ แล้วให้ Redis ทำงานที่มันทำได้ดีต่อไป

สรุป

คำถามที่ถูกไม่ใช่ Durable Objects หรือ Redis แต่คือ งานนี้ต้องการจุดตัดสินที่มีอำนาจเพียงจุดเดียวหรือไม่ ถ้าต้อง ให้ใช้ Durable Objects ถ้าไม่ต้อง และสิ่งที่คุณต้องการคือ cache เร็ว ๆ Redis ยังเป็นเครื่องมือที่ดีกว่า ระบบจริงส่วนมากใช้ทั้งสองอย่างคู่กัน

ถ้าคุณกำลังประเมินว่า Workers เหมาะกับระบบของคุณหรือไม่ เราเขียนเรื่อง เมื่อไหร่ที่ไม่ควรใช้ Cloudflare Workers ไว้แล้ว

Cipher ออกแบบและ implement ระบบบน Cloudflare Developer Platform ให้ธุรกิจในประเทศไทย ถ้าคุณมีงาน real-time หรืองาน coordination ที่กำลังฝืนแก้ด้วย Redis อยู่ เราประเมินสถาปัตยกรรมและบอกตรง ๆ ได้ว่าจุดไหนควรเปลี่ยน และจุดไหนควรปล่อยไว้อย่างที่มันเป็น

คำถามที่พบบ่อย

Durable Objects เร็วกว่า Redis ไหม

โดยทั่วไปไม่ สำหรับ cache hit ที่เซิร์ฟเวอร์กับ Redis อยู่ region เดียวกัน Redis เร็วกว่า เพราะ request ไม่ต้องวิ่งข้ามเครือข่ายไปหา instance ที่อาจอยู่อีกทวีปหนึ่ง คุณควรเลือก Durable Objects เพราะต้องการ consistency ของจุดเดียว ไม่ใช่เพราะต้องการความเร็ว

Durable Object หนึ่งตัวรับได้กี่ request ต่อวินาที

เอกสารของ Cloudflare ระบุ soft limit ที่ประมาณ 1,000 request ต่อวินาทีต่อ object หนึ่งตัว แต่จำนวน object ต่อ namespace ไม่จำกัด การออกแบบจึงต้องหลีกเลี่ยง hot key ที่ทุก request วิ่งเข้า object เดียวกัน มิฉะนั้น object จะคืน error overloaded

WebSocket Hibernation คืออะไร และทำไมต้องสนใจ

Hibernation ทำให้ Durable Object ที่ถือ WebSocket อยู่แต่ไม่มีงานทำ ไม่ถูกคิดค่า duration ตามเอกสารของ Cloudflare เคสตัวอย่าง 100 object ที่มี hibernatable WebSocket อย่างละ 100 ตัว มีค่าใช้จ่ายประมาณ 10.00 ดอลลาร์ต่อเดือน ขณะที่เคสที่เรียก accept() ธรรมดาจะเกิดค่า duration ตลอดเวลาที่ WebSocket เชื่อมอยู่

Durable Objects ทำ rate limiting ที่เป๊ะข้ามภูมิภาคได้จริงไหม

ได้ เพราะ request ทุกตัวที่มาที่ ID เดียวกันจะไปที่ instance เดียวกันทั่วโลก และ instance นั้นเป็น single-threaded การ increment counter จึง atomic โดยโครงสร้าง ไม่ต้องมี distributed lock หรือ Lua script ต้นทุนคือ latency เพราะ request อาจต้องวิ่งไปหา object ที่อยู่คนละทวีป

Durable Objects คิดเงินอย่างไร

ราคา ณ กรกฎาคม 2026 แผน Workers Paid รวม 1 ล้าน request ต่อเดือน ส่วนเกินคิด 0.15 ดอลลาร์ต่อล้าน request และรวม duration 400,000 GB-s ต่อเดือน ส่วนเกินคิด 12.50 ดอลลาร์ต่อล้าน GB-s โดย duration คิดจากหน่วยความจำ 128 MB ที่จัดสรรให้เสมอ ไม่ว่าจะใช้จริงเท่าไหร่

Scroll to Top