Server Patterns
Backend cache conventions that pair well with Tide.
Tide is a client library and works with any backend. These server-side patterns maximize Tide performance.
ETag / 304 responses
When Tide sends If-None-Match, respond with 304 if data unchanged. Zero bandwidth on polls with no new data.
go
// Go/Fiber example
func handler(c *fiber.Ctx) error {
data := getCachedData()
etag := fmt.Sprintf("\"%x\"", sha256.Sum256(data))
if c.Get("If-None-Match") == etag {
return c.SendStatus(304)
}
c.Set("ETag", etag)
return c.Send(data)
} Pre-computed cache (zero-processing serve)
Marshal JSON once in your background loop (WS broadcast, scheduler). HTTP handler serves raw bytes — no serialization per request.
go
var cachedBytes atomic.Value // []byte
// Background loop (every 3-5s)
func updateCache(snapshot any) {
bytes, _ := json.Marshal(snapshot)
cachedBytes.Store(bytes)
}
// HTTP handler — instant serve
func handler(c *fiber.Ctx) error {
data := cachedBytes.Load().([]byte)
c.Set("Content-Type", "application/json")
return c.Send(data)
} WebSocket broadcast enrichment
Enrich your WS broadcast with all fields the frontend needs. Sparse WS data forces Tide to fall back to HTTP polling.
go
// Good — WS delivers complete data, Tide stops polling
hub.Broadcast(map[string]any{
"type": "dashboard",
"data": map[string]any{
"stack": enrichedStackSnapshot,
"scheduler": schedulerSnapshot,
},
})
// Bad — sparse data causes flicker, Tide can't use it
hub.Broadcast(map[string]any{
"type": "update",
"id": "stack",
"pid": 1234, // missing most fields
}) Rule of thumb: if your WS message has fewer fields than the HTTP response, return null from the ws handler and let Tide use HTTP polling instead.