<?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:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><description>Here lies the blog of ENTP, a web application development company based in Portland, OR.</description><title>The ENTP Blog</title><generator>Tumblr (3.0; @entpblog)</generator><link>http://blog.entp.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/entp-hoth" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="entp-hoth" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><item><title>From idea to shipped feature in an hour</title><description>&lt;blockquote class="twitter-tweet"&gt;
&lt;p&gt;Sometimes the time between coming up with a kickass feature, having a “product planning meeting”, writing, coding, and shipping, is one hour&lt;/p&gt;
— c3 (@court3nay) &lt;a href="https://twitter.com/court3nay/status/193500392343089152" target="_blank" data-datetime="2012-04-21T00:44:23+00:00"&gt;April 21, 2012&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;While we were trying to scope a new Tender feature, we accidentally stumbled across a very simple and effective UI improvement that we were able to implement, test and deploy in the space of an hour. I figured I could introduce this (very small) feature with the (very short) story of how we built and shipped it.&lt;/p&gt;
&lt;p&gt;The issue was thus: We provide per-queue notification settings for support staff. These only affect whether the staff member in question receives email notifications for a queue. However, these notification settings also represent something else. They’re a list of queues that are important or relevant to a particular staff member. Amazingly, we don’t make use of this information anywhere else! I know!&lt;/p&gt;
&lt;p&gt;As things wound down in the ENTP office a couple of Fridays ago, Courtenay and I became so energized by this discovery. Courtenay immediately pushed his first pass at a topic branch for this feature. I reviewed and staged it. We went over the QA routine ourselves, since everyone else had mostly gone for the weekend. There was some confusion at first because I couldn’t find the right notification settings. This is why I don’t usually do QA. We pressed on, because we are intrepid and we kept the scope very small. We verified that it worked and shipped it to production to see it in action on our own support page.&lt;/p&gt;
&lt;p&gt;Within an hour we had the following simple, new additions:&lt;/p&gt;
&lt;p&gt;&lt;img align="left" alt="My Queues sidebar" height="200" src="https://entp-tender-production.s3.amazonaws.com/blog/my_queues_sidebar.jpg"/&gt;&lt;/p&gt;
&lt;p&gt;From now on when you elect to be notified about a queue, that queue will receive priority in the support dashboard UI under “My Queues”. Since we were keen to get a useful change shipped right away, we didn’t do any more than this for the first pass.&lt;/p&gt;
&lt;p&gt;I’m not going to lie, we were already barfing rainbows over this, so great was our excitement at this easy win. But! There was one very important bit of functionality missing, in my opinion: What I really wanted was the ability to see discussions from all of my queues in the pending view at once. So we took a little more time and added that too.&lt;/p&gt;
&lt;p&gt;&lt;img alt="My Queues filter" src="https://entp-tender-production.s3.amazonaws.com/blog/my_queues_filter.jpg" width="500"/&gt;&lt;/p&gt;
&lt;p&gt;We left ourselves greater leeway on the turnaround for this one, and we were able to get our usual QA approval before shipping. We were even able to pay off some technical debt in related code at the same time! This change has been very important to me personally as I find it to be conducive to my own workflow. It gives me an easy way to check whether any queued discussions that I should know about about are waiting for a response, and nothing else.&lt;/p&gt;
&lt;p&gt;&lt;img height="398" src="https://entp-tender-production.s3.amazonaws.com/blog/barfing-rainbows.jpg" width="491"/&gt;&lt;/p&gt;
&lt;p&gt;Like I said it’s the small things, or maybe we here at ENTP are hopeless workflow nerds. Possibly both.&lt;/p&gt;</description><link>http://blog.entp.com/post/22801868292</link><guid>http://blog.entp.com/post/22801868292</guid><pubDate>Thu, 10 May 2012 15:16:00 -0700</pubDate><category>Tender</category><dc:creator>zenhob</dc:creator></item><item><title>New: JSONP knowledge base API.</title><description>&lt;p&gt;I&amp;#8217;ve just added a callback parameter to our autosuggest json endpoint. This means you can now search your knowledge base from anywhere and integrate the results into your page. Furthermore, because it&amp;#8217;s using the autosuggest, you can plug in a bunch of unrelated words and it will simply find the best match.&lt;/p&gt;
&lt;p&gt;For example, you could parse the contents of your page and automatically suggest the best results for that page from your KB in the sidebar.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the URL:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; http://&lt;em&gt;your&lt;/em&gt;.tenderapp.com/search/autosuggest.json?q=&lt;em&gt;query&lt;/em&gt;&amp;amp;callback=&lt;em&gt;function&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s some sample code to get you started, using a script tag:&lt;/p&gt;
&lt;pre&gt;&amp;lt;script type="text/javascript"&amp;gt; &lt;br/&gt;function kb_search(results){ &lt;br/&gt; $('#results').html(results[0].title); &lt;br/&gt;} &lt;br/&gt;&amp;lt;/script&amp;gt; &lt;br/&gt;&amp;lt;script src="http://monkeys.tenderapp.com/search/autosuggest.json?callback=kb_search&amp;amp;q=how+do+i+find+api+results" defer="true"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;ve written a more complex example, that works with a form and a jQuery jsonp call at  &lt;a href="https://gist.github.com/2417083" title="gist" target="_blank"&gt;this gist&lt;/a&gt;: feel free to fork it and improve it. It attempts to minimize the number of requests sent.&lt;/p&gt;</description><link>http://blog.entp.com/post/21346120269</link><guid>http://blog.entp.com/post/21346120269</guid><pubDate>Wed, 18 Apr 2012 15:38:15 -0700</pubDate><category>tender</category><dc:creator>courtenay3</dc:creator></item><item><title>How to set up and manage your notifications</title><description>&lt;p&gt;Good day to you!&lt;/p&gt;
&lt;p&gt;When creating a new profile in Tender, the email preferences default to notifying the user of changes in the issues/discussions they have participated in (either by creating or commenting on), but you can curate your notifications for any given category or queues that you wish by signing in and going here:  &lt;a href="https://help.tenderapp.com/profile/edit" title="Edit Profile" target="_blank"&gt;&lt;a href="https://help.tenderapp.com/profile/edit" target="_blank"&gt;https://help.tenderapp.com/profile/edit&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Scroll mid-page where you&amp;#8217;ll find &amp;#8220;Email Preferences&amp;#8221; and click as you see fit.  A word to the wise:  choose your notifications wisely, young Jedi. If you get click happy, you may find your email inbox quickly becomes inundated with things you don&amp;#8217;t really care about.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_m1b2oqQSyl1r2rd10.jpg"/&gt;&lt;/p&gt;
&lt;p&gt;Occasionally, users report being spammed by Tender&amp;#8217;s support system.  If this happens, have them check their email preferences before submitting a bug report. If they have any public discussion category notifications set, the user will receive &lt;strong&gt;all&lt;/strong&gt; posts, regardless of their direct involvement in the discussion.&lt;/p&gt;</description><link>http://blog.entp.com/post/21035695569</link><guid>http://blog.entp.com/post/21035695569</guid><pubDate>Fri, 13 Apr 2012 12:16:47 -0700</pubDate><category>tender</category><dc:creator>bemmabobemma</dc:creator></item><item><title>Find all the bugs</title><description>&lt;p&gt;Even before the beginning of a pull request for Lighthouse and Tender, TATFT is enforced. Red, green, refactor as the code is written is excellent but it won&amp;#8217;t catch everything. Scripts are vital but can sometimes lead to complacency. I believe exploratory testing is a great tool in my web application testers tool belt. Unfortunately, it&amp;#8217;s often misunderstood. Here are three common misunderstandings of exploratory testing:&lt;/p&gt;



&lt;p&gt;1. &lt;strong&gt;Testers have to find bugs. Exploratory testing is like a hunting trip and serves no purpose.&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;   The belief that testers *must* find bugs is false. My happiest day is when I go through a pull request the first time and can say &amp;#8220;Ship it!&amp;#8221;. The best exploratory testing is not blind exploring, monkey clicking through the application, but rather thoughtful investigation of the application by someone who knows the code specifications.  &lt;/p&gt;



&lt;p&gt;2. &lt;strong&gt;Exploratory testing is only good right before deploy.&lt;/strong&gt;  &lt;/p&gt;



&lt;p&gt;   Exploratory testing can actually enhance the automated test suite, by finding new uses of the application not already covered by existing tests. I see every bug report as an opportunity to beef up our test scripts.&lt;/p&gt;



&lt;p&gt;3. &lt;strong&gt;Exploratory testing is done without scripts.&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;   The best exploratory testing is based on carefully created scripts, but the wise tester  knows when to stray from the scripts and follow the bug trail where it leads; being careful to track the steps to reproduce the bug in question. &lt;/p&gt;



&lt;p&gt;Although it is very easy to dismiss exploratory testing as an inefficient testing method, most web application users are not as predictable as programmers would hope. Exploratory testing bridges the gap between automated testing and those unpredictable users.&lt;/p&gt;</description><link>http://blog.entp.com/post/20192862925</link><guid>http://blog.entp.com/post/20192862925</guid><pubDate>Fri, 30 Mar 2012 16:12:06 -0700</pubDate><dc:creator>chronicole</dc:creator></item><item><title>Tender updates for March 27th</title><description>&lt;p&gt;Hi everyone,&lt;/p&gt;
&lt;p&gt;So what have we been up to?&lt;/p&gt;
&lt;p&gt;Well for starters, we fixed the spam count: we had quite some fun with this one, and it should now accurately reflect the number of messages in your spam folder.&lt;/p&gt;
&lt;p&gt;We also added a couple of endpoints to the API, and fix a big annoyance. You can now:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Delete KB articles&lt;/li&gt;
&lt;li&gt;Create and delete sections&lt;/li&gt;
&lt;li&gt;Use pagination for discussion comments (at last)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;We’ve added the relevant documentation as well. I know some folks have been waiting on those, so let us know how this works out for you.&lt;/p&gt;
&lt;p&gt;That’s it for today, see you next time with more goodies!&lt;/p&gt;</description><link>http://blog.entp.com/post/20029745099</link><guid>http://blog.entp.com/post/20029745099</guid><pubDate>Tue, 27 Mar 2012 15:50:00 -0700</pubDate><category>tender</category><dc:creator>calexicoz</dc:creator></item><item><title>Lighthouse updates for March 22nd</title><description>&lt;p&gt;Since this is a much shorter period than the last change log, we have less to talk about this time, but here goes!&lt;/p&gt;

&lt;p&gt;Most notably, ticket search has improved: While it&amp;#8217;s always been possible to specify multiple &lt;code&gt;responsible:&lt;/code&gt; specifications in a search, &lt;code&gt;responsible:none&lt;/code&gt; only worked in isolation. It was not possible to search for the set of tickets assigned to someone &lt;em&gt;as well as unassigned tickets&lt;/em&gt;. Well, this has changed! So for example, if you want to make a bin of your tickets as well as stuff that nobody has picked up yet, you can do that now.&lt;/p&gt;

&lt;p&gt;Milestone due dates could exhibit some odd behavior for project members in different time zones, so we now anchor milestone due date comparisons to the account-level time zone. This means milestones will be due/late at the same time for everyone!&lt;/p&gt;

&lt;p&gt;In some cases it was possible to silently truncate content for a page if it was too large in size. We&amp;#8217;ve added validation to prevent data loss, but the size restriction remains in place for now.&lt;/p&gt;

&lt;p&gt;We are also handling (and cleaning up) more instances of failed callbacks, reducing the load on our job runners. We have also continued to improve the stability of our export process for very large data sets.&lt;/p&gt;</description><link>http://blog.entp.com/post/19739179125</link><guid>http://blog.entp.com/post/19739179125</guid><pubDate>Thu, 22 Mar 2012 11:30:00 -0700</pubDate><category>Lighthouse</category><dc:creator>zenhob</dc:creator></item><item><title>Lighthouse updates for March 15th</title><description>&lt;p&gt;Hi folks, it&amp;#8217;s been too long since the last Lighthouse update! You have me to thank for that, but I have bravely re-learned to blog and am finally here to fill you in. We are tearing through our backlog of issues, and we have plenty of stuff to tell you about!&lt;/p&gt;
&lt;p&gt;Here are some highlights from Lighthouse releases in the last month or so:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Audited for mass-assignment bugs in every controller. I&amp;#8217;ll have more on this later.&lt;/li&gt;
&lt;li&gt;There is much-improved display of ticket changes, including inline links.&lt;/li&gt;
&lt;li&gt;We&amp;#8217;ve fixed the display for projects with thousands of tickets, so your ticket badges don&amp;#8217;t take up 2 lines.&lt;/li&gt;
&lt;li&gt;We improved the fidelity of table styling in preview, to match the final comment.&lt;/li&gt;
&lt;li&gt;Added pagination to user- and account-level activity feeds, and improved pagination behavior in milestone views.&lt;/li&gt;
&lt;li&gt;We&amp;#8217;ve updated our OpenID back-end, which should go a long way toward improving interoperability.&lt;/li&gt;
&lt;li&gt;We now avoid modifying ticket creation date when changes are rolled back.&lt;/li&gt;
&lt;li&gt;Watchers were not being added/notified in some cases, this has been fixed.&lt;/li&gt;
&lt;li&gt;We also fixed instances of subscribed watchers being re-added to tickets accidentally.&lt;/li&gt;
&lt;li&gt;Refined auto-linking behavior in the markdown formatter, so that auto-links do not happen inside markdown and textile links.&lt;/li&gt;
&lt;li&gt;We&amp;#8217;ve restored reverse-sort functionality in ticket queries.&lt;/li&gt;
&lt;li&gt;There were instances of HTML content appearing in text email notifications, these have been fixed.&lt;/li&gt;
&lt;li&gt;Internal links now work properly while previewing.&lt;/li&gt;
&lt;li&gt;Fixed a JS error being experienced by some Internet Explorer 8 user.&lt;/li&gt;
&lt;li&gt;We&amp;#8217;ve made numerous internal improvements to our export functionality, making data exports quicker and more reliable.&lt;/li&gt;
&lt;li&gt;Improved handling/reporting of missing resources during API requests.&lt;/li&gt;
&lt;li&gt;Fixed tag editing on Internet Explorer 9.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Bigger improvements and new functionality are on the horizon. I expect you&amp;#8217;re as excited about the new hotness as we are, so stay tuned for more!&lt;/p&gt;</description><link>http://blog.entp.com/post/19369475128</link><guid>http://blog.entp.com/post/19369475128</guid><pubDate>Thu, 15 Mar 2012 16:58:00 -0700</pubDate><category>lighthouse</category><dc:creator>zenhob</dc:creator></item><item><title>Lighthouse updates for February 17th</title><description>&lt;p&gt;Howdy! We have been shipping a bunch of updates to Lighthouse, dealing out bugfixes and tidying up in general; basically fixing a bunch of the nigglingest issues and making up words while we&amp;#8217;re in there. Here&amp;#8217;s what we shipped recently:&lt;/p&gt;



&lt;ul&gt;&lt;li&gt;Lighthouse has been modernized and now runs on Ruby 1.9, along with a bunch of upgraded and moderner libraries for our whole stack: memcached, mysql, and more.&lt;/li&gt;&#xD;
&lt;li&gt;Callbacks - you may know them as web hooks - now have their own UI (previously only accessible via the API.) You can make callbacks from the account-level settings page. All ticket updates get a JSON post to any URL you choose. If a callback fails continuously, we will eventually stop posting to it.&lt;/li&gt;&#xD;
&lt;li&gt;Bulk edit failure modes got improved: if you create a bulk edit that has no actual tickets (i.e. if you create it twice, or the ticket got moved), it won&amp;#8217;t sit around hassling you that it hasn&amp;#8217;t run. Also, you can&amp;#8217;t select archived projects as a bulk edit target.&lt;/li&gt;&#xD;
&lt;li&gt;CSV reports are now fully Excel compliant and are UTF-16, so your non-ASCII characters will work just fine, right-to-left, &lt;em&gt;und so weiter.&lt;/em&gt;. There&amp;#8217;s also a dedicated Excel button (it&amp;#8217;s actually a TSV) as well as the same old CSV.&lt;/li&gt;&#xD;
&lt;li&gt;We upgraded our markdown processing library to the latest, which may fix some annoying formatting bugs.&lt;/li&gt;&#xD;
&lt;li&gt;We also upgraded our date parsing library and fixed some minor bugs there.&lt;/li&gt;&#xD;
&lt;li&gt;Attachments on tickets with more than 100 comments now show correctly.&lt;/li&gt;&#xD;
&lt;li&gt;Pagination on milestones is fixed and now actually works.&lt;/li&gt;&#xD;
&lt;li&gt;&amp;#8220;Late&amp;#8221; milestones is now an accurate thing that refers to the end of day rather than beginning (you&amp;#8217;re not late til the day is done, man).&lt;/li&gt;&#xD;
&lt;li&gt;Saving default ticket bins no longer clears the default state.&lt;/li&gt;&#xD;
&lt;/ul&gt;&lt;p&gt;Once we get these fixes out of the way we have lots of exciting lighthousey things to share with you!&lt;/p&gt;</description><link>http://blog.entp.com/post/17794318335</link><guid>http://blog.entp.com/post/17794318335</guid><pubDate>Fri, 17 Feb 2012 16:56:00 -0800</pubDate><category>lighthouse</category><dc:creator>courtenay3</dc:creator></item><item><title>Scheduled-ish downtime</title><description>&lt;p&gt;Both Tender and Lighthouse will be down for up to 30 minutes tonight from 8pm Pacific while we reboot some critical servers. While we can reboot most of the instances without causing downtime (in fact, we already have), there are some services that don&amp;#8217;t handle failover particularly gracefully and so it will be cleaner for us to take the apps down completely rather than try to do it &amp;#8216;live&amp;#8217;.  For example, we could easily fail over our redis cluster to the slave instances (they&amp;#8217;re already used for reads) but there&amp;#8217;s a risk that a few minutes of writes would be lost.&lt;/p&gt;
&lt;p&gt;We apologize for any inconvenience due to the late notice - we&amp;#8217;re not entirely happy about it either.&lt;/p&gt;</description><link>http://blog.entp.com/post/14173720893</link><guid>http://blog.entp.com/post/14173720893</guid><pubDate>Tue, 13 Dec 2011 10:40:00 -0800</pubDate><category>maintenance</category><dc:creator>courtenay3</dc:creator></item><item><title>User Classes</title><description>&lt;p&gt;We&amp;#8217;ve just deployed the &lt;strong&gt;User Class&lt;/strong&gt; feature.  This is our way of providing the minimum amount of access control and segregation possible.&lt;/p&gt;
&lt;p&gt;You see, many of you have two main versions of their software or application: the normal version, and a beta version with features not generally available. You want to have articles and categories available to those users without revealing that information to the public.&lt;/p&gt;
&lt;p&gt;You also tend to have regular users, and a separate class of important users &amp;#8212; whether they&amp;#8217;re paying more, need special handling, or you just love &amp;#8216;em because they always open nice detailed and friendly support requests.&lt;/p&gt;
&lt;p&gt;So, we&amp;#8217;ve enabled a few toggles on your users, KB sections, and categories. You&amp;#8217;ll need to enable it like so:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Go to your site settings. Select &amp;#8220;Enable beta users&amp;#8221; and hit save.&lt;/li&gt;
&lt;li&gt;Go to your users page (settings/users), and check some users&amp;#8217; checkboxes. Set the Beta Access, or Important User, flag. (also can be set in the API and SSO hash)&lt;/li&gt;
&lt;li&gt;Go to your categories admin page, and edit or create a forum category with the same toggle. &lt;/li&gt;
&lt;li&gt;Go to your KB sections admin page, and edit or create a KB section with the same toggle.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Any sections, KB articles, categories, or discussions flagged as beta or important won&amp;#8217;t be visible to other users. Users who have access to see those sections and categories &lt;strong&gt;will&lt;/strong&gt; have the results show up in searches, autosuggest and regular browsing.&lt;/p&gt;
&lt;p&gt;Finally, while we haven&amp;#8217;t enabled this on discussion filters (yet!) we HAVE shipped something else that&amp;#8217;s even more useful. You can now design your filters around the &amp;#8216;extras&amp;#8217; hash that is attached to each user and discussion. So, for example, lets say you set a user with the extras hash of &lt;span&gt;{ plan: &amp;#8216;Premium&amp;#8217; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can now create a filter that will check for key/value pairs on new discussions, like &amp;#8220;plan=Max&amp;#8221; or &amp;#8220;name=Joe&amp;#8221;. You can even use regular expressions (name=~Joe) and have multiple statements (name=~Joe;plan=Premium).&lt;/p&gt;
&lt;p&gt;This feature should be (somewhat ironically) considered beta quality for the next week or so, but I&amp;#8217;d love to hear how you&amp;#8217;re using it or how it doesn&amp;#8217;t quite meet your needs. As always, open a discussion on our own forum at &lt;a href="http://help.tenderapp.com" target="_blank"&gt;help.tenderapp.com&lt;/a&gt; or email us at help@tenderapp.com.&lt;/p&gt;</description><link>http://blog.entp.com/post/12668306903</link><guid>http://blog.entp.com/post/12668306903</guid><pubDate>Fri, 11 Nov 2011 18:00:00 -0800</pubDate><category>tender</category><dc:creator>courtenay3</dc:creator></item><item><title>Scaling - a series of small, incremental evolutionary changes...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_luc3arSsqA1qf48dco1_400.png"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;img src="http://25.media.tumblr.com/tumblr_luc3arSsqA1qf48dco2_500.png"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;p&gt;Scaling - a series of small, incremental evolutionary changes interspersed with intense “oh shit!” moments.&lt;/p&gt;
&lt;p&gt;We’ve recently undergone a significant change in architecture in response to a series of bad downtime. You can see above what it used to look like: a fairly simple setup, with a few app servers, and what it looks like now. We’ve added a few important changes to the way everything works, and we’re rolling these out in stages.&lt;/p&gt;
&lt;p&gt;Tender has been growing at a fantastic rate (doubled in size this year) but the hardware infrastructure hasn’t really changed - as we’ve grown, we just increase the instance size of the master db and added app servers as necessary. This has worked excellently because it doesn’t require any downtime. But as you can probably tell, the old infrastructure had many points of failure. The main two issues we’ve seen are (a) the haproxy machine going down but not failing over and (b) high IO on the database master EBS disks.&lt;/p&gt;
&lt;p&gt;We can’t fix the failover issues - that’s the domain of our webhost, and they assure us it’s fixed. Regardless, we’ve upgraded our support plan with them to super-mega-premium, so we can get expert help a bit faster (an additional $2,000 per month! There goes the summer home in the Bahamas!).&lt;/p&gt;
&lt;p&gt;The database/EBS IO issues are unavoidable on EC2. Sometimes the disks are just slow which means random queries like ‘update sites set updated_at = NOW() where id=12254’ take fifteen to twenty seconds. In combination with the latency issue we also outgrown our web host: the largest machine that EC2 offers, is the quad extra-large has 68gb of RAM, but our largest tables (comments and discussions) each have indexes larger than this, which means a lot of mySQL hunting on disk for the data.  To make things worse, Engineyard, who provides the stack we’re using on top of EC2, doesn’t support running multi-master replication or even having multiple writable database servers. And since we’re on the largest machine that EC2 offers, we’re prevented from growing with the existing strategy. If we hosted our own gear, we could easily build yet another bigger server. But we aren’t.&lt;/p&gt;
&lt;p&gt;As it turns out, we can work around this limitation with noSQL. It involves managing a lot of the in-memory data MySQL used to handle by building things ourselves in Redis, which is ridiculously easy to scale horizontally. Here’s how we’re doing it:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Store as much as possible in Redis, which means, store as much as possible in RAM. Redis makes doing big intersections of lists (i.e. all discussions in this queue, on this site, in this state) super fast and easy.&lt;/li&gt;
&lt;li&gt;Minimize database table and index scans, again, by building our own indexes (e.g. all discussions by this user_id) in Redis instead of mysql.&lt;/li&gt;
&lt;li&gt;Add a bunch of redis instances and servers dedicated to running Redis. Redis and its ruby library makes this super easy again with consistent hashing. We’re making up to 32 instances per server.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Finally, we can also add readonly slaves to mySQL (and hope that replication doesn’t get too far out of sync), and move most of our reads to those. We already use background jobs to process most writes to the database already, so this was easier than expected. (on Friday, we were down due to a memory leak in the sharding library. D’oh! Two steps forward, one step back)&lt;/p&gt;
&lt;p&gt;So, implementing these improvements include all your standard scaling progress:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Shard the database vertically so that reads go to a separate slave. Once this works reliably,&lt;/li&gt;
&lt;li&gt;Shard the database horizontally so that each site has its own dedicated database on a server with very few other databases (better CPU to RAM ratio)&lt;/li&gt;
&lt;li&gt;Add more Redis servers with up to 32 instances per box&lt;/li&gt;
&lt;li&gt;Reindex all the existing redis data so that it is spread onto the new instances&lt;/li&gt;
&lt;li&gt;Add a bunch more app servers, so the frontend is always responsive even if the master db is backed up.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Combined, this allows us to move individual chunks of both Redis and MySQL databases onto their own server to equalize load and memory usage; once one instance gets too large (at this stage, over a few hundred MB), we can move that one instance onto a new server with very little effort and almost zero downtime. It also gives us an order of magnitude more CPU per GB of RAM, which means everything’s faster.&lt;/p&gt;
&lt;p&gt;What’s next? Hopefully all this will happen behind the scenes and everything will get faster and more reliable. We’ve just hired two more skilled developers to help us implement all this as soon as possible. Once we have the new backend fully online, we can start shipping the fully dynamic ajax frontend, live in-page updates, and more.&lt;/p&gt;</description><link>http://blog.entp.com/post/12507028770</link><guid>http://blog.entp.com/post/12507028770</guid><pubDate>Tue, 08 Nov 2011 00:55:00 -0800</pubDate><category>tender</category><dc:creator>courtenay3</dc:creator></item><item><title>Welcome to the new blog.</title><description>&lt;p&gt;We&amp;#8217;ve migrated to a new blog. Yay! All the old posts are still cached online at the old &lt;a href="http://hoth.entp.com" target="_blank"&gt;Hoth&lt;/a&gt; blog, but from now on, we&amp;#8217;re on Tumblr. Feels shiny.&lt;/p&gt;</description><link>http://blog.entp.com/post/12505278123</link><guid>http://blog.entp.com/post/12505278123</guid><pubDate>Mon, 07 Nov 2011 23:03:00 -0800</pubDate><category>entp</category><dc:creator>courtenay3</dc:creator></item><item><title>Once in a blue moon a new service comes along that is so simple...</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_levpu6mUy31qf48dco1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Once in a blue moon a new service comes along that is so simple and well executed, you walk away rethinking the meaning of software as a service. &lt;a target="_blank" href="http://flavors.me"&gt;Flavors.me&lt;/a&gt; is just that, a personal homepage service that allows you to make a homepage in minutes.&lt;/p&gt;



&lt;p&gt;So when Flavors.me announced this morning that they are using &lt;a target="_blank" href="http://tenderapp.com"&gt;Tender&lt;/a&gt; to handle their customer support and knowledge base articles, we couldn’t help but get excited.&lt;/p&gt;</description><link>http://blog.entp.com/post/2703077891</link><guid>http://blog.entp.com/post/2703077891</guid><pubDate>Tue, 11 Jan 2011 14:15:00 -0800</pubDate><category>spotlight</category><dc:creator>imagetic</dc:creator></item><item><title>Does Virb do ANYTHING that isn’t awesome?</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_ld8wqdzxAh1qf48dco1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Does &lt;a target="_blank" href="http://virb.com"&gt;Virb&lt;/a&gt; do ANYTHING that isn’t awesome?&lt;/p&gt;</description><link>http://blog.entp.com/post/2171253517</link><guid>http://blog.entp.com/post/2171253517</guid><pubDate>Wed, 28 Jul 2010 21:00:00 -0700</pubDate><category>spotlight</category><dc:creator>imagetic</dc:creator></item><item><title>The case against SLAs</title><description>&lt;p&gt;We built Tender for a few reasons, most of them pretty reactionary. We needed a better way than a shared email box or public Lighthouse project to handle customer support, but the solutions out there really didn&amp;#8217;t work for us from a user perspective.  I personally think that&amp;#8217;s because most of them were created by people who came from a customer support or &amp;#8220;Big IT&amp;#8221; background, rather than coming from &amp;#8220;just being a user&amp;#8221; background. I think this shows mostly from the concept of SLAs and automated workflows.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6b46lFxXG1qz4lun.jpg" alt="robots!"/&gt;&lt;/p&gt;

&lt;p&gt;(Side note: this is a similar rant along the lines of why we don&amp;#8217;t do priorities in Lighthouse. We do actually have priorities, but I stand by the assertion that priorities don&amp;#8217;t work).&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s how it generally goes:&lt;/p&gt;

&lt;p&gt;A customer opens an issue; they get an automated response back along the lines of &amp;#8220;You are customer request number #425. We will respond to you shortly&amp;#8221;. Conveniently turned into a number, the customer now can be conveniently turned into a trackable metric. We can start judging the performance of our employees based on the speed with which they deal with this request.&lt;/p&gt;

&lt;p&gt;Next, a support workflow kicks in, and a support operator has a limited amount of time to respond to the query, or they (presumably) get into trouble.  The operator responds, and presumably they do the support dance with the customer until there&amp;#8217;s something to track down, a question unanswered, or there just isn&amp;#8217;t a suitable response.&lt;/p&gt;

&lt;p&gt;A while passes, and the support workflow again kicks in, re-escalating the request or performing some sort of automated action on the ticket. Generally, this is &amp;#8220;close the issue after a week of no replies.&amp;#8221;  An automated response goes out informing the number, I mean customer, that their issue has been deemed solved.&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t agree with this at all. It&amp;#8217;s a technical solution to a human problem. That being said, I also don&amp;#8217;t think we&amp;#8217;ve solved it in &lt;a href="http://tenderapp.com" target="_blank"&gt;Tender&lt;/a&gt;, either, from a human OR technical standpoint.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;re not perfect when it comes to responding to our own customer support discussions, and we&amp;#8217;re not fully there in providing tools to our customers to help them solve this themselves.  But we do get responses like this, and it makes everyone on the team happy:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&amp;#8220;Check the Tender forums for an example of how to engage with your customers in a genuine manner.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But we&amp;#8217;re working on it, in a few ways.&lt;/p&gt;

&lt;p&gt;Step zero is to be authentically human and not pretend otherwise.&lt;/p&gt;

&lt;p&gt;Next, we choose to not offer SLAs. They make everyone feel worthless and under pressure. (We may implement this at some point in the future, but that will rely on the successful state-changes outlined below).&lt;/p&gt;

&lt;p&gt;We also got rid of all mention of support &amp;#8220;tickets&amp;#8221; or &amp;#8220;issues&amp;#8221; and made it uniformly &amp;#8220;discussions&amp;#8221;.  I feel that the nomenclature is important, and that the way you refer to your customer interactions actually colors the tone, emotion and ultimate success of the conversation.&lt;/p&gt;

&lt;p&gt;Finally, we&amp;#8217;re modifying the discussion states, so you can have something that isn&amp;#8217;t strictly &amp;#8220;resolved&amp;#8221;, but also isn&amp;#8217;t necessarily &amp;#8220;open&amp;#8221;, either, so it doesn&amp;#8217;t weigh on your conscience.&lt;/p&gt;

&lt;p&gt;So, if you&amp;#8217;re coming to Tender from a service where it encourages you to treat your customers like machines, it&amp;#8217;s worth taking a moment to to consider turning your &lt;em&gt;intrahuman&lt;/em&gt; communications into something a bit more fleshy.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Post written by Courtenay Gasking, Art by Josh Piles&lt;/em&gt;&lt;/p&gt;</description><link>http://blog.entp.com/post/2171212494</link><guid>http://blog.entp.com/post/2171212494</guid><pubDate>Wed, 19 May 2010 21:00:00 -0700</pubDate><category>business</category><dc:creator>entpstaff</dc:creator></item><item><title>"It’s only been a week of working with Tender and a few days of having it live for our customers to..."</title><description>“It’s only been a week of working with Tender and a few days of &lt;a href="http://moneywell-help.nothirst.com/home" target="_blank"&gt;having it live for our customers to use&lt;/a&gt;, but I’m thrilled with it. The discussion forum is much more structured than our old Google Groups forum—we can mark issues as open or resolved, assign priority queues to issues, and, best of all, support emails go to the forum so they can’t get lost in a cluttered inbox. It’s not as large and in charge as FogBugz, but that’s part of its appeal. We’re even more committed to offering timely and effective support as our customer base continues to grow, and Tender will help us stay on top of our game. My next blog post will talk more about this customer support tool and why &lt;strong&gt;it fits No Thirst Software so well&lt;/strong&gt;.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Kevin Hoctor, &lt;a target="_blank" href="http://nothirst.com"&gt;No Thirst Software&lt;/a&gt;&lt;/em&gt;</description><link>http://blog.entp.com/post/2162792365</link><guid>http://blog.entp.com/post/2162792365</guid><pubDate>Mon, 22 Jun 2009 21:00:00 -0700</pubDate><category>praise</category><dc:creator>entpstaff</dc:creator></item><item><title>git track is where it's at</title><description>&lt;p&gt;Remembering &lt;code&gt;git branch --track local origin/remote &amp;amp;&amp;amp; git checkout local&lt;/code&gt; is proving to be as difficult as a Chief Justice remembering the presidential oath.  On that note, here is a a quick rundown on git alias and a few simple examples to get you started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;git track foo origin/foo&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[alias]
 track = !sh -c 'git branch --track "$0" "$1" &amp;amp;&amp;amp; git checkout "$0"'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here is a shorter version that assumes your local branch will be named the same as your remote branch and you&amp;#8217;ll always be pulling from origin/*.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;git track foo&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[alias]
 track = !sh -c 'git branch --track "$0" "origin/$0" &amp;amp;&amp;amp; git checkout "$0"'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;update: &lt;code&gt;git checkout -b foo origin/foo&lt;/code&gt; will track  if you have &lt;code&gt;branch.autosetupmerge=true&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;Roll Your Own Git Alias&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://git.or.cz/gitwiki/Aliases" target="_blank"&gt;Git Aliases&lt;/a&gt; are a nice way to simplify your common tasks into simple commands.  Not only can you chain together git commands like we did above, you can run entire scripts, whether it be bash, ruby, python, etc.&lt;/p&gt;

&lt;p&gt;The formatting can sometimes be tricky, but one important thing to keep in mind is that unless you&amp;#8217;re simply aliasing git&amp;#8217;s built in commands, you&amp;#8217;ll need to prefix your commands with the &lt;strong&gt;&lt;em&gt;!&lt;/em&gt;&lt;/strong&gt; sign.  If your entire line is in quotes you&amp;#8217;ll want to put the &lt;strong&gt;&lt;em&gt;!&lt;/em&gt;&lt;/strong&gt; inside the quotes, directly before your starting command only.  One final note, you can accept arguments in your aliases using $&lt;em&gt;n&lt;/em&gt;.  Here are a couple more commands to give you some ideas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;git lh&lt;/strong&gt; - find all commits affecting a &lt;a href="http://lighthouseapp.com" target="_blank"&gt;Lighthouse&lt;/a&gt; ticket&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;lh = "!git log --pretty='format:%h [%ar | %aD] [%an] -- %s' | grep -i '\\[#[0-9]*'"
# == Output:
# 658f5c9 [2 months ago | Mon, 10 Nov 2008 13:46:16 -0200] [Nicolas Sanguinetti] -- Ensure managers can see a blog's profile even if it's still pending [#24 state:resolved]
# 48afbb9 [2 months ago | Mon, 10 Nov 2008 13:17:08 -0200] [Daniel Cadenas] -- Fixed. Can only change a user role if user!=current_user [#25 state:resolved]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;git ignored&lt;/strong&gt; - list all files that are ignored&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ignored = "!git ls-files --others --exclude-standard" 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So that&amp;#8217;s it!  Do you have any useful aliases you want to share?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Post written by Justin Palmer&lt;/em&gt;&lt;/p&gt;</description><link>http://blog.entp.com/post/2162653181</link><guid>http://blog.entp.com/post/2162653181</guid><pubDate>Tue, 20 Jan 2009 21:00:00 -0800</pubDate><category>code</category><dc:creator>entpstaff</dc:creator></item><item><title>Migrate from JIRA or Trac to Lighthouse</title><description>&lt;p&gt;Looking to move from old tickets from JIRA or Trac to Lighthouse?  You&amp;#8217;re not alone.  Some of our members have gotten creative with the Lighthouse API and implemented some unofficial importers.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://work.onemanswalk.com/2008/4/23/cruise-control-rb-is-moving-to-lighthouse" target="_blank"&gt;JIRA Importer&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://github.com/shayarnett/trachouse/tree/master" target="_blank"&gt;Trac Importer&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://github.com/WALoeIII/lighthouse-bugzilla-importer/tree/master" target="_blank"&gt;Bugzilla Importer&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;em&gt;Post written by Justin Palmer&lt;/em&gt;&lt;/p&gt;</description><link>http://blog.entp.com/post/2162427495</link><guid>http://blog.entp.com/post/2162427495</guid><pubDate>Wed, 23 Apr 2008 21:00:00 -0700</pubDate><category>lighthouse</category><dc:creator>entpstaff</dc:creator></item></channel></rss>

