Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Taking a Go Service to Production: slog, Configuration, Graceful Shutdown, pprof and Small Containers
Getting a Go service ready for production means reading settings from environment variables into a struct, writing JSON logs with log/slog, catching SIGTERM with signal.NotifyContext and exiting through server.Shutdown, adding health checks and serving pprof on a separate port. In Bookstore: slog with the request ID, a drain delay, measuring container-aware GOMAXPROCS and GOMEMLIMIT, builds with -trimpath and ldflags, and a 4.72 MB distroless image.
From Go 1.22 to 1.27: Loop Variables, Routing, range-over-func, Green Tea GC, json/v2 and Generic Methods
In Go, the go line in go.mod and GODEBUG settings decide a release's behaviour, but removed settings end that protection: because Go 1.27 removed asynctimerchan, the timer behaviour of a module saying go 1.22 changed with nothing but a toolchain upgrade. The changes from 1.22 to 1.27 that matter for backend work, the nil check fix, os.Root, uuid, measuring the new allocator, what moving to json/v2 does to clients, and go fix modernizers.
Working with Strings in Go: strings, strconv, fmt Verbs, Bytes vs Runes and Turkish Characters
In Go a string is an immutable sequence of UTF-8 bytes, and the strings package ignores language: strings.EqualFold does not treat "istanbul" and "İSTANBUL" as equal, and Turkish rules need unicode.TurkishCase. Normalizing and validating ISBNs, strconv error types, reading Turkish-format prices, fmt verbs and go vet, measuring strings.Builder, and RE2-based regexp.
The time Package in Go: time.Time, Duration, Formatting with the Reference Time ("2006-01-02"), Time Zones and the Monotonic Clock
In Go a date format is not given with codes such as yyyy-MM-dd but by showing how the reference time 2006-01-02 15:04:05 is written; "yyyy-MM-dd" does not fail, it is printed as it is. Duration, json/v2 giving Duration no default format, time zones and the three-hour shift from post 11, time/tzdata on scratch images and Windows, a delivery estimate on the warehouse clock, the monotonic clock and Equal, and the time.After trap.
The slices, maps, sort and cmp Packages in Go: Sorting, Searching, Grouping and Collection Work with Iterators
In Go, multi-field sorting combines slices.SortStableFunc with cmp.Or and cmp.Compare; map iteration order changes on every run, and sorted keys need slices.Sorted(maps.Keys(m)). Adding ?sort= and a category summary to Bookstore, LINQ counterparts, backing-array traps with append and slices.Delete, json/v2 map order, measuring sort against slices, and Turkish sorting with x/text/collate.
io.Reader/io.Writer, os and bufio in Go: File Operations, Composing Streams and embed
In Go a file, a gzip stream, an HTTP body and a string all satisfy the same single-method io.Reader; when a function takes an io.Reader instead of a file name, a 1 GB log is processed with constant memory. bufio.Scanner's 64 KB line limit and silent stop, the Close error of a written file, flushing csv.Writer, composition with LimitReader/MultiWriter/TeeReader, and embedding an e-mail template into the binary with //go:embed.
HTTP Clients in Go: http.Client, Timeouts, Cancellation with context, Reusing the Transport and Retries
In Go, http.DefaultClient has no timeout; in production you use one shared http.Client, Transport timeouts for each phase, Client.Timeout per attempt and a context for the total budget. Which timeout covers which phase, Go 1.27 reading small bodies on Close to reuse the connection, MaxIdleConnsPerHost, checking 4xx/5xx, retries with backoff, jitter and Retry-After, idempotency, and testing a client with httptest.