<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Development</title>
        <link>http://ayende.com/Blog/category/467.aspx</link>
        <description>Development</description>
        <language>en-US</language>
        <copyright>Ayende Rahien</copyright>
        <managingEditor>Ayende@ayende.com</managingEditor>
        <generator>Subtext Version 2.0.0.0</generator>
        <item>
            <title>Pricing software</title>
            <link>http://ayende.com/Blog/archive/2010/02/27/pricing-software.aspx</link>
            <description>&lt;p&gt;It seems that people make some rather &lt;a href="http://ayende.com/Blog/archive/2010/02/24/profiler-subscription.aspx"&gt;interesting assumptions&lt;/a&gt; regarding software pricing. When talking about commercial products, there is a wide variety of strategies that you might want to push, depending on what exactly you are trying to achieve.&lt;/p&gt;  &lt;p&gt;You may be trying to have a loss leader product, gain reputation or entry to a new market, in which case your goals are skewed toward optimizing other things. What I want to talk about today is pricing software with regards to maximizing profits.&lt;/p&gt;  &lt;p&gt;Probably the first thing that you need to do consider the base price of the product. That is important for several levels. For the obvious reason that this is what you will make out of it, but also because the way you price your product impacts its &lt;em&gt;Perception of Value&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;If you try to sell your product at a significant cost below what the market expect it to be, the perception is that it is crap, and you are trying to get rid of it. &lt;/p&gt;  &lt;p&gt;Another issue that you have to face is that it is very hard to change the base price once you settled on it. It is fairly obvious why you have a hard time jacking the price upward, but pushing the price down is also something to approach with trepidation. It has a very negative impact on the product image. Now, you can &lt;em&gt;effectively&lt;/em&gt; price it at a lower rate very easily, but doing things like offers, discounts, etc. Those do not affect the base price and so generally do not affect how the product is perceived.&lt;/p&gt;  &lt;p&gt;And just as bad as with setting the price significantly below market expectations, setting the price significantly higher than market expectations. The problem here is that you come out as a loony with delusions of grandeur. Even if your product is wonderful, and even if it will return its investment in a single week, pricing it too high generate a  strong rejection reaction. It also means that you need to actively combat that perception, and that takes a lot of time &amp;amp; effort.&lt;/p&gt;  &lt;p&gt;Finally, in the range between too little and too much, you have a wide room to play. And that is where the usual supply &amp;amp; demand metrics come into play. Since supply isn’t a problem with software, what we are talking about is demand vs. price. Everyone in &lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Pricingsoftware_A413/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Pricingsoftware_A413/image_thumb_1.png" width="644" height="412" /&gt;&lt;/a&gt;economics is familiar with the graph, I assume.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.doctorhousingbubble.com/wp-content/uploads/2008/05/basic_supply_demand.png" /&gt;&lt;/p&gt;  &lt;p&gt; As price goes up, demands goes down, and vice versa. So the question is what is the optimum price point that would generate the most revenue. Here are some numbers, showing the probable correlation between price and sales.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="81"&gt;Price&lt;/td&gt;        &lt;td width="72"&gt;Users&lt;/td&gt;        &lt;td width="89"&gt;$&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 2,000.00 &lt;/td&gt;        &lt;td&gt;1.00&lt;/td&gt;        &lt;td&gt;$ 2,000.00 &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 1,000.00 &lt;/td&gt;        &lt;td&gt;1.00&lt;/td&gt;        &lt;td&gt;$ 1,000.00 &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 200.00 &lt;/td&gt;        &lt;td&gt;100.00&lt;/td&gt;        &lt;td&gt;$ 20,000.00 &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 100.00 &lt;/td&gt;        &lt;td&gt;200.00&lt;/td&gt;        &lt;td&gt;$ 20,000.00 &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 10.00 &lt;/td&gt;        &lt;td&gt;5000.00&lt;/td&gt;        &lt;td&gt;$ 50,000.00 &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;It might be easier to look at in its graphical form to the right.&lt;/p&gt;  &lt;p&gt;You can see that when the price point is too high, very few people will buy it, if at all. When the price point is in the range that the market expects, we make some money, drastically more than we would when the price was above market expectations.&lt;/p&gt;  &lt;p&gt;However, if we set the price &lt;em&gt;way&lt;/em&gt; down, we get a lot more users, and a lot more money pouring in. We will ignore the question of damage to the reputation for now.&lt;/p&gt;  &lt;p&gt;This seems to indicate that by lowering the price we can make a lot more money, right? Except that it isn’t really the case. Let us see why.&lt;/p&gt;  &lt;p&gt;1 in 10 users has a question, requires support, etc. Let us say that each question cost 100$, and now let us look at the numbers.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="81"&gt;Price&lt;/td&gt;        &lt;td width="72"&gt;Users&lt;/td&gt;        &lt;td width="72"&gt;Calls&lt;/td&gt;        &lt;td width="110"&gt;Support Cost&lt;/td&gt;        &lt;td width="110"&gt;Income&lt;/td&gt;        &lt;td width="114"&gt;Revenue&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 2,000.00 &lt;/td&gt;        &lt;td&gt;1.00&lt;/td&gt;        &lt;td&gt;0.00&lt;/td&gt;        &lt;td&gt;$ -&lt;/td&gt;        &lt;td&gt;$ 2,000.00 &lt;/td&gt;        &lt;td&gt;$ 2,000.00 &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 1,000.00 &lt;/td&gt;        &lt;td&gt;1.00&lt;/td&gt;        &lt;td&gt;0.00&lt;/td&gt;        &lt;td&gt;$ -&lt;/td&gt;        &lt;td&gt;$ 1,000.00 &lt;/td&gt;        &lt;td&gt;$ 1,000.00 &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 200.00 &lt;/td&gt;        &lt;td&gt;100.00&lt;/td&gt;        &lt;td&gt;10.00&lt;/td&gt;        &lt;td&gt;$ 1,000.00 &lt;/td&gt;        &lt;td&gt;$ 20,000.00 &lt;/td&gt;        &lt;td&gt;$ 19,000.00 &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 100.00 &lt;/td&gt;        &lt;td&gt;200.00&lt;/td&gt;        &lt;td&gt;20.00&lt;/td&gt;        &lt;td&gt;$ 2,000.00 &lt;/td&gt;        &lt;td&gt;$ 20,000.00 &lt;/td&gt;        &lt;td&gt;$ 18,000.00 &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;$ 10.00 &lt;/td&gt;        &lt;td&gt;5000.00&lt;/td&gt;        &lt;td&gt;500.00&lt;/td&gt;        &lt;td&gt;$ 50,000.00 &lt;/td&gt;        &lt;td&gt;$ 50,000.00 &lt;/td&gt;        &lt;td&gt;$ -&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;And that tells us a &lt;em&gt;very&lt;/em&gt; different story indeed. The end goal is increasing profit, not just the amount of money coming in, after all. &lt;/p&gt;  
&lt;p&gt;&lt;strike&gt;Oh, and a final thought, the following coupon code EXR-45K2D462FD is my pricing experiment, it allows the first 10 users to buy NH Prof, L2S Prof or EF Prof at a 50% discount. &lt;/strike&gt;&lt;/p&gt;
&lt;p&gt;Since all the coupon codes run out in a short order, I am going to continue the experiment, this coupon code ER2-45K2D462FJ will give the first 25 users to buy NH Prof, L2S Prof or EF Prof at a 25% discount.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11330.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2010/02/27/pricing-software.aspx</guid>
            <pubDate>Sat, 27 Feb 2010 10:00:00 GMT</pubDate>
            <wfw:comment>http://ayende.com/Blog/comments/11330.aspx</wfw:comment>
            <comments>http://ayende.com/Blog/archive/2010/02/27/pricing-software.aspx#feedback</comments>
            <slash:comments>20</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11330.aspx</wfw:commentRss>
        </item>
        <item>
            <title>The NIH dance</title>
            <link>http://ayende.com/Blog/archive/2010/01/12/the-nih-dance.aspx</link>
            <description>&lt;p&gt;I started thinking about all the type of stuff that I had to write or participated at, and I find it… interesting.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Database – Rhino.DivanDB (hobby project).&lt;/li&gt;    &lt;li&gt;Data Access – Multitude of those.&lt;/li&gt;    &lt;li&gt;OR/M – NHibernate, obviously, but a few others as well.&lt;/li&gt;    &lt;li&gt;Distributed caching systems – NMemcached – several of those.&lt;/li&gt;    &lt;li&gt;Distributed queuing systems – Rhino Queues actually have ~7 different implementations.&lt;/li&gt;    &lt;li&gt;Distributed hash table – Rhino DHT is in production.&lt;/li&gt;    &lt;li&gt;Persistent hash tables – Rhino PHT, of course, but I actually had to write a different implementation for the profiler as well.&lt;/li&gt;    &lt;li&gt;Mocking framework – Rhino Mocks, obviously.&lt;/li&gt;    &lt;li&gt;Web frameworks– I am referring to MonoRail, although I only dabbled there, to be truthful. Rhino Igloo was a lot of fun, too, if only because I had to.&lt;/li&gt;    &lt;li&gt;Text templating language – Brail&lt;/li&gt;    &lt;li&gt;Inversion of Control containers – Windsor, and a few custom ones.&lt;/li&gt;    &lt;li&gt;AOP – I actually built several implementation, the most fun was with the Code DOM approach :-)&lt;/li&gt;    &lt;li&gt;Dynamic Proxies &amp;amp; IL weaving – Castle Dynamic Proxy, not the recommended way to learn IL, I must say.&lt;/li&gt;    &lt;li&gt;CMS systems – several, but I really like Impleo and the concept behind it.&lt;/li&gt;    &lt;li&gt;ETL system – Took 3 times to get right.&lt;/li&gt;    &lt;li&gt;Security system – Rhino Security was &lt;em&gt;fun &lt;/em&gt;to design, and quite interesting to implement.&lt;/li&gt;    &lt;li&gt;Licensing framework – because trying to buy one commercially just didn’t work.&lt;/li&gt;    &lt;li&gt;Service Bus – which I consider to be one of my best coding efforts.&lt;/li&gt;    &lt;li&gt;CI Server – so I can get good GitHub integration.&lt;/li&gt;    &lt;li&gt;Domain Specific Language framework – well, I &lt;em&gt;did&lt;/em&gt; write the book on that :-)&lt;/li&gt;    &lt;li&gt;Source control server – SvnBridge&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I haven’t written a testing framework, though.&lt;/p&gt;  &lt;p&gt;I am probably forgetting a lot of stuff, actually…&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11277.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2010/01/12/the-nih-dance.aspx</guid>
            <pubDate>Tue, 12 Jan 2010 10:00:00 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2010/01/12/the-nih-dance.aspx#feedback</comments>
            <slash:comments>22</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11277.aspx</wfw:commentRss>
        </item>
        <item>
            <title>NIH alert! Writing my own RPC systems</title>
            <link>http://ayende.com/Blog/archive/2010/01/06/nih-alert-writing-my-own-rpc-systems.aspx</link>
            <description>&lt;p&gt;Let us see if you can help me here, I found myself facing a rather unpleasant realization, in that I need to communicate between two processes (that compose a single system) with some rather draconian measures about how they are going to be used.&lt;/p&gt;  &lt;p&gt;Quite simply, I need to expose an interface with ~25 methods on it to the second process. So far, it is pretty easy to do, right?&lt;/p&gt;  &lt;p&gt;The problem is that the first process is a standard .NET executable, which may also be run on the Mono platform while the second is a Silverlight application. My first thought, just use remoting to handle this, failed because remoting isn’t available to Silverlight. My second thought, to use WCF, failed because that isn’t available on Mono.&lt;/p&gt;  &lt;p&gt;Building a simple RPC system is pretty easy, so that doesn’t worry me. The reason I am reluctant to do so is that I &lt;em&gt;really&lt;/em&gt; don’t want to build yet another infrastructure. At some point, even to me, NIH flag starts to pop up.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11276.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2010/01/06/nih-alert-writing-my-own-rpc-systems.aspx</guid>
            <pubDate>Wed, 06 Jan 2010 10:00:00 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2010/01/06/nih-alert-writing-my-own-rpc-systems.aspx#feedback</comments>
            <slash:comments>31</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11276.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Fighting the profiler memory obesity</title>
            <link>http://ayende.com/Blog/archive/2009/12/29/fighting-the-profiler-memory-obesity.aspx</link>
            <description>&lt;p&gt;When I started looking into persisting profiler objects to disk, I had several factors that I had to take into account:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Speed in serializing / deserializing. &lt;/li&gt;    &lt;li&gt;Ability to intervene in the serialization process at a deep level. &lt;/li&gt;    &lt;li&gt;Size (also effect speed). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The first two are pretty obvious, but the third requires some explanation. The issue is, quite simply, that I can apply some strategies to significantly reduce both speed &amp;amp; size of serialization by making sure that the serialization pipeline knows exactly what is going on (string tables &amp;amp; flyweight objects).&lt;/p&gt;  &lt;p&gt;I started looking into the standard .NET serialization pipeline, but that was quickly ruled out. There are several reasons for that, first, you literally cannot hook deep enough into the serialization pipeline to do the sort of things that I wanted to do (you cannot override how System.String get persisted), and it is &lt;em&gt;far&lt;/em&gt; too slow for my usages.&lt;/p&gt;  &lt;p&gt;My test data started as a ~900Mb of messages, which I loaded into the profiler (resulting in a 4 GB footprint during processing and a 1.5GB footprint when processing is done). Persisting the in memory objects using BinaryFormatter resulted in a file whose size is 454Mb and whose deserialization I started before I started writing this post and at this point in time has not completed yet. Currently the application (simple cmd line test app that only does deserialization, takes 1.4 GB).&lt;/p&gt;  &lt;p&gt;So that was utterly out. So I set out to write my own serialization format. Since I wanted it to be fast, I couldn’t use reflection, (BF app currently takes 1.6 GB) but by the same token, writing serialization by hand is labor intensive, error prone method. That lives aside the question of handling changes in the objects down the road, that is &lt;em&gt;not&lt;/em&gt; something that I would like to do.&lt;/p&gt;  &lt;p&gt;Having come to that conclusion, I decided to make use of CodeDOM to generate a serialization assembly on the fly. That would give me the benefits of no reflection, handle addition of new members to the serialized objects and would allow me to incrementally improve how (BF app now takes 2.2 GB, and I am getting ready to kill it). My first attempt in doing so, applying absolutely not optimization techniques, result in a 381 Mb file and an 8 seconds parsing time.&lt;/p&gt;  &lt;p&gt;That is pretty good, but I wanted to do a bit more. &lt;/p&gt;  &lt;p&gt;Now, note that this is an implementation specific for a single use. After applying a simple string table optimization, the results of the serialization are two files, the string table is 10Mb in length and the actual saved data is 215Mb and de-serialization takes ~10 seconds. Taking a look at what actually happened, it looked like the cost of maintaining string table is quite high. Since I care more about responsiveness than file size, and since the code for maintaining the string table is complex, I dropped that in favor of in memory only MRU string interning.&lt;/p&gt;  &lt;p&gt;Initial testing shows that this should be quite efficient in reducing memory usage. In fact, in my test scenario, memory consumption during processing dropped down 4 GB to just 1.8 – 1.9 GB and 1.2 GB when processing is completed. And just using the application shows that the user level performance is &lt;em&gt;pretty&lt;/em&gt; good, even if I say so myself.&lt;/p&gt;  &lt;p&gt;There are additional options that I intend to take, but I’ll talk about them in a later post.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11259.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2009/12/29/fighting-the-profiler-memory-obesity.aspx</guid>
            <pubDate>Tue, 29 Dec 2009 10:00:00 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2009/12/29/fighting-the-profiler-memory-obesity.aspx#feedback</comments>
            <slash:comments>18</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11259.aspx</wfw:commentRss>
        </item>
        <item>
            <title>How would you learn a new platform?</title>
            <link>http://ayende.com/Blog/archive/2009/11/23/how-would-you-learn-a-new-platform.aspx</link>
            <description>&lt;p&gt;Here is an interesting problem that I am facing. I have a pretty good working knowledge of computing, and while I can usually manage to get the gist of a new technology in a short amount of time, that is only useful for talking about it, not actually applying that. I am currently trying to figure out the parts where I am missing, and plug the holes. And I am running into a bit of a problem here.&lt;/p&gt;  &lt;p&gt;A case in point, I can &lt;em&gt;read&lt;/em&gt; Java, and I can probably write C# code in Java, but I can’t write a Java application. Not for lack of technical skills, but just because I lack the practical knowledge on how to do so.  The problem is that it is going to take too long for me to slog through everything myself, especially since my main problems are in things like IDEs and usage patterns, which aren’t really stuff that you learn from reading about it.&lt;/p&gt;  &lt;p&gt;I am thinking on taking a Java course, not so much for the content of the course, as the ability to actually build Java apps in an environment where I can ask questions. On the other hand, picking the right course is problematic, I am &lt;em&gt;not&lt;/em&gt; going to sit through “this is a for loop", but I don’t want to be the guy with the blank stare.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11218.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2009/11/23/how-would-you-learn-a-new-platform.aspx</guid>
            <pubDate>Mon, 23 Nov 2009 10:00:00 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2009/11/23/how-would-you-learn-a-new-platform.aspx#feedback</comments>
            <slash:comments>46</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11218.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Reducing friction as a standard operating method</title>
            <link>http://ayende.com/Blog/archive/2009/11/18/reducing-friction-as-a-standard-operating-method.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Reducingfrictionasastandardoperatingmeth_13EBA/image_14.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Reducingfrictionasastandardoperatingmeth_13EBA/image_thumb_6.png" width="294" height="199" /&gt;&lt;/a&gt; One of the things that I am &lt;em&gt;really&lt;/em&gt; sensitive for is friction. And anytime that I run into that, I am doing an evaluation about how much it is going to cost to remove that. Thee are two sides for this evaluation. There is the pure monetary/time side, and then there is the pure opportunities lost side.&lt;/p&gt;  &lt;p&gt;The usual evaluation is “it takes 3 minutes to do so manually, and would take a week to resolve in an automatic way”, assuming a standard 40 hours week, we would need to do something for 800 times before it make sense resolve that automatically. &lt;/p&gt;  &lt;p&gt;The problem is ignoring the opportunities lost angle. One of the things that most people do not usually consider is that we tend to avoid things that are painful. &lt;/p&gt;  &lt;p&gt;If adding content to a website requires you to commit changes to SVN and then log in to a server and update the site, that is about 3 additional minutes that you topped to something that is probably pretty minor. If you are on a slow connection, those can be pretty &lt;em&gt;frustrating&lt;/em&gt; 3 minutes. That means that editing the site get batched, so a lot of minor edits are bundled together, until the 3 minutes overhead become insignificant. That means that the site gets updated less often.&lt;/p&gt;  &lt;p&gt;If maintaining two profiles of the same application requires that you would merge between slightly different branches (a pretty painful process), they are &lt;em&gt;not&lt;/em&gt; going to be in sync. Building a way which allows a single codebase development for multiple profiles is a pretty significant investment, on the other hand. And it introduce complexity into the software.&lt;/p&gt;  &lt;p&gt;If committing is going to hit a network resource (and thus take a bit longer), you are going to commit less often. If branching… but you get the point, don’t you?&lt;/p&gt;  &lt;p&gt;If releasing your software is a manual process (even to the point of just promoting a CI build to release status), you aren’t going to release very often. &lt;/p&gt;  &lt;p&gt;Those are just a few recent examples that I have run to where friction was the deciding factor. In all cases, I put in the time to reduce the friction to the lowest possible level. What I usually look for is the opportunities lost cost, because those tend to be pretty significant. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Reducingfrictionasastandardoperatingmeth_13EBA/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Reducingfrictionasastandardoperatingmeth_13EBA/image_thumb_3.png" width="301" height="224" /&gt;&lt;/a&gt; I don’t &lt;em&gt;think&lt;/em&gt; about releasing the profiler versions, and I released 20 times in the last three days (5 different builds, times 4 different profiles). The build process for the profiler had me write several custom tools (including my own bloody CI server, for crying out load, a daily build site, upload and registration tools, etc). That decision has justified itself a hundred times over, by ensuring that &lt;em&gt;my&lt;/em&gt; work isn’t being hampered by release management, and it a very rapid turn around for releases.&lt;/p&gt;  &lt;p&gt;That, in turn, means that we get a lot more confidence from customers (we had a problem and it was resolved in 2 hours). There is actually a separate problem here, that we release &lt;em&gt;too&lt;/em&gt; often, but I consider that a better alternative than slow response times for customers.&lt;/p&gt;  &lt;p&gt;Supporting Linq to Sql as a second target in NH Prof was something that we could do in three days flat. In practice, it took over a month to get to a position where we could properly release it. The time difference was dedicated to doing it &lt;em&gt;right&lt;/em&gt;. And no, I am not talking about architectural beauty, or any such thing.&lt;/p&gt;  &lt;p&gt;The three days target time for Linq to SQL implies branching the code base and simply making the changes inline. There is relatively very little change from the NH Prof version, and we could just make it all work in a short amount of time. &lt;/p&gt;  &lt;p&gt;I am talking about doing it in a way that introduce no additional friction to our work. Right now I am supporting 4 different profiles (NHibernate, Hibernate, Linq to SQL, Entity Framework), and in my wild dreams I am thinking of having 10 or more(!). Frictionless processes means that the additional cost of support each new profile is vastly reduced. &lt;/p&gt;  &lt;p&gt;Having different branches for different profiles was considered and almost immediately rejected, it would introduce too much friction, confusion and pain into the development process. Instead, we went with the route on having a single code base that is being branched automatically by the build process. It means that we have a slightly more complex infrastructure, but it also means that we can do it once and touch it only very rarely.&lt;/p&gt;  &lt;p&gt;Does it pay off? I would say it does just in terms of not having to consider merging between the different branches whenever I make a change or a bug fix. But it is more than that.&lt;/p&gt;  &lt;p&gt;A week ago I didn’t have the Entity Framework Profiler, today it is in a private beta, and in a week or two it is going to go to public beta. All that time spent on integrating Linq to SQL paid itself off when we could just plug in a new profile without really thinking about it.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11211.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2009/11/18/reducing-friction-as-a-standard-operating-method.aspx</guid>
            <pubDate>Wed, 18 Nov 2009 10:00:00 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2009/11/18/reducing-friction-as-a-standard-operating-method.aspx#feedback</comments>
            <slash:comments>12</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11211.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Answering YAGNI commentary</title>
            <link>http://ayende.com/Blog/archive/2009/11/09/answering-yagni-commentary.aspx</link>
            <description>&lt;p&gt;My post about &lt;a href="http://ayende.com/Blog/archive/2009/11/04/applying-yagni-in-impleo.aspx"&gt;applying YAGNI in Impleo&lt;/a&gt; has gotten a lot of comments, and instead of answering them one at a time, I think it would be useful to just have a post answering all of them together.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Ryan Riley: &lt;/strong&gt;I suppose I'm still wondering, how did WebForms appear as a result of YAGNI? I realize that's the original &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; platform, but MVC seems simpler to me, and even simpler would be starting with HTML, CSS, and JavaScript (or, heaven forbid, classic ASP) with some AJAX.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Ryan, it is quite simple. It is all about friction, using HTML, CSS &amp;amp; Javascript would have added more friction initially than the webforms solution.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Torkel: &lt;/strong&gt;Any plans to open source it?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Highly unlikely.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Andrew:&lt;/strong&gt; I know we all hate Web Forms, yada yada yada, but if you need to just setup a few pages, it's dead easy and much faster than MVC, a WCF service or any other method to deliver content.  Hence why it makes perfect sense in this "I'm using YAGNI to the letter of the law" experiment.      &lt;br /&gt;But the reality is, you rarely have a project where you can work in this pure YAGNI way, since there almost always is requirements such as make it testible, make it easy to maintain, make it SOE friendly, etc. so working in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; Webforms a poor choice for the job.  But there does come a time where a project is "All we need is one page that shows data in a grid", it can be done in literally 10 minutes with a WebForm.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I agree, except that there is an additional thing that I want to bring to the table. The most important thing for me in most of my apps is the first customer demo. That is important for a host of reasons, but most importantly, because it make a product &lt;em&gt;real&lt;/em&gt;. Building fancy architecture and buzzward compliant development is usually in the way of that. The first customer demo is simple, stupid and should be out as soon as possible.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Dmitriy Nagirnyak: &lt;/strong&gt; &lt;/p&gt;    &lt;p&gt;Your own website framework?     &lt;br /&gt;Hmm.      &lt;br /&gt;What are the reason for starting it from scratch if there are some of them already available?      &lt;br /&gt;- Exercise?      &lt;br /&gt;- Lack of extensibility?      &lt;br /&gt;- Wrong architecture?      &lt;br /&gt;- "Just want my own" thing?      &lt;br /&gt;- others?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Quite simple, I wanted something that would work the way I need it to work. Anything that adds friction to the process is not acceptable. I am willing to build my own thing to get a friction free process.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Richard Dingwall: &lt;/strong&gt;Article starts with YAGNI and ends up writing a whole new CMS from scratch! Ayende!!&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;See previous reply.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11201.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2009/11/09/answering-yagni-commentary.aspx</guid>
            <pubDate>Mon, 09 Nov 2009 18:49:00 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2009/11/09/answering-yagni-commentary.aspx#feedback</comments>
            <slash:comments>9</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11201.aspx</wfw:commentRss>
        </item>
        <item>
            <title>What kind of logging should you do in production?</title>
            <link>http://ayende.com/Blog/archive/2009/11/02/what-kind-of-logging-should-you-do-in-production.aspx</link>
            <description>&lt;p&gt;That really depends on the type of application that you write and what kind of operations team it is going to have.&lt;/p&gt;  &lt;p&gt;I have applications that I setup, then forget about (this blog being one of them). In those types of applications, having a log in production is a burden, I need to purge it occasionally, or write the code to purge it automatically. &lt;/p&gt;  &lt;p&gt;Then I have applications that have a strong operations team, where people are looking at the application every single day. An alert raised from the system is actually going to be looked at by a human before irate customers start calling. In those cases, a lot is pretty important, and understanding how to properly distinguish between real errors (human needs to look at) and transient ones (do a review once a month) is pretty important.&lt;/p&gt;  &lt;p&gt;Setting things up is that I have production sites log only error conditions, which is pretty common, is also a mistake, as a simple example, I had once seen a log that where 40% of the errors where users coming back to the site after the session has timed out, and the error was leading them to the error page.&lt;/p&gt;  &lt;p&gt;The way I try to do things is:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Pay attention to messages that arrive to the error queue, see if there is anything that can be done about them.&lt;/li&gt;    &lt;li&gt;Log &amp;amp; alert any time that an error crosses the system boundary (if the users see an error page, I really want to know about it).&lt;/li&gt;    &lt;li&gt;Setup things so I can change log levels in productions without restarting / redeployment, etc.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Please note that I am making a distinction here between developer’s log and audit trails or operations information. Depending on the type of system that you have, and the requirements on it, those two can be a gold mine when trying to troubleshoot issues.&lt;/p&gt;  &lt;p&gt;Providing things like performance counters or access to internal state in your application is also important. For example, being able to ask the app for the worst performing queries is a great way of troubleshooting perf issues. Or querying the cache miss ratios, etc. It isn’t just logging that gives you visibility into the system.&lt;/p&gt;  &lt;p&gt;Something that I haven’t had the chance to do yet (but that I would like to try) is to plug the NH Prof backend (which is basically an event aggregation and analysis system) as a way to analyze log streams. That way, even if you do have some logging turned on, it doesn’t stay in its raw form, but is translated to something much more concise and understandable.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11192.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2009/11/02/what-kind-of-logging-should-you-do-in-production.aspx</guid>
            <pubDate>Mon, 02 Nov 2009 10:00:00 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2009/11/02/what-kind-of-logging-should-you-do-in-production.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11192.aspx</wfw:commentRss>
        </item>
        <item>
            <title>YAGNI, I told them, millennium hand and shrimp!</title>
            <link>http://ayende.com/Blog/archive/2009/10/27/yagni-i-told-them-millennium-hand-and-shrimp.aspx</link>
            <description>&lt;p&gt;I am running a long experiment with myself to see whatever you are gonna need YAGNI.&lt;/p&gt;  &lt;p&gt;So I went way back to this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/YAGNIItoldthemmillenniumhandandshrimp_EB74/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/YAGNIItoldthemmillenniumhandandshrimp_EB74/image_thumb_1.png" width="1023" height="384" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/YAGNIItoldthemmillenniumhandandshrimp_EB74/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/YAGNIItoldthemmillenniumhandandshrimp_EB74/image_thumb.png" width="622" height="266" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is an application that I am explicitly growing organically, only adding things as I really need them. It is working so far.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11182.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2009/10/27/yagni-i-told-them-millennium-hand-and-shrimp.aspx</guid>
            <pubDate>Tue, 27 Oct 2009 10:00:00 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2009/10/27/yagni-i-told-them-millennium-hand-and-shrimp.aspx#feedback</comments>
            <slash:comments>19</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11182.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Do you sign the default contract?</title>
            <link>http://ayende.com/Blog/archive/2009/10/03/do-you-sign-the-default-contract.aspx</link>
            <description>&lt;p&gt;This is just something that came up recently in a mailing list, we were talking about copyright, ownership and such. The topic of who owns the code you write on your own time (and on your own machines) came up.&lt;/p&gt;  &lt;p&gt;The opinion of some people was that the employer may own the code even under those circumstances. It seems that it isn’t usually part of the law (that depend on where you are at, of course), but it is part of standard employment contract templates. &lt;/p&gt;  &lt;p&gt;When I started looking for a job, I insisted on taking the employment contract home and going over it with:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;a calm mind&lt;/li&gt;    &lt;li&gt;having another set of eyes go over it&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I had one case of not properly reading what I was signing on with bad consequences, I learned since then.&lt;/p&gt;  &lt;p&gt;There is no such thing as a standard contract, you can &lt;em&gt;always&lt;/em&gt; negotiate. &lt;/p&gt;  &lt;p&gt;For that matter, I rejected an offer from one place after verbal agreements that we reached didn’t get into the contract (twice!). I decided that if they were trying to effectively cheat me when I wasn’t even working for them, I had better things to do than to put my head into this sickbed.&lt;/p&gt;  &lt;p&gt;Some of the things that I found in employment contracts are of the sort that would make your head curl. Non compete agreements that basically say that you are not allowed to do &lt;em&gt;any&lt;/em&gt; work (for anyone) for 2 years after you stop working for the company. Ownership on anything you do (be in software artifacts, a book about flowers and quite possibly any children you have during your employment terms).&lt;/p&gt;  &lt;p&gt;Some of them are unenforceable at court, but you would be at a much better position if you didn’t have to deal with annoying section in a contract that you are signed on in the first place.&lt;/p&gt;  &lt;p&gt;My usual approach to reading contracts is to debug them, assuming that the other side is nefarious, evil, double dealing and likes kicking puppies before breakfast. Most places will go with the “Try and you shall succeed” method for contracts. If you signed on to them without complaints, they are good. If you object to something, they can amend the contract to be more reasonable. It isn’t that they &lt;em&gt;are&lt;/em&gt; nefarious, or that they even plan to act according to the contract. But it is best if they don’t have any leverage on you.&lt;/p&gt;  &lt;p&gt;An interesting point that I run into is that it is often useful to be bold when negotiating a contract. I deleted the non compete clause for my employment contract when I viewed it, and required a &lt;em&gt;lot&lt;/em&gt; of clarifications about what of my work amounts to company’s property. I followed the same logic as they did, “Try and you shall succeed”, if they didn’t care about that, I was good. &lt;/p&gt;  &lt;p&gt;We ended up with a 1 year limitation for clients that they sent me to, and agreeing that any software work that I am making on the company’s time or using their equipment belong to the company, which I considered reasonable. &lt;/p&gt;  &lt;p&gt;Not reading the contract is a crime, once you did, be very careful in deciding what is acceptable and what isn’t. And if you are already signed on a contract, make sure that you &lt;em&gt;know&lt;/em&gt; what is in it.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11131.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2009/10/03/do-you-sign-the-default-contract.aspx</guid>
            <pubDate>Fri, 02 Oct 2009 22:32:00 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2009/10/03/do-you-sign-the-default-contract.aspx#feedback</comments>
            <slash:comments>19</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11131.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>