
Software Engineer @VictoriaMetrics, building VictoriaLogs
Joined August 2014
- Tweets1.1K
- Following124
- Followers8.5K
- Likes5.9K
Phuong Le retweeted
Excellent animations AND tech content!
#golang
Escape analysis in Go: stack or heap? youtube.com/watch?v=BanG_wLn…
Tbh, every second is worth it, even if you don't know Go. I wish someone had taught me this when I was learning Go.
Phuong Le retweeted
Logchef gets a mention!
If you’re looking for a really good log explore tool paired with #VictoriaLogs, def check it out!
Phuong Le retweeted
In 2017, I started learning Go, mostly from curiosity. After working some years for Mattermost, I learnt enough to start sharing that knowledge with the community. Today I’m honored to share that I’ve been recognized as a @GoogleDevExpert in Go.
This wouldn’t have happened without a lot of people involved in my own process, from the extremely welcoming Go community, to my companies, @kaleidosnet, @Mattermost, @ona_hq, and now @VictoriaMetrics, that has been always supportive and helping me to contribute back to the community.
The GDE program is about sharing knowledge, so, there is not going to change much from my side, except that I'll have even more support to keep sharing with you what I learn in Go.
#golang #GoogleDeveloperExpert #GDE #Go
VictoriaMetrics now has a new account just for the technical side. If you're interested in database techniques, observability, and products explained visually, give it a follow:
Phuong Le retweeted
Very good visualisation on how stack and heap memory works in Go
Escape analysis in Go: stack or heap? youtube.com/watch?v=BanG_wLn…
Tbh, every second is worth it, even if you don't know Go. I wish someone had taught me this when I was learning Go.
Phuong Le retweeted
My article about SIMD and Go is out!
In this one I explain how one CPU instruction can work on 8 numbers at once, and how you can now use that from plain Go with the experimental simd/archsimd and simd packages.
My intention with this post is to explain in simple terms how SIMD works at CPU level, to give you the mental model on how to use it, and then give you enough information about how you use it from Go to start working with it.
You can read it here: internals-for-interns.com/po…
#Go #SIMD
Phuong Le retweeted
If you aren't familiar with VictoriaLogs data model yet, then this clear video explainer from @func25 is for you!
youtube.com/watch?v=ZM6rUTJz…
Phuong Le retweeted
VictoriaLogs is a log database that accepts logs in many formats without a schema.
If you are new to VictoriaLogs, start here: youtube.com/watch?v=ZM6rUTJz…
Logs from many protocols all become the same internal format in VictoriaLogs. Message, time, fields and stream fields.
Phuong Le retweeted
Please welcome to my blog Kemal Akkoyun, who works at Datadog and helps maintain otelc, OpenTelemetry's compile-time instrumentation tool for Go. Today he shows how to take part in a Go build without patching the compiler.
The way in is `go build -toolexec`. Every compile, asm and link run goes through a program you pick, which gets the tool's path and arguments. From there, Kemal builds up step by step, first watching, then rewriting, and going down all the rabbit hole until he end up explaining how otelc does it.
Read it here: internals-for-interns.com/po…
#Golang #OpenTelemetry
Phuong Le retweeted
I want to share something that the @VictoriaMetrics team faced recently that I think it is an interesting case. I'm communicating it, but the heavy lifting of this was done by other members of the team.
The Go race detector found a race condition within the http client that catch us by surprise, so the team dig into it, and found two interesting things. If found this race in two places, one of the races, in our case, was not a problem, it could be, but not in our case, so we didn't fixed, but the second one actually was a bug, so we fixed it. If you want to know the details and understand what was happening, why not fixing it was the right choice for us, and why fixing the second one was needed, check out the blog post.
victoriametrics.com/blog/htt…
Phuong Le retweeted
#VictoriaTraces now comes with a new built-in UI!
🚀 VictoriaTraces v0.12.0 is here!
This release introduces a new built-in UI for exploring #traces. Find a trace, drill into its spans, and see what’s slowing down your application.
VictoriaTraces is #OpenSource, so you can try it out yourself in the playground:
play-vtraces.victoriametrics…
🔎 Check out the changelog for the full list of updates, including:
🔐 Security
✨ Features
🐛 Bug fixes
docs.victoriametrics.com/vic…
#Observability #VictoriaMetrics
Phuong Le retweeted
This is my last article in my series about Kronk. In this one, I'm talking about the API, but more specifically about the streaming API and how it works and handle errors.
This one end up being a shortest in the series, but I hope you enjoy it the same.
Read it here: internals-for-interns.com/po…
#Go
Phuong Le retweeted
Just in case you are interested about how read ahead works in linux, I wrote this post: victoriametrics.com/blog/lin…
In @VictoriaMetrics we really care about performance, so understanding how Linux is trying to help is important. But also It is important to help it to help us. 🙂
Some people think we can't learn software design with Go as it has no classes, no inheritance, no method overloading, etc
But software design is about how we organize code, manage dependencies, and keep a change in one part from breaking another.
E.g., encapsulation, it means controlling how other code can read or change our data.
- In Java, we can use classes and private fields.
- In Go, we can use packages and unexported names.
Of course, they don't work the same way, but both let us choose what other code can access and what we want to keep inside our package or class.
Polymorphism means the code can work with different implementations through an interface. Both Java and Go have interfaces but types in Go don't need a shared parent class, if they have the required methods, they satisfy the interface.
DI or dependency injection is when we give a component what it needs instead of making it create that dependency itself.
Like we can pass a database connection to a service when we create it. If the service accepts an interface, a test can pass a test implementation and we can do this with function parameters, I guess most of us have probably done it without knowing it was called dependency injection.
Memory management is a separate (but interesting) topic.
Go and Java use garbage collection, so we do not need to free heap objects ourselves. But we still need to understand how much memory our code uses, what happens when code shares data, and how keeping a reference to an object can stop the garbage collector from freeing it.
Knowing syntax means we know how to write valid code. But more important is understanding the concept. I mean can we explain what practical problem it solves and when to use it? If we can solve the same problem in 2 different ways, which one is better and why?
Actually starting with a complex, feature-rich language can be a good choice. Experience can't be taught, sometimes we need to spend time with that complexity before we can appreciate how simple the next language can be.
I just found an interesting Go repository: github.com/nikolaydubina/go-…
If you are learning Go, spend some time here after the syntax tutorials. Learning how to check test coverage, compare benchmark results, and find bugs is also part of learning how to use Go.
You can choose the wrong backend if you only look at which one is faster in a benchmark, even when the results are accurate. The backend that is faster in the test may not be faster for your application.
HTTP server performance depends on the complete request path
- Routing,
- middleware,
- logging,
- serialization,
- external calls
These all add work and 2 handlers can return the same responses but performing different things before sending them.
Concurrency describes how much work is in progress at once.
Increasing concurrent connections can increase throughput (e.g., how many requests finish per unit of time) while our server has limited capacity. But after a resource becomes saturated (reaches its capacity), additional concurrency can increase waiting time without increasing completed requests.
A database pool with 100 connections does not mean your API can only handle 100 requests/sec. Each connection can be reused as soon as a request finishes using it.
- If database queries finish quickly, the same connections can serve many requests in 1 second.
- If queries take longer, connections stay busy longer, and new requests may have to wait for one to become available.
Latency and errors give us information that throughput alone cannot.
- Average latency can hide slow responses.
- The p99 latency describes the point at or below which 99% of measured request latencies fall.
- p100 is the maximum measured latency, the slowest request in your sample and gives us a very sensitive signal, since even a single unusually slow request can noticeably change p100. See xitter.cf/valyala/status/2091799…
But none of these three tells you how many failed requests or timeouts you had.
Memory usage can mean different things depending on what you are looking at. A high memory number does not always mean an application is wasting RAM
- Live heap memory covers objects still considered reachable by the garbage collector.
- Virtual memory includes address space the process has reserved or mapped. Some of that space may not use physical RAM at all. So seeing 4 GB of virtual memory does not mean the application is using 4 GB of RAM.
- RSS shows memory currently in RAM. Some of it can be file-backed memory and is reclaimable, meaning the OS can free that RAM when needed and load the data again if the application uses it later.
When the garbage collector reclaims objects, the runtime can keep that memory for reuse, so the memory usage reported by the OS may not drop immediately.
So a high memory number alone does not prove waste or tell you how close the application is to OOM. It's better to always check which number you are reading, how much memory is reclaimable, and how usage changes as the application gets closer to its memory limit.
If one implementation is faster in your test, that does not mean it will be faster when the workload or setup changes.
Indeed, monitoring of the maximum metric value (aka p100) is better than monitoring p99 or other percentiles:
- it shows the exact maximum without any approximations and errors;
- it is very easy and fast to calculate the maximum value among many maximum values obtained from different monitoring targets - just get the maximum of maximums - this works fast even if you have hundreds of thousands of monitoring targets;
- it reflects the worst case of the monitored system - if you optimise the system for the worst case, it works great in the average case and at any percentile;
- it is very easy to calculate p100 in Prometheus-compatible exporters via standard summary metric ( docs.victoriametrics.com/vic… ).
Phuong Le retweeted
We just published a PostgreSQL 19 Interactive Tour. If you want to know what is comming in the new version of Postgres and want to play with it and see it in action, check it out here: victoriametrics.com/blog/pos…
Phuong Le retweeted
MongoDB is one of the numerous happy users of VictoriaMetrics products!
victoriametrics.com/case-stu…











