Austin Powers meme: "The 'bug'... I think is gone..."

Why and How New Freelancers Keep Failing, Part 1: The Developers

This is the first, but perhaps not the last, article series on working with new freelancers from the client’s perspective. Over the years, I’ve hired a number of developers and designers to do parts of the projects of which I’m not particularly good, e.g., graphic design, or that are too trivial to be done at my own hourly rate.

Here I try to enlighten you on the obvious mistakes made by new freelance software developers whom I’ve encountered hoping that it will help you avoid the pitfalls. You wouldn’t believe how obvious some of these lessons are!

I’ll do my best to explain both sides of the coin in each situation, the client’s side, and the freelancer’s side. At the center of this whole freelancing thing is that the project needs to work well for both. Don’t ever forget that.

In the next three sections, I share all the juicy stories that help you get on the right track as a freelancer, from the beginning.

“I’m the real developer of [app X]”

Let’s start with a short description of an app development project that I had a very long time ago. The scope of the project was to make a simple Android app with a pleasing design and basic functions, initially for sales purposes rather than actual use.

The actual use would be something I planned to take care of and do the design iterations as needed to get to a fantastic outcome in Phase 2. But the core app could be purchased for a small amount of money, so it made sense to outsource Phase 1.

What happened

I searched through one of the freelancing sites for a rather fresh freelancer profile with a good enough portfolio. It didn’t take long, so I listed several profiles and had a quick text chat with a few people. I picked the prominent proposal from a freelancer in some European country. I tried to set up a quick call, but the freelancer seemed to be on the move. So it was text-only.

We started the project and had communications through Skype chat. It went well and I didn’t pay much attention to the fact (that I realized only later) that this freelancer was deliberately avoiding any other form of communication than text. The app got developed really well from a design perspective and all my wishes and comments were taken into account perfectly. I was very happy for finding a good freelancer for app development … might hire later again.

But, when we were close to reaching the end of the project, he asked for a bonus. I should pay an additional few hundred dollars because of his girlfriend’s birthday present and we could juggle the offset as a discount to the final milestone through the freelance site. I should send money to some online payment gateway outside the freelance site. Of course, I rejected this as being strictly prohibited by the site’s user agreement. So we finished the project and I got what I had asked for and paid for it through the freelance site. Case closed, I thought.

As the scope of the project was rather small, I hadn’t done code reviews, simple black-box testing. Then I realized I had paid a tiny bit too much for the work done. Simple exception handling such as opening the app when the internet connection is not available was missing. Thus, actually crashed the whole app! And there were some smaller issues in uploading and downloading media files.

I should have tested better, of course, and let the freelancer re-do a small portion of the work. But still, the end result was really good enough and more or less worth the money. I fixed those few code-level issues myself (since learning TypeScript doesn’t take long to learn, right). I gave a good review to the freelancer to help him get more clients. As a generous guy, I had no problem with that. The problems came only later!

Weeks from finishing the project I got a strange message as a contact request on Skype. Someone politely explaining “I’m the real developer of [app X]” and requesting me to contact my freelancer to make the payment to this self-claimed “real developer.” He was using some strange nickname I had never heard of as the name of my freelancer, but obviously, he was talking about the same project. The app’s name was quite unique.

So, my freelancer here had pipelined the entire project to someone else who did all of the work and then cut this poor “real developer” loose without paying anything! This is highly unethical. It is fine to ask other freelancers to do parts of the projects with which you’re not good. I’m doing that! It is not fine at all to screw your fellow freelancers. Definitely not.

After a quick googling it turned out the “real developer” was based in Asia and clearly had a properly transparent profile on LinkedIn and elsewhere. Now it started to look unlikely that my freelancer was not based in the country where he said he was located and all the other things were lies as well, especially the part about sending a birthday present to his girlfriend. That was probably the whole payment that the “real developer” would have received, maybe.

And, it also turned out that the source code was published on GitHub by the “real developer” in his frustration! I didn’t take any action on this because of the trivial nature of the code base and simplicity in design. I’d just lose time sorting this out. Copyright of the code wasn’t important, either. Also, the purpose and the plan with the app changed slightly so there was a lot of rework done later.

Afterward, I became curious and thought maybe this guy is systematic. He could have more profiles! So I used the exact same keywords to find similar profiles and, not surprisingly, I found a few almost identical ones in terms of keywords, portfolio items, and experience. I messaged a few of them and one turned out strange.

I simply texted a few lines about the project and perceived a quite similar style in writing back. So, very bluntly, I stated that the profile seems somewhat fake. The response was an angry message of accusing my client profile of being fake instead. The chat ended quickly – and the profile was removed by the freelancer! It was probably the same guy. Busted!

Imposters don’t get far in the world of freelancing. Doing it right probably turns out more profitable, and definitely less stressful.

Lessons learned as a client

Doing little projects by just picking your guy and paying a few hundred bucks is probably fine when the freelancer’s background looks credible enough. Anything bigger requires a quick call to verify that the person is indeed transparent enough about his/her identity and has the ability to communicate orally (which is a lot quicker from the client’s side).

On the other hand, there is a big pool of great developers from countries with which you wouldn’t have a common language, but that will inevitably be a lost option as communication is one of the key parts of doing freelance jobs, especially online. And some people are just shy and reluctant to call someone on the other side of the globe just like that.

Don’t engage in any bigger projects with people who can do text-only. They may find excuses for staying in that mode later on and might have something fishy going on.

Tips for freelancers

In case your online freelancer profile is contested, the worst thing to do is to start arguing about it. Instead, set up a video call and talk about your previous works shown in your portfolio and query about the new project the client has. That will sort it out effectively and professionally. Angry people don’t get jobs online.

The same solution applies to the case where the client is wondering whether or not to take the discussion further into the details of the project. Schedule a video call, it builds trust on an entirely different level than text-only chat.

And, needless to say, you shouldn’t cheat. Paying your supply chain properly is the right thing to do. If there’s no margin left for yourself, I suppose you’re not adding any value to the process yourself.

Also, needless to say, you shouldn’t ask for any payments outside the freelance site. Going that way will only get you banned.

“Sorry for delay. I will be submit project ASAP.”

The next experience is the first and by far the most miserable attempt to outsource a simple web app development project. This is something about which I’m still having nightmares, many years later. This is also something that I learned as a valuable lesson that helped to deliver good results and positive experiences of collaboration as my CTO-as-a-Service.

All I needed was a standard user management module for a web service that was a small part of a project I was doing. For the requirements of the project, I went forward with Microsoft’s stack with Azure cloud service backend, basic web app API template (ASP.NET, C#), and some front-end widget bundle that did all the tricky parts that were already designed by others in the project.

It’s a perfect scope for a freelancer to take care of and I assumed only to do the high-level supervision and some code reviews to our codebase clean. I could do the integration work myself, as long as the code was clean and tested properly.

The freelance sites didn’t offer that many options for web developers who knew the specific widget gallery, so it was not very time-consuming to find a suitable freelancer. (For brevity, I just call him “the dev” from now on.)

What happened

Pre-start discussions: The first discussions went as usual. We had a few messages and emails about the scope of the project and on this day I had a Skype call with the dev and explained the project in more detail. I listed the pages to be developed and a few particular requirements for database design. The dev’s estimate was 15-17 days of work, and we agreed on the price, which was below a thousand dollars. (My own estimate was 10 workdays, so it wasn’t so much off.)

The messages were pretty professional at first, but they turned into a very different style quickly, even before we got the project officially started, for instance, “can you accpet my proposal ? beacuse i will the project asap.” Busy guy, I thought. Better busy than completely idle (because there’s nothing more useless than a completely idle freelancer… assuming the idle time is there because of not being able to deliver anything of value so far).

Day 1: We had no issues discussing in English and a few questions revealed that the dev had a couple of examples of using the particular technology stack and the widget bundle to show. He seems to do this on top of his full-time work, which I thought might become an issue, but since the project was pretty small (my original estimate: around 10 days in total) and I wasn’t in a hurry, I thought this might work out quite easily. I clicked my Hire button and we got started.

Day 4: The dev sent me the first delivery, just quite a standard login and signup pages, both supposedly fully functional. I was positively surprised by the quick start in terms of calendar time. But when I ran the web app to test it, the database connection didn’t seem to work at all, so I had to ask for instructions.

  • Oh, I changed the connection string from what you had.

Ok, I thought minor mishaps could occur in the beginning. Changing something without mentioning it doesn’t let the client test what you have done. The two pages implemented worked ok and looked quite decent. The only comment I had was on copy-pasting the same five code lines for handling session data, which I requested to be turned into a single common method for all pages. This was corrected quickly by the dev. So far, so good. Or just acceptable, actually.

We talked about how to set up emailing service for signup, password recovery, etc., functions and I handed over suitable email accounts of the domain we used.

Day 8: The dev gave an update on login and signup pages and he had a very nice implementation of templates for each email that I could customize. Of course, all the sample texts were full of misspelling, missing commas, and such writing-technical issues, but, for the coding part, this was decent work. I gave him my compliments and thanks.

Day 12: Now a small update contained a functional user profile page that I got to test. This was the first big disappointment. I couldn’t really use the page at all and the password recovery function was buggy as hell. My comments included:

  • Loading of the user profile data was not implemented.
  • Forget password executes correctly but the page displays an error every time (false positive).
  • After password change, the first page to land was not the user profile page for entering a new password.
  • Passwords were not encrypted in the database!

The last point was something that I remember learning in my first job during the first few months. How could this be? Despite the fact that the dev had a credible freelancer profile, had I just hired a complete amateur?

Day 15: I got an update on the previous and expected that all of the bugs were fixed. Well, only about half of them were, so I had to list the other half again.

One of the classic mistakes of new freelance software developers is to assume the "bug" is gone without having tested their software

Don’t send your client another version before all bugs listed have been fixed. Yes, all of them!

Day 16: I got an updated package of the code and tried it. Nothing worked, so I queried about the reason. The reply included:

  • Sorry, wrong files was sent to you by mistake. And update record functionality was broken.

After testing, I started to get slightly frustrated as again the bugs listed were not fixed.

  • Thanks for the updates. You managed to fix half of the issues, but these will still need to be finished as I mentioned in the previous email already. The user profile page does not load saved content.

I listed a few new bugs for him and felt I have to clarify how things are supposed to go when doing freelance projects. We had very limited functionality to be covered for Milestone 1 and this was not going too fast because of way too many bugs.

Perhaps the freelancer really doesn’t have any idea about how software is developed and who’s supposed to do what, so I tried to clarify the expectations … but had I known I was dealing with an amateur from the beginning I would have told this earlier on.

  • I think we need to clarify the responsibilities in this project if it seems unclear. Your part is:
    • Coding of the specified functionality
    • Unit tests
    • Integration of your code to the existing codebase (which you did in the beginning really well!). Feel free to use whichever version of [the widget bundle] that does the job. Once your code passes the acceptance test, I will integrate.
    • Integration tests
    • Making a complete testable package for acceptance testing.
  • My part is:
    • Making specs & giving clarifications
    • Acceptance testing
    • Making payments
    • Integration work after acceptance test is passed

Also, I had to mention what clients expect in general, just to be sure.

  • I would appreciate it if you would not push your work to me, as I am your paying customer. Instead, please send me a fully tested package with all the code, so I can do my acceptance test efficiently without spending further time figuring out what parts of the code you have changed. I have now tested your package four times, which is way too much by any standard for such a simple set of functions. I expect more careful implementation and a more systematic way of working with different versions of your files. I have time for only one more acceptance test for Milestone 1. I hope you can make it and conclude soon.

It is expected from every online freelancer that you have enough experience for getting the technical part of the work done. It’s simply so (and sorry if I just crushed your dreams here).

Day 22: The fifth update from the dev came. We tried to have a Skype call but it turned into a text chat only because of his internet connectivity problems. My feedback was purely technical at this point.

  • Some problem points:
    • Use of Knockout although we already have a [the widget bundle] library and good examples of simple JS and jQuery of how to use it. How does adding knockout make the code better?
    • Too many hard-coded text string when trying to make Knockout bindings in the HTML code
    • Mixing of CSS, HTML, and JavaScript code in [specific source code files] when we already had good examples of minimized, very clean HTML code with separate JavaScript and CSS files

And the list went on. Last but not least, actually funniest, was the issue of using the same email for user and customer profiles. So I guess the fundamental hierarchy of having customer organizations consisting of multiple users was not clear to the dev! This was something I never assumed to be mentioned since almost any software has the same approach. One of the user profiles can be assigned as an admin to a customer organization.

During the chat, I learned that the dev had gotten a friend to help with testing, which I was very happy to hear. Yet, I didn’t expect much improvement in real, looking at how things go from the pure project management side. Too many bugs in general and many of them were not getting fixed in the next update. Fixed one, produced another one. Classic coding failures.

Day 23: Now the work got a bit better to my surprise. He sent an update immediately, and it worked much better, only a few small issues remained. My simple reply was:

  • Thank you. Your package works ok now. I’ll fix the remaining 3 bugs myself when integrating everything together, probably faster that way.

Day 25: I suppose the dev felt a bit miserable so he sent yet another update trying to polish everything properly. Over the next couple of days we iterated through the Milestone 1 delivery. I still had to finalize text field validators and fix an issue of user account deletion. When an account was deleted, the same email address could not be used for registration anymore.

Anyway, we had now completed Milestone 1 and I had integrated it into the rest of the software successfully. But no points for style for the dev, though. I made the payment through the freelancing site according to what we agreed. By the time Milestone 1 was accepted, I had done seven acceptance tests on standard functionality that exists in every web app. We also had a chat about how to collaborate in a more efficient way and how the dev’s testing process was expected to improve.

Day 30: As the developer was finally getting at least something done and there were all the promises of the improved work process, we continued with Milestone 2. I listed the details of the pages I needed for the high-level functions on which we had a price tag already.

Day 31: I got a quick message to have a Skype call, which we did. Again it turned out to be text-only. I asked if he preferred to reduce his load on database work, because I thought I could just get that done faster and more correctly, so at least each page would load the data properly unlike before. It took about three minutes to wait for the answer text, which I assumed he was doing the math of how much less he might get paid because of the scope reduction. His reply:

  • I will do.

Day 41: There were no messages for about ten days. I was getting worried and pinged him on Skype a few times earlier. Now the dev said he had the customer register finished and finalized and gave his reason for the delay:

  • Sorry for the delay in response & not able to chat & give you update. I was busy with some medical emergency in family. so i was busy with that.

His delivery was much better than earlier and after my testing I only found minor bugs.

Day 49: Another eight days passed. There wasn’t any update from the dev, so I had to ask again if things are moving forward:

  • I haven’t heard from you for over a week now. I hope your medical emergency is resolving. I wish all the best.

Day 51: I got a reply accompanied by an updated version as well as a request for details on making the next few pages. I assumed that if this medical issue was now over we could proceed in decent collaboration.

Day 65: A short message of having the tasks done as a mere Dropbox file sharing note was all I got. The pages that were supposed to have been implemented were partially there, about half of what was required for Milestone 2. There were some issues with texts and database table naming conventions, etc. I listed just one critical bug and seven small ones. But still, one critical bug prohibiting the acceptance of the milestone even for the half that was implemented…

Day 74: There was no message on fixing the bugs for another week. I had to query about the dev’s availability. Still, my tone was rather positive. After pinging, we resumed the communication:

  • Sorry for delay. I will be submit project asap.
  • Ok, thanks for letting me know.

OK, if the work resumes and the second half of the milestone was completed, we’d still be on the positive side in the project, all in all. But definitely no extra points or nothing for the freelancer to quote or include in his portfolio, for sure. Bad work is bad work… but if you are finishing with pride it counts as a project completed.

Day 82:  I hadn’t heard anything from the dev for a few weeks. Not a word. I tried pinging him on Skype a few times. No reaction. I messaged about the status of the project being not finished more than 75% at best (and I was being very generous here) if we ignored the bugs that remained. Only 50% if we were strict about correct functionality.

Day 93: It was now four weeks since I had heard from the dev. No point pretending anymore. I closed the project. The freelancing site has a refund function, so I asked for a small refund through the system knowing that he’d get an automated notification email. That would make him move, for sure, if nothing else!

The worst kind of freelancer is the missing freelancer. No point asking for money if you decide to vanish before the job is finished.

Day 94: It only took a day to get that reaction to happen:

  • thanks for payment but i saw that there is refund request for 75 $, can you please tell me why is there refund request ? thanks

The same day, another short message before I replied to the first one.

  • Hello, I have received only 225$.

My reply started stating things that should and would have been started much earlier had the dev replied to my earlier messages the past month.

  • You should put more focus on your customer’s project and make sure you give realistic expectations, otherwise your customer might quit and move on. We agreed 300 USD for Milestone 2. As I mentioned earlier, you got about 75% finished. That is 225 of 300 USD. Considering that your latest 2 submissions only cover 50% of the use cases, I thought 75% is quite generous. You’re a good guy, I believe. Good luck with your endeavors and all the best.

There wasn’t any reply, so I thought the message got through and understood.

Day 99: I was betting this process would keep on going over a hundred days, but I was positively surprised it didn’t. That was the only good part. On Day 99 I got a surprise message from the dev with a title “Needed Help !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!” which looked like the world was coming to an end for him:

  • I hope you doing well !!!!! I want to say that You had already cut the 75$ fees but I had received the notification mail on [the particular freelance site]. Please see below.

He shared the message from the system (as text as well as a screenshot) and he didn’t seem to understand what was happening. It was the standard refund request processed by the system that would be drawn automatically from his account on the due date. Nothing out of the ordinary, that’s how that site worked, but he didn’t seem to know about it.

I couldn’t understand why he was asking money for work that simply was not done. Many of the web pages we had listed in Milestone 2 in the very beginning were simply not there.

From my side of the story, there was nothing I needed to do. I was pretty tired of being the supportive fellow freelancer that I tried to be in the beginning. The refund happened on the day expected, automatically. The end. The final conclusion took place over one hundred days from the start of the project with our dev here. And we never heard of him again.

In case the project is not completed or there is a major complication in working with the freelancer, few clients bother to think about it anymore but just let it go. Clients keep going with critical parts of their own work instead. Unfortunately, in this case, I wasn’t any better than any other client. I had no pressing need to reply to the last messages about the refund as I expected this guy not to get the idea anyway. And put an average review for the dev in the system.

Nothing to be highlighted in his portfolio, nothing quotable, just an objective description of the outcome that was a project nearly finished. To a new freelancer with a fresh profile on a freelancing site, that means a complete failure in any future attempts of getting new clients. Only a complete success brings more clients. Freelancers with no reputation will remain in the status quo with no future.

Lessons learned as a client

This section gets very short here. What more could I have done as a good client? My biggest mistake was that I believed the freelancer profile being genuine and the years of experience mentioned meaning something.

I did expect at least normal things to go – normally! A programmer not being able to test the most trivial functions before sending the work to the client for review does not deserve much help, in my opinion, but still being a senior freelancer myself I had to give another and another chance to him.

Maybe I shouldn’t have. Maybe I should have quit the project on the first sign of trouble!

Perhaps I can generalize that in case you notice that you’re in the client’s shoes and you realize you’re not dealing with a professional, it is better to quit than keep paying for someone’s personal learning process.

The learning process of doing the substance work takes place usually before you turn freelance, otherwise, what would you be able to sell? It is the art of freelancing, i.e., finding new clients and keeping the old ones happy, that you might learn from doing freelance projects. The technical skills must be there already.

Tips for freelancers

This dev of mine made so many mistakes it was difficult to list them in a concise manner. But here’s an attempt to do so. Let’s first list those that relate to communication:

  • Write all of your communications with the client in a professional way. It just gives a better impression than constant mistyping, always.
  • In case of emergency (external reason), be open to what you tell your client. In case of sickness, car accident, or anything like, (most!) clients accept that things happen in life. But if the delay is part of your work process and it starts to look like a chronic disease, your credibility is lost.
  • Don’t exaggerate your background, but stay truthful. Even if your polished resume gets you a project, the trouble only comes later when it turns out you cannot deliver what you let the client expects.
  • Don’t make your client repeat him/herself. If a bug is found and communicated to you, it is assumed to be fixed in the next update, for sure. If it isn’t what could you possibly say in your defense? Only working code brings you money.

Then those that relate to the business deal:

  • Never ask for money for work not completed. That will only piss off the client.
  • If you ever end up in a dispute and you have had feedback and rationale from the client, it is usually better to make the client happy rather than fight over a few dozen bucks. I’d say it is far better to spend a bit more time than risk gaining a bad reputation, which is far more important to a freelancer than small amounts of money.
  • If your first project on a freelancing site fails, it is better to delete your profile and start over. There is no chance of including a failed project in your portfolio.
  • Before sending any source code to your client, test it properly. If you do not have the time, ask someone else to do proper testing for you. One or two little bugs can go unnoticed, but if the core functionality that you had promised to deliver doesn’t actually work, you’re not doing it right. Your business is delivering software that works!
  • You can never let the project go unfinished. If the issue is on the personal side, you can always discuss it with the client and explain your situation. If continuing is simply not possible, it is better to try to settle the business deal (which each project on freelancing sites is) rather than let it die off. A dead project may mean no pay at all, in the worst case!

If this looks like a smart answer to you, please consider your value proposition. It won’t fly. Clients don’t need your time, they need the results you provide with your time.


Let’s sum up the lessons learned from these experiences, especially those that can be slightly obscure to new freelancers:

  • Your online profile has to represent your own identity. Don’t fake. Be clear if you work as an individual or as part of a company. The client will set the expectations according to how you appear.
  • Be transparent in communications and avoid the text-only mode, unless it is your client’s preference. Do video calls if possible to build trust. Get rid of your shyness, if that is the problem.
  • Respect the time of your client. Double-check your own work rather than let your client pinpoint obvious mistakes. Test properly. You’ll save time for both and appear like a pro.
  • Read the user agreement of your freelance site. Make sure you understand the policy about making payments.
  • Finish the project, always.
  • Don’t ask for money unless you know your client thinks you earned it.

A good principle is that a happy client is better than the one paying a few extra bucks, especially when the money only comes with complaints. The complaints would reduce your reputation and credibility, which is paramount to freelancers.

Are you struggling with any of the above issues or something similar? Got yourself in a situation you’re not sure how to handle? Get in touch with me and I’ll help you to get started with freelancing.

And check out Part 2.