Take a Strategic Vacation

This is yet another story that I’ve told dozens of time to individual and groups, and now finally written down. Here is a short video talk:

Back in 2004 I co-founded Mobile Workforce Management, a vertical market SaaS firm. For the first 6+ months, I was the entire development team, while my co-founder was the entire analysis, support, and customer happiness department. Over the course of a few years, we hired developers, a very-senior developer / leader / general manager, support staff, and more. In spite of these hires, as of 2007 I was still in the loop for numerous critical processes that had to happen every day or week to keep the doors open – not a great situation.

Around that time I was inspired to take a month-long family vacation, far longer than any past vacation. My family made arrangements to spend 3 weeks in a house by the beach, 1000 miles away, in the summer of 2008; these arrangements must be made far in advance, as such houses tend to fill up. I’d be away for approximately an entire month, allowing for travel time and stops along the way.

With that hard date in hand, my notions of ironing out the business processes “someday” were swept aside, and I set about tracking, automating, documenting, and delegating any of the work that involved me and had to happen at least monthly.

  • accounting / bookkeeping / payroll
  • production sysadmin
  • development sysadmin
  • system monitoring
  • management processes
  • customer relationship processes
  • vendor relationships
  • design and code reviews
  • much more

It took months of hard work (by myself and others) to build up our company ability to handle all of these things well in my absence. As of the vacation date, all of this was set up to run smoothly either entirely without me, or with a tiny bit of remote input from me.

This worked, in fact it worked so well that our customers didn’t even notice my absence.

Though I didn’t know it at the time, the work I did then to increase our organizational process maturity was a turning point in the life if the business, enabling its eventual sale. Before that work, I’d have been a bit embarrassed to say “organizational process maturity” in public. Afterward, I have lived (rather than just learned about and talked about) the notions of working on-rather-than-in a business, of building a business with a life separate from that of its owners.

In retrospect I’m calling that trip a Strategic Vacation – a vacation taken both for its own value, and to drive the accomplishment other critical goals. If your business needs you every single day, that’s a problem. Create some pressure on yourself to solve it, by scheduling a strategic vacation, then go make it happen.

When Will It Ship? Estimates and Promises

I’m trying something new with this post: a short video presentation of approximately the same content.

Here is an area of confusion that has come up both at Oasis Digital, and at every other firm I’ve worked:

estimate ≠ promise

Background: Unpredictability

Around half of my software development and leadership experience has been in enterprise/internal software development, and that is the world I am thinking of as I write this.

Software development, like other endeavors with a significant creative component, is inherently unpredictable. With a good, deep understanding of the development process, you can build a model of the probability distribution of the cost, effort, and elapsed time for software development work. In the large, on average this can be made to work: small and large projects can succeed, within some broad range of predictability.

But notice also how common it is for large complex projects (in software and elsewhere) to be farcically over budget and late. This is not (usually) due to incompetence or fraud. It is because of the inherent unpredictability of the work.

If someone claims that they (or you) can exactly predict software development work, they are:

  • mistaken, or
  • lying, or
  • padding their estimates very substantially, stating a date or cost much later/higher than a neutral median estimate would suggest

As a customer of software development services, and as a provider of such services, I don’t want any of those things.

Blame the Service Trades

I place some of the blame for the confusion of these two wildly different things, on the service trades: it is common for auto repair shops, roof installers, landscapers, and the like to offer something they call an estimate, but which is actually a fixed price quote (a promise).

Sadly, while there are plenty of common good synonyms for promise, there aren’t many for estimate. We’re stuck with using the word estimate, and explaining that we really mean it as defined. Perhaps in a few more decades we will lose the word entirely, much like the word “literally” has come to mean its antonym, “figuratively”, which renders it mostly useless.


An estimate is an approximation of an unknown quantity. Typically in the world of software development, it is a prediction of the cost, working hours, or delivery date of a project or milestone. It is not in any sense a commitment, any more than estimating the temperature outside this afternoon is a commitment.

As the word implies, a customer reasonably expects the actual value to vary somewhat, in either direction, from the estimate. In fact, if an estimate turns out exactly match the actual result, there is a good chance the books have been cooked. Moreover, if the work is completed at-or-before the estimate most of the time, this means the estimates (on average) are too high.

An estimate “costs” nothing, other than the time/effort required to create it, which consists of analyzing the work at hand, decomposing it in to parts, and comparing those parts to past work.


A promise, also called a commitment, deadline, quote, fixed price, etc. is a different beast entirely.

With a promise in hand, a customer should expect with high confidence that the actual value (for cost, hours of work, delivery date) will be less than (before), or equal to, the promised value/date.

Be wary of a promise easily made and freely given: it probably doesn’t mean anything at all. A wise customer (and I aim to count myself in this category) should expect that a casually made commitment will probably be broken; not because the maker is morally defective, but simply because meeting a commitment for complex work requires considerable effort and thought. Without evidence that happens, it would be mere wishful thinking to expect the results delivered as promised.

Likewise, keeping promises often has a cost. If the work underway gets behind the schedule needed to meet the promise, something will have to give:

  • Other work may fall behind, as time and effort are diverted to meet the promise.
  • Weekends, evenings, and overtime work may be needed. These might appear free, but are not.
  • Staff may need to be reassigned, or added
  • Additional hardware and software may be needed.

These risks cost real money; thus a wise promise-maker will find that, on average, it costs more to promise feature X by date D, than to delivery feature X by date D without such a promise.

Estimates are Cheaper, so Prefer Estimates

At Oasis Digital, we provide many estimates, but few promises. Most of the time, an estimate is what our customers need; and we can provide at estimate with very little cost. Typically we estimate reasonably well:

  • small features usually arrive with a day or two (plus or minus) of the estimated delivery date (and likewise for cost)
  • medium items within a week or two of the estimate, likewise
  • large items (major new features or subsystems with complex interdependencoes) within a month or so, likewise

The key here is is that with good estimate, commitments (promises) aren’t needed very often, and therefore the cost of promises can be avoided.

But Learn How to Promise Well, Also

Yet occasionally, a customer needs a commitment, most often because a software version needs to be available to match an important business event with a fixed date, such as a presentation, a legal filing, etc. I’ll follow up later (no promise or estimate, as to when) with thoughts on:

  • how to credibly make promises (as a service provider)
  • how to evaluate promises (as a customer)

Mobile Workforce Management, a Five Year SaaS Mission Completed

Here is the story of a substantial chunk of my professional life over the last five years. I didn’t tell this story in real time (for various good reasons), though I have mentioned bits of it in various talks.

In 2004, I co-founded a vertical market Software as a Service firm, Mobile Workforce Management (MWM). MWM serves the underground utility locating industry with a Software-as-a-Service offering, TicketRx. Most people interact with this industry only with an occasional “call before you dig”, and think of it as just a phone number. However, there is a lot more to that industry than a phone number; there are numerous companies involved, each interacting with the others to complete the work. It is a vertical market niche with specific software needs, which our product met.

I personally wrote and administrated the first version of the TicketRx software and the first few servers, and my cofounder personally performed analysis, support, documentation, operations, and mountains of other work. We then incrementally hired a team to expand our capacity (and make ourselves replaceable), building an organization to serve its customers. Our software startup became an operating business with a life of its own.

Fast forward… five years of incremental and accelerating growth…

In 2009, the opportunity presented itself to sell MWM, and we did so. MWM is still there, operating fine without me. The press release about the sale is online and is also reproduced below. It is amusing to see how PR-speak invaded, labeling TicketRx as “custom” even though its whole essence was to not be custom, but rather off-the-shelf and highly configurable. Perhaps it is custom in the very broad sense of being industry-specific.

As is common in deals like this, the “terms of the transactions were not disclosed”, along with many other interesting bits. Still, I have a great number of lessons-learned to share in future posts and talks; and as of early 2010, there is extensive information about the product itself on the company’s web site, http://mwmsolutions.com/

Where does that leave me?

For some reason, the notion of having two companies then selling one, has been surprisingly hard to communicate. I still own Oasis Digital Solutions Inc., a consulting / custom software development firm, and work more intensely than ever with its customers and developers. Oasis Digital is growing up rapidly, with marketing efforts and ever-increasing process and organizational maturity.

Growing a product/SaaS business was a great experience, and one I hope to repeat. I’m actively on the lookout for another non-consulting software business to launch, when the time and opportunity are right.

St. Louis-based MWM sold to Consolidated Utility Services Inc.

Custom software product TicketRx, provides cost effective job tracking for utility locating company

Jan. 19, 2010: ST. LOUIS, Mo. – St. Louis-based Mobile Workforce Management has announced the successful sale of its company assets, including its commercial software as a service product, TicketRx, to Consolidated Utility Services Inc., an underground utilities locator company based in Omaha, Nebraska.

“With TicketRx, we created a customizable system to provide field service staff remote access and management tools for receiving, routing and tracking tickets and job assignments in real time,” said Kyle Cordes, a principal of Mobile Workforce Management (MWM) and owner of local consulting firm Oasis Digital. “We started TicketRx in 2004, and experienced great success with over 1,000 users and a growth rate of 25% per year.”

The sale of TicketRx to Consolidated will allow the company to integrate the system into their full spectrum of services that serve to protect utility companies’ underground infrastructure. In addition to ticket tracking, Consolidated offers clients systems for locating utilities, performing field audits and managing claims.

“Creating a comprehensive software solution such as TicketRx that fulfills a complex set of needs and watching it operate successfully is a very rewarding experience,” said Cordes. “I am confident the custom software solution we developed will make Consolidated’s business stronger.”

TicketRx processes one-call tickets from ‘call before you dig’ call centers or utility companies and then routes the work to the appropriate field worker. Technicians have immediate access to the information they need, which improves on-time performance. And managers have easy-to-use tools for scheduling, balancing work loads and providing emergency notifications. The system tracks all activity on the ticket, which can be used to create invoices and reports.

TicketRx is a Software as a Service (SaaS) model, a growing trend in which companies are adopting easy-to-use services that can be integrated efficiently, with minimal risk and at a cost advantage. With SaaS companies can have the service they need without the responsibility for their own internal servers, data centers or related IT staff, saving them time and money. According to industry analyst firm Gartner by 2010, 30 percent of all new software will be delivered as a service

Since the sale of MWM, Cordes will focus his energies on Oasis Digital. “The sale of MWM and TicketRx allows us to concentrate our efforts first on our consulting clients here in St. Louis and elsewhere, then later on our next SaaS opportunity,” Cordes said.

About Oasis Digital Solutions Inc.

St. Louis-based Oasis Digital develops custom software for workflow management, application integration, business process automation, and handheld devices for companies nationwide. Oasis Digital can produce a whole project or subsystem depending on the needs of the client, using a variety of computer languages and technologies. Fore more information, visit www.oasisdigital.com.

About TicketRx

TicketRx is a product of Mobile Workforce Management, LLC, and is a software-as-a-service program for the underground utility locating industry that can manage locating tickets from one-call centers or directly from the utility companies. TicketRx offers a unique combination of a broad feature set, fast setup and quick learning time. For more information, visit www.mwmsolutions.com/ticketrx.

Sometimes You Need to Compile It Yourself

I posted an earlier version of this on the Puppet mailing list recently; it seemed worth expanding here.

An Ideal World

In an ideal world, for each piece of Linux software I use, a very recent version would be “in the box” in the distribution package repositories, for every distro and distro release I use. The package versions would be updated promptly, and backported to the most recent N distro releases. This would be done in such a way as to avoid unexpected breakage, offering a combination of original (as of the distro release), bug-fix-only, and all-updates.

We don’t live in such a world.

The Real World

I’ve found that, with at least Debian, Ubuntu, Red Hat, and Mandrake, typically only the most popular packages are prone to prompt updates for new upstream versions. Backports to not-the-current-distro are even more rare, for various good reasons.

Therefore, when adopting something less widely used, especially if I need the same (current) package version for various distro versions, I’m resigned to having to either package it myself, or find someone “out there” offering updated packages.

Example #1: Puppet

As I write this, the current Puppet version is 0.24.8. It contains a lot of bug fixes and enhancements relative to even the earlier 0.24.x versions. It would probably be only a slight stretch to say that in the Puppet community,  versions before 0.24.x really aren’t recommended for current use at all. Yet the most recent versions offered in-the-box for the last few releases for Debian / Ubuntu are all old enough to be in that category.

Example #2: udpcast

Udpcast is an extremely useful tool, both for cloning systems en masse, and for totally unrelated uses like the one I describe here; yet the version in the very latest Ubuntu is from 2004, and the same is true for Debian.

Example #3: Zabbix

To get good results with Zabbix, it’s necessary to have approximately the same, approximately current versions, on all machines. The versions in various current and past Ubuntu and Debian releases / backports are not even close.

But Please, Use Your Package System

Please, I ask you… and if you work for me on one of my projects, I require of you… do not take any of this to mean you should ever type “sudo make install”.  It’s a nightmare to untangle a system with a mix of packaged and ad hoc compiled code in /usr/bin and friends. Always install using the package system: for a one-off (one machine, ever) install, simply use checkinstall, it takes only an extra minute or two and make it trivial to back the install out later. For a set of production systems. dpkg and RPM are your friends. They won’t bite. Get to know them.

Playing to Win, Going Beyond the Call of Duty

I’m writing this up as advice to a rhetorical “you”, but it’s really written to a younger version of me.

Imagine that you are working on a project for a customer (or employer), who has a weekly or monthly budget limit. You are paid by the hour, for up to N hours per week; or perhaps you are paid a salary for full-time work, nominally 40 hrs per week.

You want to work on the project more hours than your customer will pay for. For example, maybe your customer can afford only 20 hours per week, but you have more time available that you’d like to spend on the project.

The most obvious path is to simply not work any more than your customer will pay. Go do something else unrelated instead, perhaps not even computer-related. This approach appeals strongly from a work-life balance perspective, and also has a “tit-for-tat” appeal along the lines of “I refuse to do anything that would benefit my customer unless I am being paid to do so”. However, it is a very bad strategy. Do not let your customers’s budget stop you from growing your skills and building something great.

A second path, at the other extreme, is to work all you want on a project, regardless of how few hours you are paid for. Simply don’t bill for the extra hours. This is an easy answer, and in spite of its appeal from my current perspective (as an employer and customer of software development work), I don’t recommend it. It will give your customer an erroneous indication of your productivity level, causing future problems for you (how will you live up to this apparent but false productivity in the future?) and for your customer (whose estimates and schedules will be fed by false data).

I recommend a path between these two extremes, a strategy by which you can do work that benefits you and your customer, now and in the future. Work the hours you bill, directly on your customer’s project. Then, if you have extra time available (that you haven’t filled with other, paying work), work as much as you care to, past those hours, on related activities that indirectly help the project and help you grow:

  • Read about the development tools and technologies you are using. (Learn by reading.)
  • Read about the project problem domain.
  • If your customer project uses a DBMS, read about and experiment with that DBMS.
  • Try another DBMS; port the customer project to this other DBMS. Even though the customer doesn’t need it, you can nonetheless learn a lot from the experience.
  • Build an additional feature that your customer did not ask for (yet); the offer it to them if they want it. By the way, this is a great time to learn to use a powerful source-control system to manage a long-lived branch with such a feature.
  • Start a second, sample project, which uses some of the same tools as your customer project. Learn by doing. Experiment on this sample project, practice using the tools. Try out options and feature of the tools that you haven’t needed yet on your customer project.

To me, this is a strategy for “playing to win”.

More About the Sample Project

By the way, the notion of a second, sample project is very powerful, for reasons far beyond your current project. Be careful to keep the real project code completely out of this sample project, and you will end up with a very valuable artifact: a working piece of software, built with tools you know well, which you own. You can use this project to help get future work, by offering it to future customers as a work sample, and by posting it on your web site to show (rather than merely proclaim) your expertise.

Getting Started with Git and GitHub on Windows

(Update: I have a new, related post about the Best Git GUIs for Windows.)

I’ve been attracted to, and trying out, various distributed source control tools for the last two years, and have come to the conclusion that the most likely “winner” is Git. Git does a great many things right, good progress is being made in the few areas it is weak, and it has rapidly growing popularity. There are many web sites with extensive information about using Git, learning Git, Git integration, and more.

For new Oasis Digital projects, we will generally Git rather than SVN for source control. Here are instructions I wrote to help our teams get started. The contents here are 95% generic, but the references to me are, of course, Oasis-Digital-specific.

(For a general introduction to Git, consider this video at GitHub.)


Although Git is a fully distributed source control system, it is very convenient to have a set of robust, central repositories. Oasis Digital’s repositories are hosted by GitHub:


Github offers a useful set of online features to supplement what Git has built in and available locally. As of the spring of 2008, GitHub is certainly a work-in-progress, I’d characterize is as a “beta” level service. Nonetheless it is worthwhile and recommended. There is a lot to learn from the “guides” published here also:


Install and Configure msysGit on Windows

I assume here that you are using Windows, although Git works very well (better, actually) on Linux or Mac. As I write this, the best Windows Git package is msysgit, available here:


Make sure to follow the download instructions labeled “If you only want to use Git”. As I write this the download is Git-1.5.5-preview20080413.exe, but get the current version available as you read this instead, not that specific version.

Install by running the EXE installer. Accept the default install directory. When you get to the PATH setting screen, I recommend the “Use Git Bash only” setting, because it avoid any risk of PATH conflicts.

By default, Git will be configured to translate text files between Windows CRLFs (in your working copy) and Unix LFs (in repositories). This setting is fine if you like to use an editor on Windows that insists on Windows CRLFs. I generally use an editor that is equally happy to use Unix LFs, so I sometimes use Git in the other (non-translating) mode.

msysgit includes both the git command line, and a usable GUI. The GUI is not on par with more mature products, but it is helpful and good enough for users who are allergic to the command line.

Create your SSH Key

The first step in using Git is to create your SSH Key. This will be used to secure communications between your machine and other machines, and to identify your source code changes. (If you already have an SSH key for other reasons, you can use it here, there is nothing Git-specific about this.)

In Windows Explorer, pick any convenient directory, right-click, and choose “Git Bash Here”.

Then type this command:

ssh-keygen -C "username@email.com" -t rsa

(with your own email address, of course)

Accept the default key file location. When prompted for a passphrase, make one up and enter it. If you feel confident that your own machine is secure, you can use a blank passphrase, for more convenience and less security. Note where it told you it stored the file. On the machine I tested with, it was stored in “C:\Documents and Settings\Kyle\.ssh\”

Open the file id_rsa.pub with a text editor. The text in there is your “public SSH key”. You will need it to set up your GitHub account, in the next section.

Beware of $HOME trouble: a reader reported a tricky failure mode in which some other software he installed had set up a HOME or HOME_PATH environment variable pointing in to that application instead of to your real home (“Documents and Settings”) directory.

More details on the key process are available here:


Set up your GitHub account

Go to http://github.com/ and sign up for a free account. In the sample here I signed up with a made-up alter-ego, harry@kylecordes.com. Use your own, real email address of course.

Don’t worry that GitHub describes the free account as for “open source” work; I will later add you as a collaborator to my paid (and therefore private, non-open-source) projects. Make sure to copy-paste in your SSH public key that you created earlier.

Once you have set up your github account, email your github username (not your password) to me, so I can add you to the relevant project(s). (Reminder – send to me only if you are working on an Oasis Digital project! If you are using this page as generic Git instructions, send the information to your project leader instead!)

Once I have added you as a collaborator to the relevant project and sent back its URL, you can navigate to the URL, which will look like this:


On that page, click the “fork” button to create your own workspace for the project. This will take you to your own page for the project, something like this:


Now you can clone this project to your own machine, as discussed below.

Getting Started Locally

First, use the “Git Bash Here” feature described above, to get a command prompt. Tell Git about your name and email address:

git config --global user.email Your.Email@domain.com
git config --global user.name "Your Real Name"

Then you are ready to proceed with getting into a project. Copy the “Clone URL” from a github project page. Make a new directory on your machine, to become your working directory. There are two approaches to which project to clone.

  1. Clone from your own fork repo. This will make it trivial to push your changes up, but require one more command to get upstream changes.
  2. Clone from the upstream (my) repo. This will make it trivial to get change, but require one more command to be able to push changes, because you can’t push to another Github users’ repo.

I assume later in these instructions that you chose #1.

Next, get your local clone by clicking, or by typing.

Approach 1: GUI

In Windows Explorer, Right click the working directory and choose “Git GUI Here”.

Choose “Clone Existing Repository” in the dialog that comes up:

Paste the URL that you copied above from GitHub. Note that in the screenshot I show it as if you clone your repo, while I think it’s slightly easier overall to clone the upstream repo. Thus it really should show git@githib.com:kylecordes/sample1.git instead.
Note that your browser might add an erroneous mailto: to the URL, which you must remove – Git URLs do not start with “mailto”. Enter the directory where you want your working copy:

Make sure to use real, reasonable values. For example, you are not working “sample1” and you probably don’t keep your working projects in a directory named “GitStuff”, so put in a directory that makes sense for the project you are working on. Also, put your working copy in a place where you can effectively work in it; for example the working copy for a web project should usually be under the webroot of your local development web server.

Click Clone. You will be prompted for your passphrase if you used one. In a few minutes the Clone will finish, and you have the project available on your machine. I’ve had sporadic problems with this process hanging (growing pains at GitHub are the likely cause), so if you don’t see progress for a few minutes, stop it and start over.

Approach 2: Command Line

I find this easier. In Windows Explorer, right-click on the working directory you want and choose “Gui Bash Here”. Then enter a command like this:

git clone repoURL

Git might prompt you about an SSH key, the first time you do this with github (or any other new server). Answer “yes”.

It’s worth pointing out here, if you didn’t already understand from the various Git web sites, that Git is a distributed source control system. It will pull down the whole project history, so you can browse history and even commit changes without online access. Thus Git works very well if you have an intermittent or poor network connection.

Work Flow

As with all source control, work in the directory where you use source control. Do not copy files back and forth between here and some other working directory, that is a path to endless merge and update problems.

Once you have checked out the software, here is a summary of your work flow. For more details, please read the copies Git documentation online. I suggest reading both the official Git material, as well as other sites and articles about Git.

Getting Changes

Get changes from others with “git pull” (or using the GUI). By default this will pull from the repo from which you cloned, so if you cloned the upstream repo, that will get other peoples’ changes.

If you cloned from your own Github repo, you’ll need to use something like this:

git remote add upstream git@github.com:kylecordes/sample1.git
git pull kyle upstream

Sending Changes

Commit your changes locally with “git commit” (or using the GUI). Remember that Git generally wants you to explicitly say which files’ changes to include (“git add”), so make sure you read and understand enough about Git to do this properly; it is only a few commands or clicks in the GUI. The usual caveat applies, to only commit actual source files, not generated files or temp files.

Push your changes up to your GitHub repository with “git push”. This step will make it so others on your project can see your changes. Do this at least once per day, and ideally more often as you collaborate. Assuming that you cloned from the upstream repo, you’ll need to set up a reference to your own Github repo (the one you can push to), with something like this:

git remote add harry git@github.com:harrycordes/odtimetracker.git

As usual, use reasonable names and relevant URLs, not my sample names and URLs. Once you’ve added the remote reference, pushing is easy:

git push harry master

When you have a set of changes (one or more commits) that you think are ready to go in to the main-line of the project, use Github to issue a “pull request”. Your project lead (me, typically, at Oasis Digital) will review your commits and either pull them in to the main-line, or send feedback about changes needed before they can be pulled in.

A key thing to understand about Git is that it makes branching extremely easy and fast, so that very convenient to use branches. If you are accustomed to other source control systems where branching is a big, painful thing, it will be very different for you in Git. Once you learn to use branches, you’ll sometimes push up a branch you are working on instead of master.

I’ve only scratched the surface in this introduction. You now have Git up and running with project code in it, so pick up a Git tutorial or reference (such as the screencast videos at GitCasts) and start learning.

To Learn More

I heartily recommend the “Illustrated Guide to Git on Windows“. It doesn’t yet cover GitHub, but does cover many more details of using Git itself.

Also, a bit of Git can be very useful even in a project that uses SVN, especially when you need to rearrange a bunch of files in SVN.

Update: In a newer post, I list several other Git GUIs for Windows.