How I found my first clients

One of my newsletter subscribers asked me:

Q: How do I find my first clients?

Every freelancer and consultant asks this when starting out. Either they have no clients or they have just a few to get them started.

Either way, everyone knows that they need to get more clients before the current ones finish up.

(The interesting thing is that this doesn’t change after you’re in business for awhile. You’re still going to be asking yourself where you get clients. Hopefully, by then you’ve learned some kind of repeatable marketing system so it’s less stressful.)

My previous employer

When I started, I consulted back to my previous employer. I left on good terms but moving to a different state meant that I couldn’t continue to work with them.

Fortunately, they had a few smaller projects that I could do on my own which would help them (and the development team I just left).

But in the grand scheme of things, they were only an okay client. They weren’t great. The projects were small and they use a different programming environment than what I wanted Little Stream Software to focus on.

Referral from a family friend

My next client is a better story. I meet them through a family friend. They needed just a basic brochure website, like under 10 pages, and there were no real requirements. I had full creative freedom.

I priced out a few options for them and they picked one (I don’t remember which one, it really didn’t matter). The project was a success and my client was happy with the final results.

It wasn’t a great fit though. At the time, I had a couple of years of Ruby on Rails experience and Rails was super-hot then (2007). I’ve already built and launched several successful Rails applications.

A static brochure site wasn’t a great use of my skills.

But it got me started and it was the first project where I won it based on my own personal skills.

After that second project, my confidence of talking directly with clients improved. I also learned that the great clients weren’t going to come to me just because I was “open for business”.

I needed a marketing plan or at least an idea of one.

Marketing glue

At its core, finding your first or even your latest client is about marketing. You’re finding people with problems you can solve and you solve them the best you can. Marketing is the glue that connects your services to those people.

Do it and you’ll find clients.

Do a great job at it and you’ll find great clients.

Don’t do it, or only put in a half-assed attempt and your competitors will take that business away from you before you even know it.

The solid answer to the original question about how to find your (first) clients:

  • find where they hang out and join them
  • demostrate your value with a presentation
  • build your professional network and get referrals
  • write about what problems they have and how to solve them

Once you find a tactic that works keep doing it until it doesn’t work anymore.

For myself that meant starting from the stereotypical introverted-developer and becoming an entrepreneur who loves marketing as much as development.

Just how important is marketing?

Marketing is so important that the first time I held the Run Your Consulting Business training course I had to split it into two weeks, and I still couldn’t cover everything.

But I did cover the three most important marketing strategies for freelancers and consultants. If you’d like to attend the next session, I’d like to see you there.

Eric Davis

How I started freelancing

I’d like to tell you a story about how I started web development and freelancing.

Gaming

In college I’d play computer games with friends across the world. We had a website to organize events and a forum to chat. It was fun but our website was always having problems. The webmaster at that time was also in college and he didn’t have the time to maintain it all himself. So I started to help out.

I had a background in computers but mostly on the hardware side. Fixing computers. Breaking computers. Re-fixing computers after my dad would complain that it stopped working after I ‘played’ on it.

Webmaster

While working with this webmaster I picked up HTML and PHP. The main reason I learned them was to fix problems.

Over time I became more interested in websites and programming then playing the games. My natural curiosity got the best of me and I started to dig deeper into computer programming.

Dot-com and entrepreneurship

At the same time I was learning about business and personal finance. I experimented with a few traditional business ideas. You see, this was right after the dot-com bubble burst so internet businesses were very much out of favor.

Side note: In one of my first classes there was a failed startup founder. He was only there for a week but from what I learned he started a company that was “worth” millions. Then the bubble burst and he was out. No business. No job. No prospects. Which is why he was going back to college. His story stuck with me.

Anyways. While I was teaching myself programming, I was learning the “textbook” way to run a business, while also experimenting with entrepreneurship on the side.

It was during this time that I decided I needed something with more structure than PHP for building websites. WordPress was just in its infancy and couldn’t be used for more than a simple blog. There weren’t any really good frameworks of “ready to go” PHP libraries. The only things out there were some heavy Python systems and this new thing called Ruby on Rails.

Suffice it to say that I tried Ruby on Rails and began the next stage of my programming journey. (One that continues to this day.)

Leaving California

Fast forward to 2007. My wife and I moved out of California to Oregon to start our post-college life together. As part of the move I sold my car. We wouldn’t be able to drive it, my wife’s car, and the moving truck up to Oregon.

(What we didn’t know if that we wouldn’t be able to drive my wife’s car up either. That’s a story for another day though.)

Once we moved up here, we became a single car family. I planned to re-learn how to ride a bike and use the great public transport system in Portland to go to work.

But instead, I wanted to do another experiment with entrepreneurship.

The Tiny Bet

I bet my wife that I could take half of the money from the sale of my car ($450), do “something”, and make back double that money in three months. Worst case I’d use the remaining half to buy a new bike and find a job. She agreed.

Thus started my freelancing business, which later was named Little Stream Software.

One little bet in 2007 turned into a freelance business that has keep me busy full-time, while earning more than I made as an employee.

Eric Davis

P.S. I’m telling you my getting started story to show that even without experience and outside help you can start your freelance business. Though it’ll go much better if you have a plan. Especially if it’s a good plan.

This story is part of my free 56-week (and growing) freelancer training newsletter. Join and build your freelance business

tEREUy1vSfuSu8LzTop3_IMG_2538

Don’t only track your time for clients

Tick tock. Tick tock.

I think time tracking is one of the top complaints freelancers have about the business. (Right below finding clients and dealing with problem clients)

You’d think by now it would be a solved problem. I mean, the only thing you’re doing is keeping track of what task you’re working on when you’re working.

It’s nowhere near as complex as the US tax system.

It’s not like it’s rocket surgery.

Yet it’s still a major complaint amount freelancers.

Yummy, yummy data

I’ll admit it. I’m a data and numbers person. I like metrics and measuring. I always have.

Since I’m so numbers-oriented I started tracking my time right away when I started Little Stream Software in 2007. And I’ve continued to this day.

I even track my time on non-client projects and internal stuff like taxes and email.

There is one benefit that many freelancers miss when they decide to ignore time tracking,

I track my time to know how much of it is used on good tasks and on bad tasks.

Time spent on the phone selling a client: good task.

Time spent on the phone to get a server fixed: bad task.

Value is in the review

Tracking time, it and of itself, isn’t that valuable. It’s valuable when you analyze and review that data.

Every few months I’ll do an analysis of where I spend my time.

  • How much time did I work on billable client work?
  • How much time did I work on my products?
  • How much time did I spend on marketing?
  • How much time did I use on other tasks?
  • How long were my days, on average?
  • How long were my weeks, on average?

And most important of all:

  • Are there any long-term trends in these?

This analysis let me discover many things in the past, such as:

  1. I was billing most of my time but wasn’t marketing, which lead to a lean time a few months later.
  2. My total billable time each month for each client would fit into a month, which lead to replacing my hourly rate with a weekly rate.
  3. There’s an average of 20 days per month which I could bill.

I could have happened across these insights without tracking my time, but they would have just been guesses. Realistically, I wouldn’t have seen them at all.

Even if you don’t track all of your time, try to do an analysis like this on the time you do track (e.g. client work). You might be surprised at what you find.

Eric Davis

Want weekly freelancer training like this?

QUnit – Tech Learning

This post is part of my tech learning series, where I take a few hours each week to try out a piece of technology that I’d like to learn.

This time I’m back to using JavaScript but instead of using a framework or library to build an application, I decided to try out the testing framework called QUnit.

QUnit came from the jQuery project and is now a general purpose JavaScript testing framework. I’ve used Jasmine for my JavaScript testing in the past but I’m not a fan of the BDD/spec style it uses. Maybe that’s because I learned unit testing on Ruby’s Test::Unit but I’ve always preferred assert style tests over expect.

Testing with QUnit

Since I don’t want to build an application just to use QUnit, I decided to port an existing test suite from Jasmine to QUnit. My A/B Test Calculator was the perfect candidate:

  • it’s small
  • it’s self-contained
  • it has an existing, high coverage test suite

Getting started with QUnit was easy. Their documentation was pretty through and all that I needed was to create an HTML file that did a few things:

  • loaded the QUnit css
  • had a div with the id of qunit
  • had a div with the id of qunit-fixture (though I didn’t use it in these tests)
  • loaded the QUnit JavaScript
  • loaded my test suite

Autostart

One thing that threw me for a loop was I was trying to use grunt to run the tests on the commandline. Normally QUnit runs automatically on the page load, but in Grunt that wouldn’t work.

Instead, you need to stop QUnit from starting automatically, load your tests, and then start QUnit manually.

  <script src="qunit-1.14.0.js"></script>
  <script>QUnit.config.autostart = false;</script>
  <script src="tests.js"></script>
  <script>QUnit.start();</script>

Test layout

Instead of using nested functions or methods like Jasmine and Ruby to separate contexts, QUnit takes a simpler approach. Making a function call to QUnit.module("name") will end your current context and start a new one.

At first I thought this was confusing but it actually prevented my tests from getting deeply nested. I could see this being an advantage when refactoring tests because you wouldn’t need a dummy commit to re-indent everything after moving code around.

Each module can also have setup and teardown functions that run but none of my tests needed them.

Tests

Each test is started using QUnit.test("test name"), function(assert) with the function acting as your test body. The assert object is where your assertions are called on. Though I wouldn’t do it, you could use a different name like expect and make it spec-like:

QUnit.test("test name"), function(expect) {
  expect.equal(a, b)
}

Calling it should might be interesting though:

QUnit.test("test name"), function(should) {
  should.equal(a, b)
}

Running QUnit tests

Running the tests couldn’t have been easier. I was using grunt on the commandline and they’d work exactly how you think.

I was also able to open the test HTML file in a browser using file:/// and QUnit worked exactly how you’d expect.

Summary

I really enjoyed using QUnit. It feels more direct and simple than Jasmine though I don’t know how many third party libraries are out there for it.

I’d also be curious to see how to integrate it with Rails and the asset pipeline. That’s one of the main reasons why I started with Jasmine, it had some great Ruby integration and it felt like a good fit there.

I’ll definitely be adding QUnit to my standard toolkit. It won’t be replacing Jasmine yet, at least until I get an opportunity to try QUnit in Rails and in a production application.

Would you like to hire me?

Code

The HTML test runner which loads the tests and qunit.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>QUnit Tech Learning</title>
  <link rel="stylesheet" href="qunit-1.14.0.css">
</head>
<body>
  <div id="qunit"></div>
  <div id="qunit-fixture"></div>
 
  <script src="../src/qunit-tech-learning.js"></script>
 
  <script src="qunit-1.14.0.js"></script>
  <script>QUnit.config.autostart = false;</script>
  <script src="tests.js"></script>
  <script>QUnit.start();</script>
</body>
</html>

The test suite which has two modules.

QUnit.module("Sanity");
QUnit.test("sanity test", function(assert) {
  assert.ok(1 == "1");
});
QUnit.test("SplitReview loaded", function(assert) {
  assert.ok(SplitReview);
});
 
 
// Based on abingo and http://20bits.com/article/statistical-analysis-and-ab-testing
var treatmentA = [
  { impressions: 182, conversions: 35},
  { impressions: 180, conversions: 45}
];
var treatmentB = [
  { impressions: 182, conversions: 35},
  { impressions: 189, conversions: 28}
];
var treatmentC = [
  { impressions: 182, conversions: 35},
  { impressions: 188, conversions: 61}
];
var treatmentD = [
  { impressions: 182, conversions: 35},
  { impressions: 189, conversions: 14}
];
var treatmentE = [
  { impressions: 182, conversions: 282},
  { impressions: 189, conversions: 114}
];
 
QUnit.module("SplitReview#score");
QUnit.test("should return a scoring object", function(assert) {
  var result = SplitReview.score(treatmentA);
 
  assert.equal(typeof(result), "object");
  assert.ok(result.z, "z should be defined");
  assert.ok(result.p, "p should be defined");
  assert.ok(result.winner, "winner should be defined");
 
  assert.ok(result.a_rate)
  assert.ok(result.b_rate)
});
 
QUnit.test("should show the experiment as a winner against treatment A at 90%", function(assert) {
  var result = SplitReview.score(treatmentA);
 
  assert.equal(result.a_rate, 19.23);
  assert.equal(result.b_rate, 25.0);
  assert.equal(result.winner, 'b');
  assert.equal(result.z, 1.33);
  assert.equal(result.p, 0.10);
});
 
QUnit.test("should show no winner against treatment B", function(assert) {
  var result = SplitReview.score(treatmentB);
 
  assert.equal(result.a_rate, 19.23);
  assert.equal(result.b_rate, 14.81);
  assert.equal(result.winner, null);
  assert.equal(result.z, -1.13);
  assert.equal(result.p, null);
});
 
QUnit.test("should show the experiment as a winner against treatment C at 99%", function(assert) {
  var result = SplitReview.score(treatmentC);
 
  assert.equal(result.a_rate, 19.23);
  assert.equal(result.b_rate, 32.45);
  assert.equal(result.winner, "b");
  assert.equal(result.z, 2.94);
  assert.equal(result.p, 0.01);
});
 
QUnit.test("should show the control as a winner against treatment D at 99.9%", function(assert) {
  var result = SplitReview.score(treatmentD);
 
  assert.equal(result.a_rate, 19.23);
  assert.equal(result.b_rate, 7.41);
  assert.equal(result.winner, "a");
  assert.equal(result.z, -3.39);
  assert.equal(result.p, 0.001);
 
});
 
QUnit.test("should show the control as a winner against treatment E at 99.9% (over 100% conversion rate based on unique counting)", function(assert) {
  var result = SplitReview.score(treatmentE);
 
  assert.equal(result.a_rate, 154.95);
  assert.equal(result.b_rate, 60.32);
  assert.equal(result.winner, "a");
  assert.equal(result.z, -12.27);
  assert.equal(result.p, 0.001);
 
});

Helping new entrepreneurs build a successful software business.

Need more freelance clients?