Concurrent logging

June 18, 2026

One last note in the performance section…

How does logging work in a concurrent system?

Performance considerations

The built-in handlers acquire a lock before calling io.Writer.Write to ensure that exactly one Record is written at a time in its entirety. Although each log record has a timestamp, the built-in handlers do not use that time to sort the written records. User-defined handlers are responsible for their own locking and sorting.

So three points fall out from this:

  1. The built-in logging handlers ensure it’s safe to log from multiple goroutines concurrently. You’ll never get a partial log from one interwoven with a log from another. This won’t happen:
2022/11/08 15:28:26 INFO hello 2022/11/08 15:28:27 INFO hello count=3count=3
  1. Timestamps are not used for sorting. So in theory, this could happen:
2022/11/08 15:28:28 INFO hello count=3
2022/11/08 15:28:27 INFO hello count=3
  1. If you’re implementing your own logger, these guarantees don’t apply, unless you implement them yourself.

Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Back after an unannounced absence

Hey everyone… I dropped the ball! A combination of unexpected family events, prepping for a conference, and some travel, meant I haven’t been writing for much longer than I like. But I’m back! So where were we? Oh that’s right… performance considerations with log/slog. We had looked at using the fmt.Stringer interface to avoid eager processing with slog.TextHandler. But let’s now look at a more general solution: Performance considerations …


Lazy attribute evaluation for JSONHandler

As I was writing yesterday’s post, a portion of the GoDoc confused me. I’ve now spent over 3 hours with Claude trying to parse the prose grammatically, build test cases, and make general sense of it. I think I finally have… Here’s hoping! So, yesterday we saw how you can lazy-evaluate some values when using TextHandler. But the proposed solution (pass a fmt.Stringer rather than a literal string) has other, likely uninintended, consequences if you’re using JSONHandler:


Attribute evaluation

log.With isn’t the only trick available for improving performance of logging. Many values you may want to pass to a logger need to be calculated. And sometimes that calculation is expensive. And if a log is omitted, because it’s a debug log, and our logger is only configured for info-and-up level, that calculation should be skipped. Performance considerations … The arguments to a log call are always evaluated, even if the log event is discarded.

Get daily content like this in your inbox!

Subscribe