I failed a $5000 web dev Upwork project

––– views

5 min read

Firstly something about me, I'm a 24 years old self-taught dev, I started coding in 2018, and got my first freelance gig a year later since then.

I've been mostly working with long-term clients and things have been progressing slowly until October of last year, when⁠ ⁠I received an invitation from a client that had no Upwork experience, and by my first impression, they were tech illiterate.

There I was hungry for more $ and experience and decided to give it a go. ⁠

Job description

"Build a site for a travel agency based in the Maldives, that offers luxury stays and experiences."

Requirements: "Statically generated Gatsby site, that would get data from a CMS and automatically create all the pages for all the accommodations/events they offer" ⁠ ⁠Time to complete: "1 month", a little optimistic but okay.

The biggest reason for the failure of this project was what's known as "scope creep" it is a concept for determining project length and how much time it would take me to implement all the features that the client requested.

The client had no experience managing and successfully launching sites, I had limited experience when it came to taking a project to the end on my own successfully, we were bound to fail the moment we signed the contract.

Project story

At first, things were going great, they had the design ready and a database schema. In the first week, I managed to somewhat finalize all the models in Sanity, created half of their landing page, and planned out the next two weeks.

They were happy and so was I. By the end of the third week I had done what was agreed upon, but now they realized that manually entering all the data would be a nightmare, so I added another task to the backlog.

Then they realized that they needed a feature that would check hotel prices in real-time and display them accordingly on every hotel page (again a feature not originally agreed upon). I used an API, which has a ton of real-time information for most of the hotels.

Problems and misunderstandings

After this, all kinds of problems started coming up, images that they were uploading were raw and not at all optimized, I guided them to use optimization tools. In the end, they had to hire someone who would optimize the 5000+ images they had. Which slowed the whole process down.

Then the hotel page design was changed mid-development, and it took an extra 20 hours for me to implement. ⁠⁠At this point, I was getting anxious about this client and I wasn't seeing the end of the project anytime soon. We were 1 month in ($3800) spent, with a budget of $5000, and the project wasn't even 50% completed. ⁠

After fixing some of the above-mentioned problems and reaching their target budget of $5000, they paused my contract saying it was what we previously agreed upon, and that it would take only 2 more weeks of work (for free) to finish it.

I skeptically agree with this and was determined to take it to the end and get rid of them. Two weeks later and we're even further from the end than before, new features were requested, old features were removed, data problems and unorganized images, this time they sent me a $200 bonus 👏, and once again tell me that they only need 2 more weeks of my time to which I again naively agree.

Near the end of the 4 free weeks they again ask for more free work, at this point I know it was over for me. I canceled the contract, I wasn't going to spend one more minute thinking about this project. They left me a 1-star review and the worst words I have ever read about me. Luckily at this time, I was already a top-rated + freelancer on Upwork.

Being a top-rated+ freelancer grants you Feedback Removal for one project

Lessons learned

Toxic clients will always exist, the goal is to start recognizing red flags early on. Ever since this happened I had 3 new clients who had clear goals and previous experience, I was able to do a perfect job and they were happy with the results.

This failed client was my 3rd major one and the hasty decision to accept the contract after just 1 brief interview is the biggest mistake I've made professionally. These days before I accept any interview I keep this checkpoint list.

The project needs to have clearly defined goals

  • All major features must be defined
  • The time frame needs to be realistic
  • External services to be used need to be determined and costs agreed upon
  • 💡
    During any project, there will most likely be feature/scope changes, but as long as clients have common sense, many of the problems would be avoided

    Communication is a top priority

  • Timezones are hard, my availability/client's availability needs to be set, I don't want the client to expect me to be available at 11 pm (which happened many times)
  • Meetings should be arranged at least 1 day prior
  • Room for error

  • This is web development, in a perfect world everything goes to plan, but we aren't in one. Having room for error gives you the advantage to solve problems without pressure.
  • If you think a feature would take 3 days to implement, always add at least 25% more time, if you say it takes 4 days but do it in 3 that's great. The other way around not as much.
  • Conclusion

    I was able to get out of this project without damage, but for someone else it might be different, I'm sure every seasoned freelancer has dealt with this kind of client before, and maybe you will too, the biggest advice I could give you is to always be on the lookout for red flags and don't be greedy, money will always come if you're good at what you do.

    By now you might be thinking that the client got the worst end of the deal, and I do agree with you, my lucky point was the special feature from Upwork, in the end, I was paid in full, learned a valuable lesson, and got 200 hours + of web development experience.

    All they got was an unfinshed project with no end in sight, I do feel sorry for them and I do wish I would’ve done a better job. But as I said in the beginning the project was doomed the moment we signed the contract.

    To comment please authenticate