Blog /

The Temptation of Services

Twitter Facebook Google+
BLOG PROJECTS

The Temptation of Services

10 Jan 2017

Services are a hallmark of many early stage start up companies. You start with the genesis of an idea, but you don’t really know whether or not that idea holds interest in the market until you put it out into the market and see if it holds water. Why invest a lot of time and energy into something that isn’t going to be providing value for the company long term once the company shifts direction? It is this line of thinking that leads early stage tech startups down the path of services orientation. However, when do service oriented approaches in tech make sense, and when do they fall flat, and what are their limitations?

As an example lets take a very basic and contrived activity and walk through it from a services and from a product oriented approach. Remember, this is just an example, think about it in analogy to actual services and product like activities rather than taking it literally.

The log(x) excercise

Suppose the company needs to generate a data set representing log(x) with a sample size of 1001 maximum value of 3. A purely services approach would take some (poor soul) and request “Could you manually create data until we have 1000 items that follow log(x)?” For the sake of argument suppose they start to construct a spreadsheet in the simplest way by manually entering the values (and they can’t use autofill). First they might know that log(0) is 1. So they will add the values [0,1] to their spreadsheet. Then maybe they will say I know the maximum value is 3, and log(1000) = 3, so they will also add [1000,3] to the data set. Now you have a dataset that looks something like:

0,1
1000,3

For simplicity lets represent this as an array of arrays:

[
  [0,1]
  [1000,3]
]

They need to have 999 more values, and they have exactly that amount between 0 and 1000. So they start one by one adding each additional value of [x, log(x)] to their data set using a calculator, until they are done. Suppose it takes about 5 seconds for them to enter each item into their spreadsheet. This means that the whole task will take the services person about 1.4 hours to complete. Now remember, this is an analogy, of course no one would do this, but suppose that the [x, log(x)] activity is standing in place for some perhaps more complex activity that might be difficult to productize.

An early stage tech startup executive might look at this and say. This is great, this means that they can get about 6 of these done in a day, or 30 in a week. Maybe you need this done on a weekly basis 300 times. So you decide to hire 10 services people and you have met the capacity required.

Now lets look at a purely product drive approach to the same problem. The company comes to a software engineer and says, I need to be able to generate spreadsheets with data representing [x, log(x)]. The engineer might come up with a black box solution like:

def discrete_log(max, values)
# code
  end

which takes a max and the desired number of values and produces [x, log(x)]. In this case they can use the function to produce the dataset:

discrete_log(3, 1000)
  =>
  [
    [0,1]
    [1, 0.3]
    .
    .
    .
    [1000, 3]
  ]

Again for the sake of argument, imagine that log(x) actually some much more difficult task which the engineer estimates will take about 80 hours to build, or 2 entire weeks worth of work. Suppose that this particular function doesn’t require any maintenence to utilize (not a realistic assumption). This is a simplistic example, but automatically we can see the obvious advantage of automation through a purely Produt driven process: ( Services: 400 Hours x Week | Product: 80 Hours)

This is just to state the obvious and say that automation saves time. Granted, services employees tend to be easier to find, and engineering assets much more expensive but you can see just in the simple fact that the product driven approach is a one time cost (albeit an expensive one), that it will end up being much cheaper to sustain over the lifetime of the company.

Another complexity is in the fact that the engineering assets do not scale linearly like services. Suppose that the engineering task was actually estimated to take 400 hours up front. You can’t, like in the services example, simply hire 10 engineers and expect the task to get done in 1 week. Usually one engineer is working on a specific task, or if the task can be broken apart, it doesn’t scale so simply. Worst case scenario it might take the engineer 10 weeks, and you will be stuck waiting those 10 weeks.

Now lets take each of these and submit them to some pressures you might expect in a tech start up environment.

Pressure 1: Changing Requirements

Suppose that the company realizes that instead of doing log(x) it wanted to produce spreadsheets of ln(x) (the natural log base e).

Services: The services approach is unaffected, now when they go to their calculator instead of type log(x), they type ln(x). All is well, the estimates are the same and the number of head count required is the same.

Product: The product approach is not marginally better than the services approach in this case. In this case the product engineer has to create a new black box function:

def discrete_ln(max, values)
# code
  end

and then apply this to the scenario. This glosses over the fact that discrete_ln and discrete_log might have some shared functionality.

#psuedocode
class DiscreteData

def log(x)
# some hard function
  end

def ln(x)
# some other hard function
  end

  def print
  [x, ln(x)]
  end

  end

So if the implementation has been invested in sufficiently then its possible the Product approach is not totally susceptible to this pressure. However, once the new function is implemented continued hours required to sustain the solution are 0.

Pressure 2: Changing Parameters

Suppose that we wanted to return 2 log(x) instead of just log(x). We can think of 2 as being a parameters of the problem since it is the coefficient on the function.

Services: The services approach is still unaffected, now when they go to their calculator instead of type log(x), they type 2 log(x). All is well, the estimates are the same and the number of head count required is the same. You are left with a total number of hours roughly the same as before.

Product: The product is practically unaffected. The existing solution can be extended by doing something like:

discrete_log(3, 1000).map{|x| [x[0], 2 * x[1]] }

Because in this case the changing parameter equates to changing the coefficient in front of the function we get this added benefit practically for free.

Pressure 3: Changing Scope

Say for example instead of just returning x and log(x) we also wanted to return log(2x), something like: [x, log(x), log(2x)]. Suppose that we wanted this to be the data backing a 2D graph before and now its the data backing a 3D graph. Now we have increased the scope of the problem.

Services: The services approach is increased slightly but is still unaffected. Perhaps instead of taking 5 seconds for each row in the spreadsheet now it takes 8 seconds. This can still be easily measured and to meet the needed capacity we can simply scale up the amount of services employees that we need.

Product: Like with Pressure 1, the product approach now may or may not be faster to implement in the beginning depending upon how general the solution was originally implemented. For example if the engineer anticipated requiring more dimensions he might have implemented the solution in a more general way:

#pseudocode
class DiscreteData

def log(value)
# some hard function
  end

def print()
  [ x, log, log(2x)]
  end

  end

Thus the internals of the function are abstracted out and the print function handles the heavy lifting of being able to configure the operation to expand to the needed scope.

Now that we have looked at 3 different types of pressure that can be exerted to both pure approaches lets step back and look at the advantages and disadvantages of each:

Pure Services Approach:

Advantages Disadvantages
Can know exactly how long the task will take and budget for it appropriately. Requires ongoing work from services down the road or incurs a recurring work stream.
Capacity Scales Linearly Capacity Scales Linearly
General process does not change with changing parameters, requirements or scope.  
Doesn’t require up front work. Time to first iteration is fast  

Pure Product Approach:

Advantages Disadvantages
Up front work is reusable in the case of changing Parameters Cannot know exactly how long the task will take and budget for it appropriately. Must work from estimates.
Up front work is reusable in the case of Changing Scope if the solution is sufficiently generalized Requires up front work without immediate apparent value, time delay.
Up front work is reusable in the case of Changing Requirements if the solution is sufficiently generalized  
Capacity does not scale linearly but has potential to scale polynomially or exponentially  

The curious thing here is that I listed “Capacity Scales Linearly” as both an advantage and a disadvantage for a Pure Services Approach. How can this be?

In the above graph I show how linear scaling capacity increases with increasing assets (in this case additional services headcount), and three possible graphs for how Product scales with increasing assets (both tech assets as well as infrastructure and engineering assets). You can see that linear scaling is useful in the early stages of a tech startup, it says that you get out of your asset allocation roughly what you put into it, but most important about this, is that you can measure how much you get out of it. That certainty is worth its price in gold to an early stage tech startup. This explains why it is so appealing: it is better to have a Known Good, than an Unknown Excellence. However, as the demands on a tech company grow, so do the demands on capacity. This is especially true for the web, where network effects can take place and you might be suddenly faced with a capacity requirement unlike you imagined. Faced with the prospect of producing an operation a million times in a week that would require a services head count of 100,000 people, suddenly the need for scalability becomes apparent, and if this capacity is not present that equates to lost opportunity for the company.

Product capacity scaling however is not linear. Its hard to gauge exactly what it is, but when things are going well it can in the higher limits far outpace the linear scaling of services. As with services approach it is still subject to diminishing returns, however, due to capabilities of vertical scaling within infrastructure the gap could be very large.

Pure Services to Product Evolution: A Handicap?

So its obvious that services have problems scaling, but they provide a lot of benefit upfront, therefore does it make sense to think of services -> product as an evolution of a tech company as it starts to reach maturity? This is certainly the prevailing conventional wisdom on the topic. However, this is where you see start differences in companies in Silicon Valley (heavily funded companies) vs everywhere else (modest initial funding). A heavily funded tech startup can skip the initial stages of having a more services oriented product by operating in the red for a considerable amount of time while the build out the product and then, if the planning has been on the mark, you begin with considerable capacity to scale. This doesn’t have to be a black and white equation either. Maybe the company can take on a modest amount of revenue through having a striped down product (MVP), that way they are showing momentum and still in the red but not depedent upon a heavy services approach for their operating cash flow. This is the lean start up model.

However, companies that start with much smaller initial investments might have to be more strategic about exchanging a certain amount of services to generate operating cash while they are simultaneously building out the product. However, in some ways taking on services is like taking on VC investment. In the same way that VC investors may have different priorities than the company, services may start to make special demands on the product. The product cannot serve two masters and in the end the product and the entire company starts to mold itself around a services oriented approach. This is why it is so important that companies utilizing services take every opportunity to productize their services whenever they get a little bit of a bubble in their operating expenses: The longer you use services, the harder it is to get rid of them.

Kicking the Services Habit

Why is it so hard to move away from services once your company has started to differentiate in that direction? Think about the people problem, once you have hired your services team to a certain size, services are going to be hesitant and resistant to automating any of their tasks (even if it means that it frees them up to work on more interesting things). Think of the logistical problem, the processes that services use have differentiated in possibly thousands of different directions, so it becomes very hard to generalize the snowflake like patterns that they have adopted they have done into a single coherent product.

But perhaps the biggest reason services are hard to drop is psychological. Why change things when they are working fine? Where is the need for something that is going to cost a lot up front and is difficult to measure? (this is not actually true, more on how to measure product features in a later blog post). After all, in some sense services feel good to a company. It feels productive, when a new spreadsheet is generated. But its important to stop and ask, is that needed productivity?

So, why implement a product when services can produce the results I want now? Let me answer that question by asking another question. Why exercise? Its just going to hurt and Im going to feel worn out afterwards. Because when you exercise you increase your bodies ability to cope with daily function. In other words, you have increased your capacity, much in the same way a product oriented mindset increases a tech companies capacity to scale.

Services in many ways are like an addictive substance. They provide immediate value quickly, they are apparent measurable value and capacity scales linearly. However, the longer you use them, the harder it is to get off of them for your organization, and the more likely your company is to fall into a pattern of stagnation.

Services = Short term gain?

Is that to say that all services are simply chasing after short term gain? Not necessarily. They could be a very deliberate strategic decision. For example, one Pure Services approach that seems to work for companies is a “Truncated” Pure Services approach. The idea behind this approach is for your company to embrace services and more or less scrape by with limited capacity until it reaches the finish line. Usually that means some type of acquisition event. In this strategy the services approach is important as a kind of “planned obsolescence” of the company itself. In other words, it doesn’t make sense for the company to invest in very long term gains because the company more or less has a target and only needs to grow to that level. Whether or not that level can be achieved with linear growth in capacity depends on the company, maybe companies will have to exchange a greater amount of Product in order to reach that goal, and where that ratio lands, whether its 50:50, 70:30, 90:10 really depends on the company.

However, even this is quite a gamble. As a parent company investing in another company, it seems likely that you would like to probe into the technology of a company and know whether or not it is truly scalable, or merely appears to scale but is in reality propped up by an army of services.

Pure Product Approach: A Possibility?

Revisiting the above code examples, you can see that even an attempt to implement a “Pure” product approach in fact produces a result that is still on a spectrum between Services and Product.

The more general you make your solution the more potential pressure the solution can accommodate making it more similar to services. In this way you can really think of Product development as the process of encapsulate potential services patterns within a repeatable automated framework, hence Software as a Service.

So how do you define the scope of your product? One tactic could be “code only to the use cases that you know of. “ That is, define the user stories you wish to cover and cover just those. However, another approach that is more in the middle of the spectrum might be something like “code to the use cases that you know of, and can estimate are likely to arise.” This is much more art than it is science. Its the true mark of a skilled engineer. But there is also something to be said about how the microservices approach fits into a possible hybrid services / product type architecture.

Suppose you already have a robust services architecture and would like to an adopt more of a pure product approach. If you define the needed scope to capture your current services in terms of a single monolithic product then you might be hesitant to start down that path because the scope may seem too ambitious. However, if you envision it as a series of microservices, some which can be productized easily and others which might temporarily remain as a service type arrangement then there is a greater chance you can start to break the problem apart and actually reach the goal productizing your services architecture incrementally, one small bite at a time.

Kyle Prifogle


Twitter Facebook Google+