Customer PM vs. Product PM

A Program Manager (PM) is defined by a person that is responsible for design and release of a software product or services. PMs are often developer themselves in small companies. In larger companies that is often not the case. A Product PM is responsible for the software whereas a Customer PM is involved with the implementation and service of the software. The lines are often gray – a good Product PM also works with customers and a good Customer PM works with the product group at the design phases.

What is the fundamental difference between a Customer PM and a Product PM? Being the advocate of the customer – the customer PM would like all kinds of features in a product. Especially, if the product is new and there are product gaps to be filled. Some of these features are really important that customers cannot live without and some are nice to have. Some features are customer specific and some affects all customers.

A Product PM prioritizes new features according to work that needs to be done by a release date, available developers and testers, and various other factors. Customer PMs are often tasked with solving the whole architecture of a project that can encompass a plethora of products whereas Product PMs are often focused with extreme sharpness on a particular product.

In the software business, everybody is under a time crunch. New features need to go out the door as soon as possible. Hastily making a product available sometimes comes with the price of product gaps – some features are missing or poorly built. This means a lot of "dancing around" for the Customer PMs. Customer PMs usually know how to work around it but it’s still is a workaround! The arguments in favor of the product gaps are – We know there are some gaps but without the release this version of the software customer will not have any improvements or xyz improvements. This is a fallacy, because now the customer has to apply a whole lot of workarounds to make a product work. Customer’s productivity goes down. Lots of coding workaround takes longer for the customer to implement their solution. In extreme cases, customers start looking for a product where they don’t have to do that which translates to competitive product.

Often Product PMs move on to the "Shiny Penny Syndrome" – working on new feature instead of closing the gap of the current product. These could be also brought on by upper management because the competition has the feature. Quite often these features do not align with what the customer wants. Surely an interview with the current customers can answer valuable questions about the new feature’s usefulness but this process is often overlooked. I realize a product needs to be competitive with the current market and for that reason it needs new features. But what happens to the product gaps in the software? Milestone after Milestone these gaps do not see the light of day. And when it does, guess what the customer has to do – they have to undo the workaround they implemented which again translates to more but less productive work for the customer.

As I mentioned earlier Customer PMs works on the whole architecture and because of this they often know the product gaps that are going to be especially painful to the customer and often before the customer gets to it. While the customer is in development mode, they are heads down and often don’t get to the product gaps as fast. I will be the first to admit that in the past I had often advised my customer to file a product change request because of a feature gap, instead of filing it myself.

I am not saying Customer PMs are all high and mighty. They have their own flaws. Customer PMs are often swayed by the current customer’s need, irrelative of the usefulness of the feature for the broader group of customers.

Instead of publishing a feature (or a featurette) I would propose to work on the entire solution. Example – to go from the ground floor to the hundredth floor you can build a ladder made of rope or wood, or you can build stairs. But is that really what you want? Let’s not do any of that, let’s build a high speed elevator. That is what our customers want – an elevator. If we have to wait for the elevator to be built, we will. Both of us are working towards the same goal which is to make the product better for the customers. I think after all said and done, customers will appreciate the Cadillac of all options.


Parallelize and load – Basics of splitting a table

If you are loading data from one SQL Server to another, you have options:

    1. Bcp-out the file and then Bcp-in
    2. Use SSIS to load data directly.

If the table is large you can split up the file creation or increase the data flow tasks in SSIS to load the table faster. This is a very basic way to parallelize a load.  Here is a simple trick to split up the table and it works well if the table in question has at least one somewhat distinct integer type column.


Table DDL –

CREATE TABLE [dbo].[Tablename](

[DateKey] [int] NOT NULL,

[AccountId] [int] NULL,

[OrderItemId] [bigint] NOT NULL,

[AdId] [int] NOT NULL,

[More columns]….



Using a mod function on the distinct integer type column to split the table in 5 pieces-

Select * from [DatabaseName]..[Tablename] where OrderItemId%5 = 0

Select * from [DatabaseName]..[Tablename] where OrderItemId%5 = 1

Select * from [DatabaseName]..[Tablename] where OrderItemId%5 = 2

Select * from [DatabaseName]..[Tablename] where OrderItemId%5 = 3

Select * from [DatabaseName]..[Tablename] where OrderItemId%5 = 4

This way of splitting up a table can be used in a Bcp-out call or in SSIS tasks. You can use any divisor number for the mod function.  Just remember to use a 0 based number on the other side of the equal sign.

As an example if you want to divide your table into 10 pieces –

Select * from [DatabaseName]..[Tablename] where OrderItemId%10 = 0

Select * from [DatabaseName]..[Tablename] where OrderItemId%10 = 9

Following script can help in creating Bcp-out scripts.

DECLARE @servername sysname, @dbname sysname, @tablename sysname, @outputdir sysname
        ,@splitbyCol varchar(300), @numsplits int, @totalsplits int
SELECT  @servername = @@SERVERNAME
       ,@dbname = DB_NAME()
       ,@outputdir = ‘c:\temp\’
       ,@tablename = ‘customer’
       ,@splitbyCol = ‘customerID’
       ,@numsplits = 0
       ,@totalsplits = 5

WHILE (@numsplits < @totalsplits)
SELECT ‘bcp "Select * from ‘ +@dbname+’.’+OBJECT_SCHEMA_NAME(object_id)+’.’+ name + ‘ Where ‘+@splitbyCol+ ‘%’+Cast(@totalsplits as varchar(5))+ ‘ = ‘+Cast(@numsplits as varchar(5)) +’" queryout ‘
       + @outputdir + name + ‘.dat.’+Cast(@numsplits as varchar(5))+’ -b 10000 -T -c -S ‘ + @servername
       FROM sys.objects
       WHERE type_desc = ‘USER_TABLE’
       AND name = @tablename

       SET @numsplits = @numsplits+1