<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>3ft9</title>
	
	<link>http://3ft9.com</link>
	<description>software development, web development and IT consultancy</description>
	<lastBuildDate>Sat, 05 May 2012 18:28:40 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/3ft9" /><feedburner:info uri="3ft9" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Another URL shortener bites the dust</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/LUSDM3ow-e8/216-another-url-shortener-bites-the-dust</link>
		<comments>http://3ft9.com/216-another-url-shortener-bites-the-dust#comments</comments>
		<pubDate>Sat, 05 May 2012 18:27:40 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=216</guid>
		<description><![CDATA[I&#8217;ve decided to take jmp.li down. The code behind it is open source, and I&#8217;m open to offers for the domain name. Existing short URLs will continue to resolve for a while but I don&#8217;t plan to do any more maintenance on the site. Why? It&#8217;s mostly being used for spam and porn URLs, and [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve decided to take <a href="http://jmp.li/">jmp.li</a> down. The <a href="https://github.com/3ft9/shurly">code behind it is open source</a>, and I&#8217;m open to offers for the domain name. Existing short URLs will continue to resolve for a while but I don&#8217;t plan to do any more maintenance on the site.</p>
<p>Why? It&#8217;s mostly being used for spam and porn URLs, and that&#8217;s not a service I want to provide. I have no interest in marketing the service to compete with the likes of tinyurl.com, bit.ly and the other established sites.</p>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/LUSDM3ow-e8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/216-another-url-shortener-bites-the-dust/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/216-another-url-shortener-bites-the-dust</feedburner:origLink></item>
		<item>
		<title>Rackspace CloudFiles plugin for Jekyll</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/SI9Sm9PM2Ac/210-rackspace-cloudfiles-plugin-for-jekyll</link>
		<comments>http://3ft9.com/210-rackspace-cloudfiles-plugin-for-jekyll#comments</comments>
		<pubDate>Tue, 27 Sep 2011 01:12:48 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[cloudfiles]]></category>
		<category><![CDATA[rackspace]]></category>
		<category><![CDATA[rackspacecloud]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=210</guid>
		<description><![CDATA[As part of my ongoing conversion from dynamic to static sites using Jekyll, a requirement recently came up to put all static files on the Rackspace CloudFiles service via their CDN integration. The logical solution to this was to write a plugin. I looked at several ways of doing this, but the best way appeared [...]]]></description>
				<content:encoded><![CDATA[<p>As part of my ongoing conversion from dynamic to static sites using <a title="Static site generator from GitHub" href="http://jekyllrb.com/">Jekyll</a>, a requirement recently came up to put all static files on the <a title="Rackspace CloudFiles" href="http://www.rackspacecloud.com/2148-0-3-13.html">Rackspace CloudFiles</a> service via their <a title="Rackspace CloudFiles" href="http://www.rackspacecloud.com/2148-0-3-13.html">CDN integration</a>. The logical solution to this was to write a plugin.</p>
<p>I looked at several ways of doing this, but the best way appeared to be adding a tag to the Liquid templating system. <a title="Rackspace CloudFiles plugin for Jekyll" href="https://github.com/3ft9/jekyll-rackspacecloudfiles">The plugin is up on GitHub</a> and should be pretty simple to use. I&#8217;m currently using it on one site I&#8217;m developing but expect to be using it on a few more over the next few months.</p>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/SI9Sm9PM2Ac" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/210-rackspace-cloudfiles-plugin-for-jekyll/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/210-rackspace-cloudfiles-plugin-for-jekyll</feedburner:origLink></item>
		<item>
		<title>Introducing FURL</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/Wiw2Bf-7Vfs/194-introducing-furl</link>
		<comments>http://3ft9.com/194-introducing-furl#comments</comments>
		<pubDate>Fri, 05 Aug 2011 22:30:46 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=194</guid>
		<description><![CDATA[A couple of hours ago I needed a break from the project I&#8217;m currently working on, so decided to flex my Node.js muscles again. This time I&#8217;ve developed a really simple but useful server that presents a simple API for resolving short URLs to their final destination. You can find it on GitHub: https://github.com/3ft9/furl Here&#8217;s [...]]]></description>
				<content:encoded><![CDATA[<p>A couple of hours ago I needed a break from the project I&#8217;m currently working on, so decided to flex my Node.js muscles again. This time I&#8217;ve developed a really simple but useful server that presents a simple API for resolving short URLs to their final destination.</p>
<p>You can find it on <a href="http://github.com/3ft9">GitHub</a>: <a href="https://github.com/3ft9/furl">https://github.com/3ft9/furl</a></p>
<p>Here&#8217;s the README file&#8230;</p>
<blockquote>
<h3>FURL</h3>
<p>FURL is a service written in Node.js to provide an HTTP API for resolving short URLs.</p>
<p>The service is running at <a href="http://furl.li/">http://furl.li/</a> so feel free to have a play, but please don&#8217;t hammer it! Try: <a href="http://furl.li/http://is.gd/w">http://furl.li/http://is.gd/w</a></p>
<p>It&#8217;s highly recommended that this is run behind a mature web server such as nginx &#8211; this is advice from the creator of Node so pay attention Bond!</p>
<h3>Configuration</h3>
<ul>
<li>All configurable variables are at the top of the source file.</li>
</ul>
<h3>Usage</h3>
<ul>
<li>Call / and it will return the destination URL. If an error occurs it will return a message starting with ERR.</li>
<li>Call it with /stats to get a JSON response containing various stats.</li>
<li>Call it with /clean to trigger a cache cleaning operation. This will return the number of objects deleted during the clean.</li>
</ul>
<h3>TODO</h3>
<ul>
<li>Move the configuration out to a conf file.</li>
<li>Add the ability to have an hourly per-IP limit to prevent abuse.</li>
<li>Add the option of using a memcached instance for the cache so it can be shared across multiple instances of the daemon behind a load balancer.</li>
<li>I&#8217;ve not really stress-tested it yet, but the tests I have done show it to be pretty stable.</li>
</ul>
</blockquote>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/Wiw2Bf-7Vfs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/194-introducing-furl/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/194-introducing-furl</feedburner:origLink></item>
		<item>
		<title>Rackspace CloudFiles Uploader</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/rFIhg7ZKzBE/188-rackspace-cloudfiles-uploader-script</link>
		<comments>http://3ft9.com/188-rackspace-cloudfiles-uploader-script#comments</comments>
		<pubDate>Sat, 19 Mar 2011 22:58:37 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[cloudfiles]]></category>
		<category><![CDATA[rackspace]]></category>
		<category><![CDATA[rackspacecloud]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=188</guid>
		<description><![CDATA[I&#8217;ve recently been transferring a lot of my sites and server-based services over to RackspaceCloud, and part of this meant uploading a fairly large number of files to the CloudFiles service. The web interface sucks for more than a few files so I knocked up this quick script to make it easier. It has already [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve recently been transferring a lot of my sites and server-based services over to <a href="http://www.rackspacecloud.com/2148-0-3-13.html">RackspaceCloud</a>, and part of this meant uploading a fairly large number of files to the CloudFiles service. The web interface sucks for more than a few files so I knocked up <a href="https://github.com/3ft9/CloudFiles-Uploader">this quick script</a> to make it easier. It has already saved me a ton of time so I thought it worth sharing.</p>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/rFIhg7ZKzBE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/188-rackspace-cloudfiles-uploader-script/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/188-rackspace-cloudfiles-uploader-script</feedburner:origLink></item>
		<item>
		<title>Twitter TOS changes</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/Zhh58dINxX4/186-twitter-tos-changes</link>
		<comments>http://3ft9.com/186-twitter-tos-changes#comments</comments>
		<pubDate>Sun, 13 Mar 2011 18:20:11 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=186</guid>
		<description><![CDATA[Twitter have recently changed the terms of service for their API and it&#8217;s caused uproar in the development community. I&#8217;ve written up my analysis over on Stut.net.]]></description>
				<content:encoded><![CDATA[<p>Twitter have recently changed the terms of service for their API and it&#8217;s caused uproar in the development community. I&#8217;ve <a href="http://stut.net/2011/03/13/twitter-tos-changes/">written up my analysis</a> over on <a href="http://stut.net/">Stut.net</a>.</p>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/Zhh58dINxX4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/186-twitter-tos-changes/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/186-twitter-tos-changes</feedburner:origLink></item>
		<item>
		<title>Stutbot</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/85_EQDGM930/178-stutbot</link>
		<comments>http://3ft9.com/178-stutbot#comments</comments>
		<pubDate>Sun, 13 Mar 2011 07:34:38 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=178</guid>
		<description><![CDATA[In a past life I ran an IRC server that formed part of a private chat network, and off the back of that I had developed an IRC bot called Stutbot. One of my clients recently informed me that they want to set up an IRC server to facilitate realtime communication between their remote developers, [...]]]></description>
				<content:encoded><![CDATA[<p>In a past life I ran an IRC server that formed part of a private chat network, and off the back of that I had developed an IRC bot called Stutbot. One of my clients recently informed me that they want to set up an IRC server to facilitate realtime communication between their remote developers, with some status information being squirted in from various sources. This occurred to me as an ideal opportunity to revive and update that project.</p>
<p><span id="more-178"></span>Stutbot has been through many rewrites since the first version. Initially he was written in PHP, the I rewrote him in C++, and most recently Python. Continuing that tradition I have started rewriting him again, in <a href="http://nodejs.org/">node.js</a>.</p>
<p>As always the code is <a href="https://github.com/3ft9/stutbot">up on our github account</a>.</p>
<p>The project has always supported a plugin architecture in al of its implementations and I was excited to see what node had to offer in this regard. After a number of iterations the final architecture is broadly similar to the original PHP implementation, with the added bonus that you can reload the plugins on the fly &#8212; or you could if I hadn&#8217;t broken that earlier today!</p>
<p>So far I&#8217;ve not implemented many of the plugins the previous versions have supported, but now the architecture is there it&#8217;s fairly trivial to extend. Stutbot can currently do the following&#8230;</p>
<ul>
<li>Be a magic 8-ball</li>
<li>Tell you the date and time</li>
<li>Dance, but not boogie</li>
<li>Respond to a ping</li>
<li>Play hangman</li>
</ul>
<p>It&#8217;s the last of these that I&#8217;ve spent most time on. Games are started via a private message, and there can only be one game per channel at any one time. The current state of the games is persisted across bot restarts. I chose to focus on this plugin because it demonstrates how to use most of the bot features.</p>
<p>I&#8217;m currently working on an <a href="http://www.unfuddle.com/">Unfuddle</a> plugin which will allow the developers to get info on their project without needing to load the web interface. I&#8217;m also hoping I can hook into Unfuddle&#8217;s support for callback URLs on git repositories, so Stutbot can post commit messages to an IRC channel.</p>
<p>Beyond that I have a list of plugins I&#8217;ve previously implemented in other languages that I will build as and when the need or desire arises.</p>
<p>Is there anything you&#8217;d want an IRC bot in your dev channel to be capable of?</p>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/85_EQDGM930" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/178-stutbot/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/178-stutbot</feedburner:origLink></item>
		<item>
		<title>Shurly</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/eQxrn-EzZ9I/168-shurly</link>
		<comments>http://3ft9.com/168-shurly#comments</comments>
		<pubDate>Wed, 09 Mar 2011 05:00:04 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=168</guid>
		<description><![CDATA[I&#8217;ve recently been looking at Node.js with a view to using it on a few projects I have in mind. This evening I have finished my first Node project, and I thought I&#8217;d tell you all about it. Node is an &#8220;Evented I/O platform for V8 JavaScript&#8221;. It&#8217;s server-side JavaScript. The thought of that initially [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve recently been looking at <a href="http://nodejs.org/">Node.js</a> with a view to using it on a few projects I have in mind. This evening I have finished my first Node project, and I thought I&#8217;d tell you all about it.</p>
<p>Node is an &#8220;Evented I/O platform for V8 JavaScript&#8221;. It&#8217;s server-side JavaScript. The thought of that initially made me nervous, but I soon realised that there&#8217;s no reason for JS to be limited to the client-side. This is the same mental block that makes many people believe PHP should only be used for building web pages when it&#8217;s more than capable of performing many other roles.</p>
<p>The core concept behind Node is to ensure that nothing blocks. What this means in practice is lots of callbacks and a very thoughtful development process. It was interesting to see my approach to writing code changing such that whether it would block was foremost on my mind.</p>
<p>In order to get to know Node better I decided to rewrite <a href="http://jmp.li/">JMP.LI</a>. I&#8217;ve <a href="https://github.com/3ft9/shurly">pushed the code up to our github account</a> and called it Shurly (insert Airplane jokes here).</p>
<p><span id="more-168"></span>The current service is implemented in PHP and uses a simple disk-based key-value store. It uses no other libraries beyond PHP and runs to about 400 lines of code not including templates. To match this environment I have not used any external libraries save for a module to access MongoDB. Not including templates, the Node version runs to around 600 lines of code.</p>
<p>I normally work very hard to ensure code reuse and elegant design, but given that one of my primary goals was to build a fast service I have made sacrifices in that area. Two things I definitely wanted to retain was some sort of simple templating and the ability to use different data storage backends with minimum fuss. I managed to include both while retaining decent performance.</p>
<h3>Templates</h3>
<p>There were two issues with performance with the templates. The first is having to load the templates from disk every time they are needed. This was easily solved by preloading them into variables during startup.</p>
<p>I initially had the files being loaded in sequence, with the callback for each triggering the next. The callback for the final file then kicked off the data initialisation. This only happens at startup so I decided to simplify the code and allow the data module to initialise while the files were being loaded. This leaves a very small chance that upon restart people might get served a page containing the default text, like this:</p>
<blockquote>
<pre>Loading...Loading...Loading</pre>
</blockquote>
<p>They&#8217;d see it three times, once for each of the header, index and footer templates. The window of risk, however, is extremely tiny.</p>
<p>The replacements in the templates are handled by simply replacing all instances of %%var%% with the variable value. Templating at its simplest!</p>
<h3>Data providers</h3>
<p>The other thing I wanted to include was changeable data providers. This was not rocket science and simply loads the module specified in the configuration file. If a module exports a variable called data which implements init, shortenURL and get and they do the same job as the existing MongoDB module, everything will work fine.</p>
<p>The one major compromise I had to make is to have the data module actually generate the next short URL. While not the end of the world this doesn&#8217;t sit right with my brain. I could have used a callback to have the main code do it, but this seemed like even more ugly so I&#8217;ve left it as it is.</p>
<p>The main reason for this is that the data module, by necessity, handles the atomic selection of the next short URL to be used. The fact that the current implementation is not actually atomic is neither here nor there; it should be! I can live with it until I can come up with something better.</p>
<h3>Summary</h3>
<p>Hopefully I&#8217;ll get some time to do a bit more testing on this code, iron out some rough edges, and make it production-ready. If I do then I&#8217;ll definitely consider putting it in to replace the existing JMP.LI backend.</p>
<p>I also want to implement a MySQL data provider that optionally uses memcache to cache keys. It would also be interesting to experiment with adding a simple, internal cache to the Mongo provider to save round-trips to the server, where it would also queue up updates to the hit stats and use periodic batch writes instead of doing it on-the-fly. I also want to sort the race condition in that module which means figuring out how to execute an increment operation using the mongo driver.</p>
<p>So that&#8217;s that. Another late night of writing code all in the name of learning comes to an end. Fun.</p>
<p>No, seriously&#8230; FUN!</p>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/eQxrn-EzZ9I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/168-shurly/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/168-shurly</feedburner:origLink></item>
		<item>
		<title>New year, new site</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/RZWxCmDY4KM/166-new-year-new-site</link>
		<comments>http://3ft9.com/166-new-year-new-site#comments</comments>
		<pubDate>Tue, 08 Mar 2011 13:15:29 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=166</guid>
		<description><![CDATA[Yes, I know it&#8217;s March now, but we&#8217;ve been busy! This new design replaces an off-the-shelf site that didn&#8217;t in any way reflect the nature and ethos of the company. This new site is completely different, and we hope you like it. There are a few more changes yet to be made, but the old [...]]]></description>
				<content:encoded><![CDATA[<p>Yes, I know it&#8217;s March now, but we&#8217;ve been busy! <img src='http://3ft9.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>This new design replaces an off-the-shelf site that didn&#8217;t in any way reflect the nature and ethos of the company. This new site is completely different, and we hope you like it. There are a few more changes yet to be made, but the old site was depressing us so we pushed this out as soon as we could.</p>
<p>Let us know what you think.</p>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/RZWxCmDY4KM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/166-new-year-new-site/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/166-new-year-new-site</feedburner:origLink></item>
		<item>
		<title>TwitApps on 37signals’ blog</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/MLcZsumOQ-A/84-twitapps-on-37signals-blog</link>
		<comments>http://3ft9.com/84-twitapps-on-37signals-blog#comments</comments>
		<pubDate>Tue, 07 Dec 2010 14:44:35 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=84</guid>
		<description><![CDATA[I was recently asked to answer a few questions for the 37signals&#8217; blog, Signal vs. Noise, and it just went live. The post summarises the reasons a number of startups are no longer around. I never really considered TwitApps to be a startup, but I was honoured that Matt wanted to include it in the [...]]]></description>
				<content:encoded><![CDATA[<p>I was recently asked to answer a few questions for the 37signals&#8217; blog, <a href="http://37signals.com/svn/">Signal vs. Noise</a>, and it just <a href="http://37signals.com/svn/posts/2682-the-creators-of-no-longer-with-us-products-explain-what-went-wrong">went live</a>.</p>
<p>The post summarises the reasons a number of startups are no longer around. I never really considered TwitApps to be a startup, but I was honoured that Matt wanted to include it in the post.</p>
<p>Matt didn&#8217;t use all of my answers to his questions, so in case anyone&#8217;s interested I thought I&#8217;d post them here.</p>
<p><span id="more-84"></span><strong>Why didn&#8217;t TwitApps take off the way you hoped? Or did it?</strong></p>
<p>It did, far more so than I&#8217;d hoped. When I shut the service down there were over 4000 active users and was growing every day.</p>
<p><strong>If you had it to do over again, what would you do differently?</strong></p>
<p>I wrote TwitApps Replies in response to Twply (see <a href="http://techcrunch.com/2009/01/01/the-problem-with-twply-is-you-cant-turn-it-off/">here</a> and <a href="http://techcrunch.com/2009/01/02/a-much-cleaner-way-to-get-those-twitter-messages-to-your-email/">here</a> for more info).</p>
<p>It was a technical exercise for me, not an attempt to create a product. The second tool, TwitApps Follows, was written in response to the bad press Qwitter was getting for being unreliable and essentially useless. I considered the whole thing to be a toy project for a long time and it took me a while to realise that people were starting to rely on the service.</p>
<p>So what I&#8217;d do differently is to either treat it like a proper product from day one, or make it clear to users that it was just a toy and should be used as such. A lot of the code I write outside of paid work comes under the heading of toys or technical exercises, and it&#8217;s rare that any of them gain the number of users TwitApps was fortunate to attain a relatively large number of users in a fairly short amount of time but it definitely taught me to be more careful in future.</p>
<p><strong>Other lessons you learned?</strong></p>
<p>Once you&#8217;ve established a free service, and that service has other free competition, it&#8217;s very difficult to monetise it.</p>
<p>It&#8217;s not easy to come up with unique features for something as simple as a notification service for new replies and follower changes.</p>
<p>It&#8217;s also very hard to change people&#8217;s impression of what something is once they&#8217;ve decided for themselves.</p>
<p><strong>Why did you grow tired of developing for the API?</strong></p>
<p>There were a couple of reasons, the first of which was the constantly changing rules. I developed TwitApps during a period of great change in the API, especially around the social graph parts. Keeping up with the changes, both in the API and in the access policies, made maintenance of the tools fairly intensive for a toy project.</p>
<p>It became difficult to juggle the time demands of supporting TwitApps with the requirements of a full time job, several contracts and the need for downtime. In the end something had to go and it was clearly going to be the bit that wasn&#8217;t earning any money.</p>
<p><strong>What advice do you have for those considering starting a startup?</strong></p>
<p>Make sure you know what you&#8217;re getting into, and what commitment your users are going to expect from you in terms of continued service.</p>
<p>If you want press coverage, do something worth being covered. The original version of TwitApps Replies was written in about 4 hours following my reading a post on TechCrunch about Twply. Once completed I emailed them to let them know it existed, and because it was a hot topic that day they covered it. If what you&#8217;re doing is not noteworthy don&#8217;t expect anyone to note it!</p>
<p><strong>Anything else surprising/interesting about the whole TwitApps experience?</strong></p>
<p>Twitter is a fantastic service, a platform with awesome potential, and a fundamental conflict between internal goals and the desire to support a rich developer community. I&#8217;m amazed Twitter themselves have not implemented some form of email-based replies notification, and I wouldn&#8217;t be surprised if it arrives at some point in the form of a paid upgrade.</p>
<p>The Follows tool is definitely going to arrive at some point, but probably in a less granular fashion. They have already hinted that follower analytics form a significant part of their upcoming commercial offering.</p>
<p><strong>What do you think is the best way to finance a startup?</strong></p>
<p>Personally I would not take any money from anyone else to start a company, but that&#8217;s probably because I&#8217;m a control freak! Seriously though, I would approach any project from the view that if I start small and prove the concept, then I can develop it further. I&#8217;d wait as long as possible before bringing more cooks into the kitchen than absolutely necessary.</p>
<p><strong>What are you working on now?</strong></p>
<p>Right now I&#8217;m contracting for a number of companies and looking for interesting projects to get involved in. I&#8217;m also working on launching myself as a <a href="http://stuartdallas.com/">professional photographer</a>.</p>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/MLcZsumOQ-A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/84-twitapps-on-37signals-blog/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/84-twitapps-on-37signals-blog</feedburner:origLink></item>
		<item>
		<title>Would you pay for TwitApps?</title>
		<link>http://feedproxy.google.com/~r/3ft9/~3/l3Z3_FVIWLo/21-would-you-pay-for-twitapps</link>
		<comments>http://3ft9.com/21-would-you-pay-for-twitapps#comments</comments>
		<pubDate>Thu, 08 Jul 2010 10:31:11 +0000</pubDate>
		<dc:creator>Stuart</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://3ft9.com/?p=21</guid>
		<description><![CDATA[I&#8217;ve had the same thought running around my head since putting the TwitApps domain names up for sale yesterday&#8230; would people pay for it? The reason I shut it down is because it no longer held any interest for me, but that would change if I could get some meaningful revenue from it. I know [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve had the same thought running around my head since putting the TwitApps domain names up for sale yesterday&#8230; would people pay for it?</p>
<p><span id="more-21"></span>The reason I shut it down is because it no longer held any interest for me, but that would change if I could get some meaningful revenue from it. I know a lot of people really liked the services, and a number of people have said they would be happy to pay for it, so I think it&#8217;s worth gauging the level of interest out there.</p>
<p>So, my proposal is that I get version 2 finished and put the site back up. I charge a monthly fee, let&#8217;s say £5 for arguments sake, and that gives you access to all the tools on the site (currently Replies and Follows). Existing subscribers would automatically get access to new tools I develop for the site.</p>
<p>Please give me your thoughts about this. If there&#8217;s enough interest (enough to pay for the hosting and my time) I&#8217;ll bring it back, better than ever!</p>
<img src="http://feeds.feedburner.com/~r/3ft9/~4/l3Z3_FVIWLo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://3ft9.com/21-would-you-pay-for-twitapps/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://3ft9.com/21-would-you-pay-for-twitapps</feedburner:origLink></item>
	</channel>
</rss>
