Playing Beth Harmon...

Beth_Harmon_Playing_Chess.jpg

Like most people, I was captivated by the NetFlix series “The Queen’s Gambit” recently. I have fond memories of playing my dad as a kid, but I was never really a good player. Which is strange, because I have always heard that programmers usually make good chess players. But I was the exception to this particular rule (or maybe I am a bad programmer too? 🤔).

But a couple of years ago, I made the decision to try and improve my chess playing skill. To become more strategic and long term in my thinking. I subscribed to a paid plan on Chess.com and started watching several YouTube channels regularly to learn what the grand masters do.

Happily last week, I discovered that Chess.com has introduced the ‘Beth Harmon Bot’ to their list of computer players, so I can now play against (the totally fictitious character, by the way) Beth at the various stages of her storyline, from a young girl starting to learn the game with the janitor at her orphanage, to the 22 year old Grand Master slayer.

Beth Harmon 1.png

I like that the bot has the unique playing style that Beth demonstrates in the show. Playing very quietly at the start, then launching a devastating attack during the middle game. Take for instance, the Queen’s Gambit opening that the show is named after. Most of the other bots I play on Chess.com will usually accept the gambit, however the Beth Bot always exercises caution that early on and declines it in order to position her troops for the overwhelming attack to come.

I love the fact that some of that personality is built into the Bot. I can almost imagine I am looking into Beth’s doe like, yet penetrating eyes across the board. Every unexpected move make me feel a nervous twinge, exactly as I would when playing another human player.

So far, I am managing to beat 9 year old Beth regularly, but 10 year old Beth has me struggling sometimes (I have yet to beat her playing black), and 15 year old Beth simply hands me my ass with alarming regularity (by that I mean: Every. Single. Time).

Here is a game analysis against 9 year old Beth (click on the image to go to the full analysis). I was particularly proud of this game because while it wasn’t elegant, I did manage to restrict her usual broad development and entrap her King by sheer force of will.


I will try and do another update in a few months to see how my game has improved!

Making Google blink first...

Google-Graveyard-Halloween-2019-Hero.jpg

Some history - I wrote and launched the first version of my HR startup back in late 2015. Early going was slow, but promising. In early 2017, we enhanced our offering by adding on a recruitment and applicant tracking system to help our small, but dedicated customer base.

Then, our of seemingly nowhere, in July 2017, Google announced Google Hire, a recruitment and applicant tracking platform for small to medium businesses. I’ll be honest here, it was a bit of a gut punch. How could we, a small 2 person startup based in a country town in Northern Australia, compete with one of the biggest giants in the online world?

Colleagues, customers and friends would all regularly give me a sympathetic look and a figurative pat on the shoulder when they heard the news. “Oh, well, at least you tried…” was the unspoken words behind their eyes.

Yes, I did consider just throwing in the towel during that time, but I still had a spark within me that was fanned by those early customers and their positive feedback on what we were building, so I decided to ignore the ‘big G’ and persevere.

Then, in late 2019, Google suddenly announced that they were shutting down Google Hire. On 1st September this year, the service was turned off.

Ours is still running, and growing stronger every day. We have over 500+ job listings open on our public facing job boards today by over 1500+ customers, and we have processed nearly 40,000 applicants through our system. Still tiny by most standards, but we outlasted Google.

It’s not the size of the dog in the fight, but the size of the fight in the dog.

Remember the 'ground breakers'

In music

EVH.jpg

This week the world said goodbye to the legend who was Eddie Van Halen. I grew up with VH’s music, and Eddie’s guitar riffs feature prominently on the background canvas that was my youth. I clearly remember the first time I bought “Van Halen 1” and put it on my dad’s Yamaha turntable and listened to it. I was initially blown away by “Runnin’ with the Devil”, but then when “Eruption” came on, I reeled back. Initially with confusion and disgust. What was this weird way of playing guitar? What on earth was he doing? No one has ever used the whammy bar like THAT before!

Yep, I didn’t like it at first. But then, as I played that album over and over again, I began to love that particular 2 minutes of the album. Every time I heard it, I discovered something new. It was a multi layered, complex beast of a guitar arrangement. EVH soon became one of my top 5 guitar influences, though I never played a fraction as well as him.

Years later, my son (who was born 20 years after VH1 was released) and I were having a conversation about Eddie. I told my son that Eddie moved the goal posts. That he was an innovator that moved guitar playing to a whole new level in a similar way that Jimi Hendrix had done back in the 60’s. But initially, my son was confused, and said “But everybody plays like that now… How was Eddie different??”.

And that was the crux of the discussion. Everybody DOES play like that now, BECAUSE of Eddie. If he hadn’t had come along, the guitar playing landscape would be very different. Eddie revolutionised the whole game and pushed everyone to a new level.

In business

I see similar arguments in my working life too. I came across this tweet a few weeks ago (focus on the reply to this tweet here):

Bezos_Startup (Blurred).png

The fact is - Bezos DID do something ground breaking. Other people DID have the same idea, but couldn’t make it run.

I was trying to start an ecommerce business here in Australia at about the same time Bezos was getting Amazon off the ground. And it was hard. NOT just because of (lack of) money, but because there was absolutely no infrastructure around to do it. There was no Shopify to start a turnkey store. There was no Stripe to process credit card payments.

In fact, processing customer credit cards was a massively expensive consideration, and required merchant accounts with certain banks and exorbitant fees. There were no APIs or hosting providers that you could spool up a server quickly and get a store online in just a few hours.

I am not a Bezos fan boy by any stretch of the imagination, but he changed all that. We see the offshoots of his efforts today. In fact, my latest startup is hosted on Amazon’s AWS platform, which is a byproduct of all his learnings and efforts in setting up the Amazon online store in the first place.

The point is - everyone CAN set up a store really easily today because Bezos ‘broke the ground’ in the early days. Everyone can do two handed tapping on the electric guitar and dive bomb whole octaves because Eddie showed us it could be done (and it could be acceptable in modern music) in the early days.

Salute to these early revolutionaries. Thank you for breaking the ground for the rest of us.

Making my code run 3000 times faster!

Photo by Abed Ismail on Unsplash

Photo by Abed Ismail on Unsplash

I first started using the MySQL database system way back when version 2 was released. I cut my teeth on writing SQL queries using that system, even when it still didn’t have nested SELECTs, which entailed me really getting to grips with hand optimised JOIN commands.

But over the years, as better tools and layers of abstraction evolved, I began to touch the raw SQL less and lees, and began to rely on these other tools to do the heavy lifting for me.

My latest startup uses the newest, shiniest version of MySQL to store data, but I am several steps removed from the data store via a Ruby ORM (Object Relational Mapping). Basically, I just define all the database elements as standard Ruby objects, and the system just takes care of everything for me.

It works well 98% of the time, but sometimes there is a problem, like the one I will describe below.

Plenty of space, really! 😅

Plenty of space, really! 😅

In my SaaS app, we allow our users to store document attachments against their employees. We have a handy little widget in the footer of every screen to show our users just how much of their allotted storage they are presently using.

Now, this widget used to do a quick calculation upon every page load. Initially it worked well, with only a few extra milliseconds being added to page load time, but as our system grew, and we allowed attachments in different areas (i.e. Company Library, Job Applicants, e-Signatures, Expense Claim receipts etc.), we started to find that this page load time was actually being increased to over a second - sometimes even a couple of seconds per view, which really impacts the overall snappy feel of the app.

What started as this…

What started as this…

Quickly became this…

Quickly became this…

How would we solve this? Well, we decided to transition from a live, real time calculation, to running a process every couple of hours (in the background) that would go through the file attachment tables and tally up the total storage amount and store that in a database field somewhere. The screen rendering process would then just present the value of that database field on the screen each time.

So we would lose the real time aspect, but customers would still see their storage allocations up to only a couple of hours of lag time. Best thing was that page loads were back up to nearly instantaneous again.

We built a utility routine that runs on our background worker server to run these calculations every 4 hours (on a CRON timer). But the problem was, the routine would have to run through our entire active customer list of 1700+ companies, and tally up all the attachments across the different files in different areas, and store it in the company masterfile. That routine would take up to 45 minutes to run! AND it was also spiking the CPU of the worker server so that other critical background tasks (like calculating leave, handling Slack notifications and important emails) was being impacted and delayed.

We tried several things like spawning several concurrent Threads to run part of the task in, but still no joy. I kept getting critical alerts in the middle of the night that our worker instances were down or struggling with the load. Clearly not acceptable.

This was a frustrating issue, and the team, including myself, were struggling to solve it. But then it dawned on me. We were getting lazy. Our immediate ‘go to’ solution was to stick with Ruby and the ORM and our background worker to solve a background task. What if there was another way?

Looking at the problem, there were no real external inputs required. The task was simply to step through the customer database row by row, then find the associated records (which was easy, because we have keys linking them all), and run a SUM query and then total up all those SUMs and save it in the main company database.

Why weren’t we just doing this in SQL directly? But also, MySQL now has the concept of ‘Scheduled Events’, where you can store regular housekeeping routines right within the database that can to routine queries on a fixed interval. No need to set up a timer on our worker server at all.

So I opened up a MySQL query console, and typed up a query that would do the totalling of all the attachment records and perform an UPDATE on the company row.

Nested selects…. nested selects everywhere!

Nested selects…. nested selects everywhere!

I ran the query.

It took…. 0.8 seconds!

Let me say that again - it took LESS than a second to run. Compared the worker thread we used to do the EXACT SAME thing that took 45 minutes+. That is about 1/3000th the time.

Best of all, it completely takes the load off our worker server. I think the database CPU spiked about 2% for that 1 second timeframe. This meant that instead of running every 4 hours, we could schedule the task to run every hour. Heck, we could even run it every 5 minutes if we wanted to, but I don’t want to get that crazy unless customers really demand it.

It was a valuable lesson to me that complacency and laziness can really be a detriment in a growing business. When you have a hammer, everything looks like a nail, and we were so wrapped up in the comfy perceived safety and convenience of our Ruby ORM that it hadn’t really occurred to us that we could take the covers off and get down to the nuts and bolts to solve the issue in the first place.

Next time there is a problem like this in my startup, I will go back several decades in my working life again, and see if I can roll up my sleeves and fix it the ‘good old fashioned way’.