Tit Petric's Blog
February 21, 2021
Real world optimisation
Don’t optimize prematurely - but have a plan how you’re going to do it.With the services I write, a lot of the code may be clear, simple andreadable over actually optimizing for speed. Sometimes, the differencebetween that code, and the optimized code, is a short refactor.
One of the services I write, is a comments service for the Sloveniannational TV & Radio station, RTV Slovenia. On a typical day, the ElasticAPM transactions end up being something like this:
What this tells us, that w...
February 7, 2021
How we use logging
When it comes to logging in your Go services, the immediate package toreach for is the standard library log package.As it happens, you’ll outgrow the log package needs almost immediately,because the log package is able to send the relevant logs only to oneio.Writer stream, by default sent to os.Stderr.
There may be other needs that you may feel you want to address:
Structured logging that can be consumed by external services like Logstash, ELKSplit the log destination based on message se...August 13, 2020
Go and JSON encoding/decoding
After a few years of writing JSON APIs for various purposes, with more
success than this article may lead you to believe, I have come to the
conclusion that the JSON support in the wider Go ecosystem is broken. And
it isn’t really Go’s fault, but fixing it so it plays nice with other
very common programming languages is something that hasn’t been given
much consideration to.
All the problems of JSON encoding and decoding stem from being strict about
the encoding/json package behavior, imagining...
May 29, 2020
Waiting on Goroutines
Go is a program language which has basic concurrency syntax built in.
Maybe calling it basic isn’t exactly right - simplicity is the more
correct description. After all to run a function independent of the main
execution, all you have to do is prefix the invocation with the go
keyword - that function call will now live on it’s own goroutine.
For people not familiar with threading or concurrency in general, it may
take a while to figure out what the behaviour here is. After all, when
you run a f...
April 28, 2020
Extending pflag with environment variables
Chances are that if you’re writing Go code for a while now, your needs for command line arguments have grown beyond just what the standard library flag package is able to provide.
A quick listTo quickly list a few packages:
namsral/flag - add environment variable parsing, spf13/pflag - use posix/gnu-style --flags, urfave/cli - adds a default action and command actions, env aliases,… spf13/cobra - an interface for cli commands like git and go tools, spf13/viper - a larger...February 17, 2020
Optimizing requests with a queue
With our background jobs interface in place, we can create an API that will queue our incoming data and flush it to the database at a defined frequency. Flushing our data in bulk will give us performance advantages.
The QueueA basic Queue in Go is a slice. To extend the queue, you can call append, which allocates a larger slice if required. Since this is not thread safe, we need to use locking to ensure that the queue is modified safely.
// Queue provides a queuing structure for Incoming{}...January 13, 2020
Microservice background jobs
API services, especially low latency ones, will resort to background jobs to process data faster on ingesting it, and aggregating and flushing it to backend services in an optimal way.
Adding background jobs to our serviceIn our stats microservice, we issue insert queries for each request directly into the database. The database supports extended inserts, meaning we could flush thousands of rows at the same time, and actually increase throughput, since adding 10K rows to the database with a...
December 18, 2019
Go: Stress testing our service
As we implemented our service that adds pageviews to the database, we realize an unfortunate circumstance. Each insert query takes about 12ms, which means our request rate, at least per single CPU core, is poor. We’re talking about 83 req/s poor.
But as we know that scaling isn’t linear and you shouldn’t judge a single request, we need to perform some stress testing to give us a better idea of where we are.
Now, the best practices of stress testing suggest that you need...
December 17, 2019
Instrumenting the Database client with Elastic APM
After we set up Elastic APM to log our request transaction, the following thing we wish to instrument are the SQL queries going to our database endpoint. Elastic APM provides instrumentation that wraps the database/sql driver, which produces an *sql.DB.
Extending DB connectionWe already planned to produce a *sqlx.DB for this eventuality with the Connector field function in db.ConnectionOptions:
// Connector is an optional parameter to produce our // own *sql.DB, which is then wrapped in...

