How do you hire a good remote tech freelancer?

Julian Harris
Knowcast
Published in
6 min readJun 21, 2023

I share my experience hiring tech freelancers with Knowcast, with a few tricks I stand by today.

Hiring software people is hard. If you’re a software developer yourself and you want to augment your capacity, it’s still really hard, because hiring itself is a specific set of skills and not part of any software development course I know of.

If you’re technical and want to hire others, here are two insights that I stand by today:

  1. Collaboration skills matter: get collaborating directly with the person in real time as soon as possible. For example, I did pair programming with some candidates. Others I hired for a couple of weeks initially to see how they worked.
  2. Find great talent by create super-targeted gigs with very specific technical problems that you can have meaningful conversations about. For example I created a job for modeling a one-to-many relationship using AWS DynamoDB.

Collaboration skills matter: get collaborating directly asap

There’s a saying “all plans fail on first contact with the enemy”. I think there’s something similar to say when hiring. What do you think?

“all recruitment planning fails on first contact with actual work”

This is deliberately provocative to underscore that you really can’t get a sense of someone’s true capability until you’ve worked with them.

The big challenge of assessing coding skills

There is an entire industry of platforms that will test someone’s ability to code.

The surprising power of “I’ll pay for 90 minutes of your time”

There are a lot of people in freelancing communities like UpWork that believe “fake it until you make it” is an effective strategy. And it might well be. But it seemed many were not prepared for the technical scrutiny I was applying. For example, I was hiring a Flutter developer for my POC.

  • Five candidates agreed to join a pair programming session with me: coding together building on some Flutter code I’d been working on.
  • Of those, only two turned up! The other three, I assume, decided it was not worth being paid for, or possibly they’d be found out. Either way, that’s an effective filter in action.
  • Of remaining two, one was terminated within 5 minutes! This was shocking again.

Here’s an anecdote from one of the live coding sessions where we shared a screen and started navigating some Flutter code. To underscore, I was very clear:

  • You’ll be paid for this time as a freelancer.
  • This is a test focusing firstly on collaboration skills and secondly on relevant coding skills

Me: ok so what would you do here? (gesturing to the code, after briefing them on the problem)

Candidate: er…

Me: do you have any questions? Remember we’re working on this together so it’s ok to ask questions and make mistakes

Candidate: waves mouse vaguely… well I’ve only been doing Flutter for a few weeks

Me: so, not the 2 years you listed in your profile?

Candidate: no

Me: ok. I hope you can understand that at this point I need to terminate the interview as you’ve been dishonest with the skillset you purported to have.

Me: terminates session

Then I broke my golden rule! 🤦‍♂️

The 5th candidate was a disaster in another way. Here’s roughly how it went:

Me: ok great let’s get working on this code then

Candidate: sure so what I wanted to do instead was show you some code I’ve written that’s similar. Prepares to dazzle me with lots of plausible-looking Flutter code.

Me: ok great everything you say makes sense, you’re hired!

The hire was a disaster. What did I learn? Stick to my guns.

I should’ve trusted my process. I should’ve said “that’s all well and good but let’s stick to the agreed process and use this time together to write some code”.

Because:

  • I had no idea if he wrote that code he showed me
  • I had no idea how he wrote it and against what spec

When the contract started the code produced was terrible, the freelancer was continuously late to 1:1 syncs (eg 20 minutes late for a 30 minute sync, with no apology), and when I provided feedback the code written in response suggested they didn’t really have that much experience, certainly not to the quality of the code as I remember it in the interview.

Caveats

Here are just a few.

  • Not every candidate will be ok to spend the collaboration time with you, even if you offer to pay. That’s ok; that in itself is a filter in my book.
  • Sometimes it’s not practical for security or IP reasons to share code.

Create very (very) targeted gigs initially

Headlines:

  • It filters well: anyone wanting to fake it will likely skip the job because it’s clear they’ll be found out immediately. Only people with the seniority I want
  • You’ll attract people who are particularly interested in that technology rather more general jobs like “AWS architecture stuff”
  • You don’t even need to use the result: it’s a short project, maybe a POC (in this case below we didn’t use this result).

This insight was actually an accident. I was looking for a way to augment my own skills and thought I could contain it to a specific, well-defined piece.

I created the gig, and the quality of conversations was very different because I’d taken the time to be very specific about what I needed. I attracted people who had solid working knowledge of that area and are enthusiastic about it.

Rather than the commonplace UpWork response like “Hello Dear, I have read your project requirements very carefully and I can do all the things” I had meaningful conversations about the specific set of technologies I was using and why I should use one approach over another. I found a great guy, Andre, and it became immediately apparent that he was very able to provide other services too. I went on to work with Andre for 18 months.

Caveats

  • You need to have done the grunt work to get to the point where you are able to be this specific.
  • Small jobs with specific tasks might seem like a lot of overhead for some people.
  • Some might think they’re giving away the crown jewels and that it’s not a serious job.

Tech sidebar: DynamoDB modeling

I wanted to learn how to use AWS DynamoDB to store content for the Knowcast POC. Why? It was the only true “serverless” storage system AWS offered and I was perhaps being a little obssessive about the principle of “serverless” being “you only pay what you use”. When budgets are ultra-tight, these things matter!

DynamoDB is an odd bird. Fundamentally as I understand it, it was designed for ultra-high scale deployments, with a schema structure highly optimised for extremely high production performance. Almost like Amazon designed something they themselves needed at their scale and deployed it for others to use.

Is this bad? The conclusion I came to was that DynamoDB is unnecessarily inflexible and complex for “smaller” workloads — the performance / agility balance isn’t right for most people, is my opinion.

Did I end up modeling one-to-many relationships in DynamoDB?

I made a call later on to run with a conventional relational model using “AWS Aurora Serverless” (where “Serverless” was clearly added by the marketing team 🤦‍♂️ for reasons I’ll explain later).

But DynamoDB is largely untyped. Shouldn’t your data in your storage layer be strongly typed?

Over the years I have come to the conclusion that I prefer “one job, one system”. If you impose business rules on how data can change, do just that. But to do that purely in SQL is impossible, so why bother at all? I feel that’s why DynamoDB is essentially schemaless — you have no safety nets at the storage layer, and I think that’s fine if you ensure all access is through your own data access layer on top, as is I think reasonable and fairly common practice.

One of my very targeted job as a recruitment test. The conversations I had were deeply insightful and I found my tech lead, Andre, as a result.

Next: but how do you build the right thing? My behaviour science journey

--

--

Julian Harris
Knowcast

Ex-Google Technical Product guy specialising in generative AI (NLP, chatbots, audio, etc). Passionate about the climate crisis.