Tuan Anh

container nerd. k8s || GTFO

Brag document

There’s this idea that, if you do great work at your job, people will (or should!) automatically recognize that work and reward you for it with promotions / increased pay. In practice, it’s often more complicated than that – some kinds of important work are more visible/memorable than others. It’s frustrating to have done something really important and later realize that you didn’t get rewarded for it just because the people making the decision didn’t understand or remember what you did. So I want to talk about a tactic that I and lots of people I work with have used!

I’ve been doing this for years and it really works. Highly recommend you give this post a read.

link bài gốc

Debugging with git bisect

Suppose I have this project with 5 commits. You can clone it from here.

git bisect

Say, there’s a regression bug in the master branch but a lot has been added to master after the feature was first inroduced. How would I go debugging this? Which commits break it?

Usually, we would go manually and see which commit would possibly do this but if the project is large and active, it’s a quite troulesome process.

Luckily, we have git bisect for that.

  • Go to the project and issue git bisect start
  • Mark the bad commit by git bisect bad <commit-id>. You can ommit the commit id if you’re already on it.
  • Mark the good commit by git bisect good <commit-id>.
  • Add the tests for the regression bug. In this case it’s add() function.

I’m gonna go ahead and add a fail test case for the regression bug I’m having. You may argue why not add test in the first place? Well, this is just an example so I have 0 test for it.

In actual scenario, you can have an extensive test cases but still can miss an edge case. In that scenario, you will need to add that fail test for that edge case here.

// test.js
const assert = require('assert')
const add = require('./add')

assert(add(1,2) === 3, 'one plus two should equal to three')
  • Do git bisect run <test-command>. In this case, it would be git bisect run node test.js.

  • Do git bisect log and see the result. It would look like this.

# bad: [addb180af061bbfbad298cd6a9ad2110df0f873e] feat: add multiply
git bisect bad addb180af061bbfbad298cd6a9ad2110df0f873e
# good: [7688391b1a9b133bef92198e376c9f5979260ade] feat: add add() function
git bisect good 7688391b1a9b133bef92198e376c9f5979260ade
# bad: [d504f94f1d71c93deb9d9bbdf87bfe333bbecff6] chore: add readme
git bisect bad d504f94f1d71c93deb9d9bbdf87bfe333bbecff6
# bad: [d516aaf29331953382a8558f013b683427d7a390] feat: add subtract() function
git bisect bad d516aaf29331953382a8558f013b683427d7a390
# first bad commit: [d516aaf29331953382a8558f013b683427d7a390] feat: add subtract() function

There you can see which first commit makes the test fail is [d516aaf29331953382a8558f013b683427d7a390] feat: add subtract() function.

  • Do git bisect reset when you’re done.

Happy coding!

The state of tiling window manager on Windows 10

The state

1. Workspacer

  • Opensource.
  • Best in term of feature set.
  • Closest thing to an actual tiling window manager on Windows 10.
  • Have some weird bugs that’s quite annoying.
  • Development velocity is slow.

2. Bug.n

  • Opensource.
  • Written in scripting language - AutoHotkey. Require AutoHotkey installed.

3. PowerToys

  • Opensourced by Microsoft.
  • Not really tiling. It’s still manual process.
  • Very stable for daily use.
  • Not really focusing on window management, it’s just one of the features.
  • Development velocity is very fast.


I settled on PowerToys for now but keeping an eye on workspacer. I love workspacer’s feature set. It actually has everything I need but lacking stability.

A beginner guide to CPU air cooling

I was researching about CPU air coolers for the best CPU air cooler and I learnt a lot of stuff. Thought this might be useful to some of you. Most of the stuff below are copy and pasted from various sources. This serves as a basic guide for absolute beginners like me when it comes to CPU air cooling.

TL;DR: Noctua NH-D15 is the best air CPU cooler out there.

Reading fan specs

CFM, m³/h, RPM, dB/A and mm H20

Every fan features a cubic feet per minute (CFM) rating, which measures of the volume of air it moves in a minute. The greater the CFM, the more air a fan moves. To properly air cool your computer, you need have enough case fans to push or pull air into and out of the case. More case fans means higher total CFM and more air being moved through your computer.

Some manufacturers use m³/h as unit. One m³/h is ~0.589 CFM and one CFM is ~1.699 m³/h. You can use website like ConvertUnits.com to convert them.

The airflow is always moving from the front to the back of the fan

Other specs like RPM (rounds per minute) and dB/A which is the noise level are kind of self-explained. Higher RPM is cooler but also noisier. Lower dB/A is better.

You may also notice mm H2O which stands for millimeters of water - which is measurement of “static pressure” - the amount of negative pressure it takes to makee a fan come to a complete stop at xxx RPM. As you can see, it’s highly dependent on RPM speed.

Fan connector pins

A three pin connector is basically power (5/12 volt), ground, and signal. The signal wire measures how fast the fan is moving without any controls for the fan’s speed. With this type, fan speed is typically controlled by increasing or decreasing the voltage over the power wire.

A four pin connector is a little different than the three pin connector since it has the extra (fourth) wire used for controlling and sending signals to the fan, which likely has a chip on it that tells it to slow down or speed up (in addition to the other wires the three pin connector has). You probably don’t need to know more than that.

Positive / Neutral / Negative air pressure

Explained by Linus Tech Tips

Or you can just take a look at thousand words below:

Positive pressure looks like this

Neutral pressure looks like this

Negative pressure looks like this

Selecting a CPU air cooler

Once you found an air cooler that you like, make sure it can be fit inside your case. Read your case specs and find CPU cooler clearance.

To be sure, you can also go to site like PCPartPicker and find complete builds features the case and cooler you intend to use.


Advanced filtering and sorting with redis (part 2)

With the recent introduction of Redis modules (since Redis v4), redis is now a lot more flexible than the old redis.

Previously in part 1, if you want to mimic the sorting and filtering behavior, you need to use set/sorted set and do the intersection/union by yourself.

Not anymore.

Meet RediSQL

RediSQL is an in-memory SQL engine, built on top of Redis as Redis module.

It’s pretty much SQL under the hood now. No more smart trick to mimic the behavior.

The downside is there ain’t many redis client that support browsing data for these modules, aside from the newly released RedisInsight, which currently only support RedisGraph, RediSearch and RedisTimeSeries. This makes debugging is really troublesome. This is a big show stopper for me. Just something for you to keep in mind.


RedisGraph is a graph database module for Redis. It’s specificly built for graph database but can be utilized for doing filtering as well, because it’s a graph database. It’s kinda using the wrong tool for the purpose. RedisGraph is a lot more powerful than just doing filtering and sorting.

Example of doing filtering in RedisGraph

Loading data

GRAPH.QUERY TestGraph "CREATE (:Property {id: '1', name: 'hotel 1'})-[:hasFacility]->(:Facility {id: '1', name: 'Swimming pool'})"
GRAPH.QUERY TestGraph "CREATE (:Property {id: '1', name: 'hotel 1'})-[:inCity]->(:City {id: '1', name: 'Hanoi'})"
GRAPH.QUERY TestGraph "CREATE (:Property {id: '1', name: 'hotel 1'})-[:hasStarRating]->(:Rating {id: '4', name: '4 star'})"

GRAPH.QUERY TestGraph "CREATE (:Property {id: '2', name: 'hotel 2'})-[:hasFacility]->(:Facility {id: '2', name: 'Spa'})"
GRAPH.QUERY TestGraph "CREATE (:Property {id: '2', name: 'hotel 2'})-[:inCity]->(:City {id: '1', name: 'Hanoi'})"
GRAPH.QUERY TestGraph "CREATE (:Property {id: '2', name: 'hotel 2'})-[:hasStarRating]->(:Rating {id: '3', name: '3 star'})"

Filter all 3 star hotels in Hanoi

GRAPH.QUERY TestGraph "MATCH (h:Property)-[:inCity]->(c:City) WHERE c.name = 'Hanoi' and r.name='3 star' RETURN h.id, h.name"


I’ve heard a lot of praise about Pi-hole project but hadn’t gotten around actually trying it yet until recently.

Pi-hole is a network-wide ad-blocking solution via local DNS. You set it up as a local DNS server and it will block all the ads that match the rule from DNS level. This way, you don’t have to setup adblock on each and every devices you have, especially tablets and mobiles. See example of VnExpress without adblock below.

vnexpress without adblock

People usually use Pi-hole with a low powered device like Raspberry Pi (hence the name Pi-hole) but in my case, I already have an Intel NUC lying around as Plex server (running Windows 10). I could just use it instead of setting up sth new.

The easiest way to install Pi-hole is to use Docker. The process is as easy as

  • Install Docker for Desktop.
  • Create a few folders for pihole config. Let’s do it in Documents folder and mount it to container. If you change it to something else, make sure to update the following commands. Create the 3 folders with the folowing structure.
├── dnsmasq.d/
├── pihole/
  • Download and run pihole Docker container with the following command
docker run -d --name pihole \
    -p 53:53/tcp \
    -p 53:53/udp \
    -p 80:80 \
    -p 443:443 \
    -v "/c/Users/<USESRNAME>/Documents/pi-hole-config/pihole/:/etc/pihole/" \
    -v "/c/Users/<USESRNAME>/Documents/pi-hole-config/dnsmasq.d/:/etc/dnsmasq.d/" \
    -e ServerIP="<YOUR_HOST_IP>" \
    --dns= \
    --dns= \
    --restart=unless-stopped pihole/pihole:latest
  • I need to disable Windows Firewall for local network which I think it’s safe to do at home in order to access the container from other machine.

And that’s it. Now you can head over to HOST_IP/admin to login and configure Pi-hole. Once it’s done, you can config your router to use the HOST_IP as the default DNS server, and maybe Cloudflare or Google’s DNS as backup. Ah, and make sure to set static IP for your Pi-hole host machine so you don’t have to update router’s setting if the IP changes.

pihole admin

Keep in mind that Pihole is not a complete replacement for browser extension like uBlock origin. You probably still needs that because DNS-based adblocking functionality is quite limited (eg: sites that serve ads on the same domain as content). It’s mostly useful for mobile browser where adblocking is almost non-existent or not good enough.

Microsoft Sculpt Ergonomic Desktop review

While i’m a hardcore mechanical keyboard fan, this is my very fisrt split (partially), ergonomic keyboard.

The keyboard comes in tenkeyless size and a separated numpad. It’s a bit bigger for my taste but I can live with that. I’m more accustomed to a smaller board. 60%-65% is usually the sweet spot for me.

The sculpt keyboard uses wireless but probably not Bluetooth which makes me wonder if I can find the replacement USB receiver dongle if I ever lost it.

The keyboard

Decent looks. Not like Apple-good looking but quite good. It’s also look nicer in picture than in real life so keep that in mind

Pretty standard layout with non-standard key size, with several keys of unusual size. This kind of split keyboard will help you realize if you’re touch typing wrong. For example, i sometimes type Y with the left index finger. While its possible to do that on a normal keyboard, it’s not do-able on split keyboard in general because it’s now too far from the left index finger. I think of this as a good thing.

I also suffer a short period of inaccuracy with the B key, although the size is same with other keys, it feels like the hit box is much smaller. Same thing with the Enter key.

I’m also not a big fan of the ESC key and the whole Fn row. They’re small and quite wobble.

Coming from a big fan of mechanical keyboard, scissor switch is kind of meh. It’s better than a typical laptop keyboard but so much worse than a mechanical keyboard. The typing feeling can only be as good as scissor goes.

Media keys are nice. They work out of the box with apps like Spotify. There’s a button at the top right corner to switch back and forth between Fn function keys and media keys.

The biggest downside of this keyboard is that remapping keys (via firmware) is not possible.

One of the thing I would like to do is to map the left spacebar to backspace. It’s possible with the Sculpt Comfort but not possible with Sculpt Ergonomic. You can only blame Microsoft for this. The issue has been there for a few years so I dont think they have any plan to fix this.

From the documentation on Microsoft website, it seems remapping is a supported feature but it’s super misleading. There are only 9 keys that can be customized and the available mapping options are quite limited.

You may think the Caplocks can be customized from the above picture? Wrong. You can only turn it on or off and that’s it.

Good thing is you can still do it via software. There are apps like AutoHotkey where you can program it like how you like. But you will have to set it up again if you use the keyboard on another machine.

Personally, I find TouchCursor good enough for my needs. The software mostly focuses on SpaceFn layout but you can config it to use any key as the Fn key.

Also, you don’t need Microsoft Mouse and Keyboard Center software. It’s garbage.

The mouse

Let’s talk about the mouse. It’s goofy and make you feel kind of strange to hold it at first. It feels like you’re holding a ball. Overall, it’s a lot more comfortable than the coventional mouse with office work but I wouldn’t use it for gaming though.

The mouse back button requires a bit of force which I think they can improve in newer version. Also, lowering the button a little bit would be nice.


Even though I own lots of mechanical keyboards but I don’t use them as often as this keyboard. This thing is slowly becoming my personal favorite.

I would def. recommend if you don’t need the some serious remapping feature (Check TouchCursor out to see if it’s working well enough for you) or play games a lot.

Optimal team size

Recently, I saw this tweet on Twitter. This is regarding the challenge of adding more engineers to a project in relation to the number of communication lines.

This is easy to notice adding 1 more engineer to the team will increase no. of communication lines quite a bit because the function to calculate no. of communications lines in regard to no. of engineers is

<?xml version=”1.0” encoding=”UTF-8” standalone=”no” ?>

O(n*n), no wonder why it’s steep. More on that later.

Amdahl’s law

This tweet immediately reminds me of Amdahl’s law.

Let’s talk broader, instead of discussing about number of communication lines, how about we try to optimize the team throughput in relation to the number of engineers on the team.

The most common misunderstanding in project management is how the project time is inversely proportional to the number of the team as you often hear this joke

A project manager is someone who thinks that 9 pregnant woman can create a baby in 1 month.

<?xml version=”1.0” encoding=”UTF-8” standalone=”no” ?>

This assumes everything on the project can be done parallel. Everyone’s work is independent. This assumption is almost never true in real world project management.

So, how can we refine the above function to better reflect the real world situation. The first thing that pops in my mind is the Amdahl’s law.

Amdahl’s law is often used in parallel computing to predict the theoretical speedup when using multiple processors. For example, if a program needs 20 hours using a single processor core, and a particular part of the program which takes one hour to execute cannot be parallelized, while the remaining 19 hours (p = 0.95) of execution time can be parallelized, then regardless of how many processors are devoted to a parallelized execution of this program, the minimum execution time cannot be less than that critical one hour. Hence, the theoretical speedup is limited to at most 20 times:

<?xml version=”1.0” encoding=”UTF-8” standalone=”no” ?>

Sounds like we can use this to further refine our function above. But first, this is Amdahl’s law:

<?xml version=”1.0” encoding=”UTF-8” standalone=”no” ?>

Let’s call p is propotion of work that can be parallel with p=0 means nothing can be done parallelly and p=1 means everything can be done paralelly.

<?xml version=”1.0” encoding=”UTF-8” standalone=”no” ?>

When p=0 (nothing can be done in parallel), we got the time = work. When p=1, time = work / n as before

Communication overhead

Now, let’s try to add communication overhead to the formula. Assuming commication cost is proportional to no. of communication lines with each of them takes a fixed cost in time, says k (assuming k is a small positive number).

<?xml version=”1.0” encoding=”UTF-8” standalone=”no” ?>

Of course, in reality, communication doesn’t look like that. Maybe more like org chart. Or it could be group meeting to exchange information instead of pair-wise. This is just to say, when you want to optimize your team’s throughput, you may want to check for communication method. It’s certainly a big factor.

But for the time being, let’s just go with this.

Our function will now become

<?xml version=”1.0” encoding=”UTF-8” standalone=”no” ?>


So we can see that at first, adding engineers to a project will speed it up but if go beyond a certain optimal size, adding more engineers to a project will just make it slower.

I don’t think the above function can reflect the project estimation well enough. But I know for sure, up to a certain number, adding more people will slow the project down. Maybe it’s more related to Parkinson’s law because “work expands so as to fill the time available for its completion”.

The question remains: what’s the optimal team size? Do you think it will make a big difference? Yes or no, lemme know.

From macOS to Windows 10

I’m an Apple fan no doubt but recently, I’ve been using Windows 10 exclusively at work and to be honest, I’ve grown to quite fond of Windows 10. For the first time since 2008, I’m seriously thinking about buying a Windows laptop.

With the recent introduction of Ryzen 3000 series, I was so tempted to build a PC again for the first time since 2006 (my last build was 13 years ago!!!) and install Windows 10 on it. Everything has been amazing experience since the switch. I don’t have any regret at all.

Lots of cool productivity apps

Everything (voidtools) - FREE

Amazing Spotlight replacement. I don’t even understand how can it be that fast. Just pure magic!

Ditto - FREE

For clipboard management, Windows 10 has built-in feature as well but it’s quite limited in term of feature set. Ditto is a free replacement that does the job very well.

You can set max items in history, how long you want Ditto to keep the history. Type of things you want to keep in clipboard. Changing global hotkey, etc…

Accessing clipboard history is just one shortcut away (I use Ctrl+Shift+V).

ditto windows

ShareX - FREE

Very good screenshot annotation app. I use Monosnap on macOS but ShareX is a hell lot better. I prefer Monosnap UI a bit more but ShareX trumps Monosnap in term of features.

Monosnap’s upload destination is quite limited and the app is not free.

With ShareX, I can simply press Ctrl+Shift+3, draw the screenshot rectangle, add some annotations and click upload (Imgur). Just like what I’m used to on macOS.

Microsoft Terminal

Open-source terminal application from Microsoft. It’s already quite good in preview build but what’s more is the app development velocity is insane. You can see for yourself on GitHub.

Very nice development experience

macOS is a Unix-like operating system, which make it very developer-friendly. You get the nice GUI apps from macOS and you get the best of all the CLI tools from Linux.

Now, all that stuff do-able on Windows 10 as well with the introduction of Windows SubSystem Linux (WSL).

With WSL, developers get the best of all worlds.

  • You can use all the latest drivers for your hardware (Because Windows support is still first class)
  • You get to use Microsoft Office - which still is the best office suite out there.
  • You get to develop just like you’re on an Unix machine (VSCode integration with WSL is also very good)
  • You can play games without rebooting into Windows.
  • etc…

microsoft terminal preview


I still use macOS occasionally but I’m ok with the idea of moving to Windows entirely. I’ve yet to find anything that I miss from macOS.

Tips on reducing WASM file size with Emscripten

Optimize for size over performance

If size is more important than performance, you can use -Os flag.

I tried with camaro and the file size reduce from 176KB down to 130KB. It’s worth a try.

Disable assertion, debug

Try adding these flags: -s ASSERTIONS=0 and -DNDEBUG to emcc.

Using emmaloc

Try using emmalloc which is a smaller malloc version available in emcc by adding -s 'MALLOC="emmalloc"' flag


Using --closure 1 flag may also help as well.

Remove unnecessary dependencies

Try not to import unnecessary libs in C++. Eg: don’t forget to remove iostream if you only use it for debugging with std::cout

Emscripten has a whole section about this, do read this to stay up to date.