[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"academy-blogs-en-1-1-all-ep108-timeout-connection-cleanup-websocket-golang-all--*":3,"academy-blog-translations-huetis3lx1o0tll":94},{"data":4,"page":82,"perPage":82,"totalItems":82,"totalPages":82},[5],{"alt":6,"collectionId":7,"collectionName":8,"content":9,"cover_image":10,"cover_image_path":11,"created":12,"created_by":13,"expand":14,"id":88,"keywords":89,"locale":64,"published_at":90,"scheduled_at":13,"school_blog":86,"short_description":91,"slug":92,"status":84,"title":6,"updated":93,"updated_by":13,"views":87},"EP.108 Advanced Timeout and Connection Cleanup Techniques","sclblg987654321","school_blog_translations","\u003Cp>When your WebSocket Server enters a real Production Environment, one of the most common problems is stale connections or idle connections that are no longer active but still consume system resources.\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>If left unmanaged, this can lead to resource leaks, which waste CPU and memory — eventually slowing down your system and even causing crashes.\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>In this episode, you’ll learn essential techniques to:\u003C\u002Fp>\u003Cul>\u003Cli>Set timeouts to detect unresponsive connections\u003C\u002Fli>\u003Cli>Monitor idle connections\u003C\u002Fli>\u003Cli>Build cleanup mechanisms to handle stale connections\u003C\u002Fli>\u003C\u002Ful>\u003Cp>All to make your WebSocket Server more stable, secure, and scalable for production use. 🔧\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🧩 1. Why Timeout and Cleanup Are Necessary\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>WebSocket is a long-lived connection that might remain open without being properly closed. For example:\u003C\u002Fp>\u003Cul>\u003Cli>A user closes the browser without sending a close frame\u003C\u002Fli>\u003Cli>Temporary network drops\u003C\u002Fli>\u003Cli>The client stops sending data for too long\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>Without a proper management system, this results in:\u003C\u002Fp>\u003Cp>❌ Memory leaks from stuck connections\u003Cbr>❌ Unnecessary CPU usage\u003Cbr>❌ Limits on the number of users your system can handle\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🕒 2. Timeout Technique Using Ping\u002FPong\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>Go supports Ping\u002FPong via \u003Ccode inline=\"\">gorilla\u002Fwebsocket\u003C\u002Fcode>, which helps check whether a client is still active.\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>✅ Example Code:\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">const (\n\tpongWait   = 10 * time.Second\n\tpingPeriod = (pongWait * 9) \u002F 10\n)\n\nconn.SetReadDeadline(time.Now().Add(pongWait))\n\nconn.SetPongHandler(func(string) error {\n\tconn.SetReadDeadline(time.Now().Add(pongWait))\n\treturn nil\n})\n\nticker := time.NewTicker(pingPeriod)\ndefer ticker.Stop()\n\nfor {\n\tselect {\n\tcase &lt;-ticker.C:\n\t\tif err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {\n\t\t\tlog.Println(\"Ping error:\", err)\n\t\t\treturn\n\t\t}\n\tdefault:\n\t\t_, _, err := conn.ReadMessage()\n\t\tif err != nil {\n\t\t\tlog.Println(\"Connection closed:\", err)\n\t\t\treturn\n\t\t}\n\t}\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>🔍 Explanation:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Ccode inline=\"\">SetReadDeadline\u003C\u002Fcode>: Set a timeout if no data or pong is received\u003C\u002Fli>\u003Cli>\u003Ccode inline=\"\">WriteMessage(PingMessage)\u003C\u002Fcode>: Send ping to the client\u003C\u002Fli>\u003Cli>\u003Ccode inline=\"\">SetPongHandler\u003C\u002Fcode>: Extend timeout if pong is received\u003C\u002Fli>\u003Cli>If timeout occurs → connection is closed automatically\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🧹 3. Cleanup Stale Connections Using Worker\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>In large-scale systems with tens of thousands of connections, you need a worker that periodically removes inactive connections from memory.\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>✅ Example Code:\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">type Client struct {\n\tID         string\n\tConnection *websocket.Conn\n\tLastActive time.Time\n}\n\nfunc cleanupInactiveConnections() {\n\tfor {\n\t\ttime.Sleep(30 * time.Second)\n\t\tfor id, client := range clients {\n\t\t\tif time.Since(client.LastActive) &gt; 1*time.Minute {\n\t\t\t\tlog.Printf(\"Closing inactive connection: %s\\n\", id)\n\t\t\t\tclient.Connection.Close()\n\t\t\t\tdelete(clients, id)\n\t\t\t}\n\t\t}\n\t}\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cul>\u003Cli>Check every 30 seconds\u003C\u002Fli>\u003Cli>If inactive for more than 1 minute → close and remove the connection\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>⚙️ 4. Best Practices for Timeout and Cleanup\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cfigure class=\"table\">\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Practice\u003C\u002Fth>\u003Cth>Details\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\u003Ctr>\u003Ctd>⏱ Set Read\u002FWrite Deadline\u003C\u002Ftd>\u003Ctd>Close unresponsive connections\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>🔄 Use Ping\u002FPong Mechanism\u003C\u002Ftd>\u003Ctd>Check if client is still active\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>🧹 Use Goroutine Cleanup Worker\u003C\u002Ftd>\u003Ctd>Remove expired connections\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>🧠 Store Last Active Timestamps\u003C\u002Ftd>\u003Ctd>Track client activity\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>🧯 Handle Panic\u003C\u002Ftd>\u003Ctd>Prevent system crash during cleanup\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003C\u002Ffigure>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🧠 5. Debug and Monitor the System\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>Once you've implemented timeout and cleanup:\u003C\u002Fp>\u003Cul>\u003Cli>Use Logs: Track when connections are closed\u003C\u002Fli>\u003Cli>Use Metrics: Monitor number of active connections\u003C\u002Fli>\u003Cli>Use pprof: Check for goroutine or memory leaks\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🚀 Challenge\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>Enable Ping\u002FPong and Timeout, then:\u003C\u002Fp>\u003Cul>\u003Cli>Leave an idle connection open\u003C\u002Fli>\u003Cli>Close browser without sending a close frame\u003C\u002Fli>\u003Cli>See if the server auto-closes the connection\u003C\u002Fli>\u003C\u002Ful>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>You'll notice your WebSocket Server becomes:\u003C\u002Fp>\u003Cp>✅ Lighter\u003Cbr>✅ Free from resource leaks\u003Cbr>✅ More ready to handle higher loads 🚀\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Chr>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>🌟 Next EP:\u003C\u002Fh2>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>EP.109: Optimizing WebSocket Performance for Mobile Devices\u003C\u002Fp>\u003Cp>Learn techniques to improve WebSocket performance on mobile, including:\u003C\u002Fp>\u003Cul>\u003Cli>Reducing power consumption\u003C\u002Fli>\u003Cli>Handling reconnect when signal drops\u003C\u002Fli>\u003Cli>Adjusting timeout for mobile behavior\u003C\u002Fli>\u003C\u002Ful>\u003Cp>📱 With real-world production-ready Go code examples!\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp data-start=\"498\" data-end=\"834\">\u003Cstrong>Read more\u003C\u002Fstrong>\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp data-start=\"498\" data-end=\"834\">\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.superdev.school\u002Fblogs\u002Fcategories\u002FGolang\">\u003Cstrong>Golang The Series\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp data-start=\"498\" data-end=\"834\">\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.superdev.school\u002Fblogs\u002Fcategories\u002FJS2GO\">\u003Cstrong>JS2GO\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp data-start=\"498\" data-end=\"834\">\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.superdev.school\u002Fen\u002Fblogs\u002Fcategories\u002FTailwind%20CSS\">\u003Cstrong>10 Eps That Will Make You a Pro Tailwind CSS Overnight\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Cp>\u003Cstrong>🔵 Facebook: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.facebook.com\u002Fsuperdev.academy.th\">\u003Cstrong>Superdev Academy\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003Cp>\u003Cstrong>🔴 YouTube: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.youtube.com\u002Fchannel\u002FUC2eI2RxcA2zbTqZyHyWIfRg\">\u003Cstrong>Superdev Academy\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003Cp>\u003Cstrong>📸 Instagram: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.instagram.com\u002Fsuperdevschool\u002F\">\u003Cstrong>Superdev Academy\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003Cp>\u003Cstrong>🎬 TikTok: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.tiktok.com\u002F@superdevacademy?lang=th-TH\">\u003Cstrong>https:\u002F\u002Fwww.tiktok.com\u002F@superdevacademy?lang=th-TH\u003C\u002Fstrong>\u003C\u002Fa>\u003C\u002Fp>\u003Cp>\u003Cstrong>🌐 Website: \u003C\u002Fstrong>\u003Ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\u002F\u002Fwww.superdevacademy.com\u002Fen\">\u003Cstrong>https:\u002F\u002Fwww.superdevacademy.com\u002Fen\u003C\u002Fstrong>\u003C\u002Fa>\u003Cstrong>&nbsp;\u003C\u002Fstrong>\u003C\u002Fp>","188_11zon_3f0291extc.webp","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclblg987654321\u002F0xxaut2o20jbu86\u002F188_11zon_3f0291extc.webp","2026-03-04 08:45:36.917Z","",{"keywords":15,"locale":58,"school_blog":68},[16,23,28,33,38,43,48,53],{"collectionId":17,"collectionName":18,"created":19,"created_by":13,"id":20,"name":21,"updated":22,"updated_by":13},"sclkey987654321","school_keywords","2026-03-04 08:34:00.920Z","ecac9y661or1xka","WebSocket","2026-04-10 16:08:05.227Z",{"collectionId":17,"collectionName":18,"created":24,"created_by":13,"id":25,"name":26,"updated":27,"updated_by":13},"2026-03-04 08:44:48.724Z","s6xhnfomy7n5ycp","WebSocket Server","2026-04-10 16:12:50.171Z",{"collectionId":17,"collectionName":18,"created":29,"created_by":13,"id":30,"name":31,"updated":32,"updated_by":13},"2026-03-04 08:45:35.177Z","ljqmsdx1e0bcmav","Timeout","2026-04-10 16:13:00.233Z",{"collectionId":17,"collectionName":18,"created":34,"created_by":13,"id":35,"name":36,"updated":37,"updated_by":13},"2026-03-04 08:45:35.456Z","p12faqv7fmetlja","Golang timeouts","2026-04-10 16:13:00.381Z",{"collectionId":17,"collectionName":18,"created":39,"created_by":13,"id":40,"name":41,"updated":42,"updated_by":13},"2026-03-04 08:20:11.547Z","ey3puyme01a9bsw","Go","2026-04-10 16:07:25.893Z",{"collectionId":17,"collectionName":18,"created":44,"created_by":13,"id":45,"name":46,"updated":47,"updated_by":13},"2026-03-04 08:20:14.253Z","ah6lvy4x8qe08l5","Golang","2026-04-10 16:07:26.172Z",{"collectionId":17,"collectionName":18,"created":49,"created_by":13,"id":50,"name":51,"updated":52,"updated_by":13},"2026-03-04 08:45:34.555Z","pcr9o7q0iswjgjp","Go Language","2026-04-10 16:13:00.018Z",{"collectionId":17,"collectionName":18,"created":54,"created_by":13,"id":55,"name":56,"updated":57,"updated_by":13},"2026-03-04 08:45:35.697Z","14mxfvvebe39f82","Cleanup","2026-04-10 16:13:00.513Z",{"code":59,"collectionId":60,"collectionName":61,"created":62,"flag":63,"id":64,"is_default":65,"label":66,"updated":67},"en","pbc_1989393366","locales","2026-01-22 11:00:02.726Z","twemoji:flag-united-states","qv9c1llfov2d88z",false,"English","2026-04-10 15:42:46.825Z",{"category":69,"collectionId":70,"collectionName":71,"expand":72,"id":86,"views":87},"wqxt7ag2gn7xcmk","pbc_2105096300","school_blogs",{"category":73},{"blogIds":74,"collectionId":75,"collectionName":76,"created":77,"created_by":13,"id":69,"image":78,"image_alt":13,"image_path":79,"label":80,"name":81,"priority":82,"publish_at":83,"scheduled_at":13,"status":84,"updated":85,"updated_by":13},[],"sclcatblg987654321","school_category_blogs","2026-03-04 08:33:53.210Z","59ty92ns80w_15oc1implw.png","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclcatblg987654321\u002Fwqxt7ag2gn7xcmk\u002F59ty92ns80w_15oc1implw.png",{"en":81,"th":81},"Golang The Series",1,"2026-03-16 04:39:38.440Z","published","2026-04-25 02:32:15.470Z","huetis3lx1o0tll",213,"0xxaut2o20jbu86",[20,25,30,35,40,45,50,55],"2025-11-10 09:04:48.079Z","Discover how to manage stale or idle WebSocket connections using Timeout and Cleanup techniques to keep your production server stable and resource-efficient — with real-world Go code examples.","ep108-timeout-connection-cleanup-websocket-golang","2026-04-25 02:47:55.055Z",{"en":92}]