Skip to content
Writing
GoGolangMicroservicesResilience

Go (Golang) Microservice for Email with Circuit Breakers & Retries

Learn how to write a production-grade Go service that dispatches millions of emails with resilient circuit breaking, retries, and zero memory leaks.

Tayyab MughalFounder & AI Chief2 min read

Why Go microservices need circuit breakers for external APIs

When downstream third-party networks experience temporary degradation, unbounded goroutines trying to send emails can exhaust system file descriptors and crash your service.

Implementing the Circuit Breaker pattern with sony/gobreaker ensures your Go service fails fast during upstream outages without cascading failures.

Go Email Client with Circuit Breaker (email.go)

Here is the complete Go implementation with circuit breakers and custom JSON transport.

GOLANG
package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/sony/gobreaker"
)

type EmailClient struct {
	apiKey     string
	httpClient *http.Client
	cb         *gobreaker.CircuitBreaker
}

type SendRequest struct {
	To      string `json:"to"`
	Subject string `json:"subject"`
	Text    string `json:"text"`
}

func NewEmailClient(apiKey string) *EmailClient {
	st := gobreaker.Settings{
		Name:        "SadaSendCircuitBreaker",
		MaxRequests: 5,
		Interval:    30 * time.Second,
		Timeout:     10 * time.Second,
	}
	return &EmailClient{
		apiKey:     apiKey,
		httpClient: &http.Client{Timeout: 5 * time.Second},
		cb:         gobreaker.NewCircuitBreaker(st),
	}
}

func (c *EmailClient) Send(ctx context.Context, req SendRequest) error {
	_, err := c.cb.Execute(func() (interface{}, error) {
		payload, _ := json.Marshal(req)
		httpReq, _ := http.NewRequestWithContext(ctx, "POST", "https://api.sadasend.com/v1/emails", bytes.NewBuffer(payload))
		httpReq.Header.Set("Authorization", "Bearer "+c.apiKey)
		httpReq.Header.Set("Content-Type", "application/json")

		resp, err := c.httpClient.Do(httpReq)
		if err != nil {
			return nil, err
		}
		defer resp.Body.Close()

		if resp.StatusCode >= 500 {
			return nil, fmt.Errorf("server error: %d", resp.StatusCode)
		}
		return nil, nil
	})
	return err
}

Core Advantages in Go Production Clusters

  • Zero goroutine leakage on connection stalls.
  • Fail-fast protection that recovers automatically when connectivity restores.
  • Native context.Context cancellation support for graceful server shutdowns.
Early Access

Building AI agents that send email?

Join the SadaSend early access waitlist to get scoped API keys, recipient allowlists, and Model Context Protocol (MCP) servers upon launch.

Rolling out in developer batches·No credit card needed
Social Hashtags & Share
#EmailAPI#DeveloperTools#Go#Golang#Microservices#Resilience
Tayyab MughalFounder & AI Chief

Building SadaSend — transactional email with an MCP server that has a ceiling. Writes about deliverability, email infrastructure, and what happens when you hand an autonomous agent a sending credential.

Keep reading