# 🚀 Senior Go Interview Question: The Graceful Shutdown Trap

If you are interviewing for a **Senior Backend** role in Go, you will almost certainly be asked about concurrency and lifecycle management.

Here is a classic question that perfectly separates mid-level developers from seniors:

> *"How do you implement a graceful shutdown for an HTTP server that also processes background jobs, ensuring zero data loss, handling in-flight requests, and preventing goroutine leaks?"*

### 🪤 The Trap

A mid-level developer will usually suggest using `os/signal` to catch `SIGTERM` and calling `server.Close()`.

**Why it fails:** `Close()` immediately closes all active net.Listeners and connections. In-flight requests will be dropped, and background workers might be killed mid-transaction, leading to corrupted data or inconsistent states.

### 💡 The Senior Approach

A senior engineer knows that graceful shutdown is about **cooperative cancellation** using the `context` package.

Here is the checklist of what your answer should cover:

1.  **Signal Handling:** Use `signal.NotifyContext` to listen for `SIGINT` and `SIGTERM`.
    
2.  **Context Propagation:** Pass the context down to all background workers and database calls. When the signal is caught, the context is automatically canceled.
    
3.  **HTTP Server Shutdown:** Use `server.Shutdown(ctx)` instead of `Close()`. This stops accepting new connections but waits for active requests to finish.
    
4.  **Timeout Control:** Wrap the shutdown context with a timeout (e.g., `context.WithTimeout`) so the app doesn't hang forever if a request is stuck.
    
5.  **WaitGroups:** Use `sync.WaitGroup` to track background workers. The main goroutine should wait for the `WaitGroup` to hit zero before exiting the process.
    

### 💻 The Golden Snippet

```go
// Create a context that listens for OS signals
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

// ... start server and workers ...

<-ctx.Done() // Block until signal is received
log.Println("Shutting down gracefully...")

// Give outstanding requests 10 seconds to complete
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

if err := srv.Shutdown(shutdownCtx); err != nil {
    log.Fatalf("Server forced to shutdown: %v", err)
}

wg.Wait() // Wait for background workers to finish
log.Println("Server exited properly")
```

### 🗣️ Over to you

How does your team handle graceful shutdowns in production? Do you use any specific libraries or patterns for background workers? Let me know in the comments! 👇

**🚀 Want to test your skills?**  
I’m building an interactive platform to help developers practice real-world backend scenarios and compare their level with others. If you're preparing for interviews, come try out our Go/Backend quizzes here: [https://skillhacker.io](https://skillhacker.io/backend-developer)
