<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>iContact Labs</title>
	<atom:link href="http://icontactlabs.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://icontactlabs.wordpress.com</link>
	<description>Just another WordPress.com weblog</description>
	<lastBuildDate>Sun, 10 Apr 2011 01:19:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='icontactlabs.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>iContact Labs</title>
		<link>http://icontactlabs.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://icontactlabs.wordpress.com/osd.xml" title="iContact Labs" />
	<atom:link rel='hub' href='http://icontactlabs.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Supervisor Expandconfig</title>
		<link>http://icontactlabs.wordpress.com/2011/04/09/supervisor-expandconfig/</link>
		<comments>http://icontactlabs.wordpress.com/2011/04/09/supervisor-expandconfig/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 01:19:35 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=85</guid>
		<description><![CDATA[Short demo of a tool we&#8217;re working on to expand configurations for Supervisord. You can see a brief screencast covering this.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=85&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Short demo of a tool we&#8217;re working on to <a href="https://github.com/drasch/supervisor-tools">expand configurations</a> for Supervisord.  </p>
<p>You can see a brief <a href="http://screencast.com/users/drasch/folders/Jing/media/8276e6df-9a3f-4313-b090-9b764a8dc30d">screencast</a> covering this.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/85/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=85&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2011/04/09/supervisor-expandconfig/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>
	</item>
		<item>
		<title>Caching – Hunting for Database Hotspots, Part 5</title>
		<link>http://icontactlabs.wordpress.com/2010/11/08/caching-%e2%80%93-hunting-for-database-hotspots-part-5/</link>
		<comments>http://icontactlabs.wordpress.com/2010/11/08/caching-%e2%80%93-hunting-for-database-hotspots-part-5/#comments</comments>
		<pubDate>Tue, 09 Nov 2010 03:38:30 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=78</guid>
		<description><![CDATA[Last time, we covered how to optimize the application to avoid calls to the database. A cache can offer a solution when you can neither avoid getting the data nor make the queries more efficient. A cache serves as a logical middle layer between the application and the database. A general pattern I&#8217;ve seen for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=78&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Last time, we covered how to optimize the application to avoid calls to the database.  A cache can offer a solution when you can neither avoid getting the data nor make the queries more efficient.  </p>
<p>A cache serves as a logical middle layer between the application and the database. </p>
<p>A general pattern I&#8217;ve seen for caching:<br />
<code><br />
KEY="data"<br />
data = cache.get( KEY )<br />
if (!data) {<br />
  data = db.query("slow")<br />
  cache.set(KEY, data, 30);<br />
}<br />
</code></p>
<p>You&#8217;ll notice that the code first checks the cache to see if we get a &#8220;hit&#8221;. If not, we query the database and store the data back to the cache. </p>
<p>Now we know how to store and retrieve data in the cache.</p>
<p><strong>What happens when a user sees the data, changes something, and then wonders why the data isn&#8217;t showing up?</strong></p>
<p>Many cache services like <a href="http://memcached.org/">Memcache</a> and/or <a href="http://us.php.net/apc">APC</a> allow for a timeout to be specified so that we can make the data we put into the cache expire automatically.</p>
<p>Timeouts only go so far. Sometimes you need to lower the timeout to give the user fresh data, which marginalizes the benefit of caching. Ideally, your application knows exactly when the cache becomes invalid&#8211;when the user updates the object affected by the cache. A solid caching strategy also dirties the cache elements so the user never has knowledge of the cache!</p>
<p>We do lots of caching here to keep iContact running.  We run a cluster of Memcache servers to store our sessions, and cache lots of data that&#8217;s frequently accessed to reduce the load on our database servers.  On some pages, once the cache is warmed the number of queries goes down to 2-3 per page!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/78/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=78&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2010/11/08/caching-%e2%80%93-hunting-for-database-hotspots-part-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>
	</item>
		<item>
		<title>Readiness Criteria</title>
		<link>http://icontactlabs.wordpress.com/2010/09/10/readiness-criteria/</link>
		<comments>http://icontactlabs.wordpress.com/2010/09/10/readiness-criteria/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 20:21:47 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=70</guid>
		<description><![CDATA[How do you know when you&#8217;re ready to do work? &#160;How much design is un-agile? Agile teams tend to make the mistake of doing almost no up-front design before plowing into the work at hand. &#160;Being agile doesn&#8217;t meant the work should be a complete mystery when you&#8217;re being asked to estimate and deliver it. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=70&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>How do you know when you&#8217;re ready to do work? &nbsp;How much design is un-agile?</p>
<p>Agile teams tend to make the mistake of doing almost no up-front design before plowing into the work at hand. &nbsp;Being agile doesn&#8217;t meant the work should be a complete mystery when you&#8217;re being asked to estimate and deliver it. &nbsp;Here at iContact, we&#8217;re rolling out a checklist that helps us determine when we&#8217;re ready to move forward from an idea to an Epic and when a Story is ready to go into a sprint.</p>
<p><strong>Epic Readiness</strong> &#8211; know what we need to build so we can design</p>
<ol>
<li>Business Requirements</li>
<li>Technical Requirements</li>
<li>Documentation</li>
</ol>
<p><strong>Story Readiness</strong> &#8211; know how we&#8217;ll build it so we can estimate</p>
<ol>
<li>Design</li>
<li>Stories</li>
<li>Documentation</li>
</ol>
<p>We&#8217;ve developed some checklists to help us get to this level of readiness:</p>
<div>
<h4>Business Requirements Checklist</h4>
<ul>
<li>Do I know who the stakeholders are and what they want?</li>
<li>Do I know how we plan to roll this out to customers?</li>
<li>Do I understand feature-wise priority?</li>
</ul>
<h4>Technical Requirements Checklist</h4>
<ul>
<li>Will this affect areas of the software known to be more risky?</li>
<li>Do I have a high level understanding of environment/infrastructure/architecture impact?</li>
<li>What type of testing is needed? Load testing?</li>
</ul>
<h4>Design Checklist</h4>
<ul>
<li>Do we have a design documented?</li>
<li>Have I read it?</li>
<li>Have we solicited feedback from stakeholders? Are there collaboration points?</li>
<li>Do we have a diagram?</li>
<li>Do we understand the interfaces and the data passed between components?</li>
<li>Will there be additional data to store? Where? How will it be used?</li>
<li>Does our design manage risk?</li>
<li>Are there standards we can apply?</li>
<li>Is the design iterative? &nbsp;Can it be built in stages?</li>
</ul>
</div>
<p>These tools are helping our teams plan backward from their grooming sessions to determine what level of technical vetting is necessary.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/70/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=70&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2010/09/10/readiness-criteria/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>
	</item>
		<item>
		<title>10 Key Elements of Web Frameworks</title>
		<link>http://icontactlabs.wordpress.com/2010/08/05/10-key-elements-of-web-frameworks/</link>
		<comments>http://icontactlabs.wordpress.com/2010/08/05/10-key-elements-of-web-frameworks/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 01:39:29 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=67</guid>
		<description><![CDATA[As we improve our own internal web framework that powers iContact, we&#8217;ve identified some key things you should look for in any web framework. Must haves: 1. Request 2. Response 3. RequestHandler These must haves provide an abstraction for the key elements of any web framework, whether it be MVC or otherwise.  Having objects to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=67&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As we improve our own internal web framework that powers iContact, we&#8217;ve identified some key things you should look for in any web framework.</p>
<p><strong>Must haves:</strong><br />
1. Request<br />
2. Response<br />
3. RequestHandler</p>
<p>These must haves provide an abstraction for the key elements of any web framework, whether it be MVC or otherwise.  Having objects to encapsulate the request, and send back a response allow for many tasks be simple.  Most importantly, they allow you to construct a test harness that doesn&#8217;t have to jump through hoops to process headers or handle sessions.</p>
<p><strong>Extremely Helpful</strong><br />
4. Autoloading &#8211; Webs of require/require_once are no fun<br />
5. Error/Exception handling &#8211; Displaying pretty output when errors occur<br />
6. Logging &#8211; Log levels, different targets<br />
7. Profiling<br />
8 Security helpers &#8211; XSS/CSRF</p>
<p>Helpful, but probably belongs somewhere else<br />
9. Database wrapper<br />
10. Sessions and authentication</p>
<p>While these latter elements aren&#8217;t in the same class as 1-3, you&#8217;ll end up constructing most of these components to make tasks easier.  Wouldn&#8217;t you rather focus on building our application than building another framework.</p>
<p>How do your favorite web frameworks shape up?  Let us know in the comments!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/67/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=67&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2010/08/05/10-key-elements-of-web-frameworks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>
	</item>
		<item>
		<title>The Application – Hunting for Database Hotspots, Part 4</title>
		<link>http://icontactlabs.wordpress.com/2010/06/30/the-application-%e2%80%93-hunting-for-database-hotspots-part-4/</link>
		<comments>http://icontactlabs.wordpress.com/2010/06/30/the-application-%e2%80%93-hunting-for-database-hotspots-part-4/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 01:26:39 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=62</guid>
		<description><![CDATA[Sometimes we get tied into specific requirements rather than leveraging some agility and creativity to determine what&#8217;s really needed.   Often by using this creativity we can improve performance, reduce load on our database, and users understand that perfect data isn&#8217;t always available. A great example of approximate data shows up when you do any search [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=62&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Sometimes we get tied into specific requirements rather than leveraging some agility and creativity to determine what&#8217;s really needed.   Often by using this creativity we can improve performance, reduce load on our database, and users understand that perfect data isn&#8217;t always available.</p>
<p>A great example of approximate data shows up when you do any search through your favorite search engine.  Both the number of search results and the number of pages are approximations.  Sometimes you&#8217;ll find as you go to switch from page 3 of search results to page 4 that the search engine finds out there aren&#8217;t actually any more results to show.  Alternatively, as you page through the results the number of pages can decrease.  In both of these cases, the performance and accuracy of the information is tuned to the needs of the users.</p>
<p>Data shows that more than 50% of users only click on the first search result after conducting their search.  When you add up the entire first page of results accounts for &gt;90% of clicks to results.  To more than 90% of users, the number of pages of further results are almost entirely irrelevant.  Search engines have realized this and prioritized the computation of these values.</p>
<p>At iContact, we just had an instance where we decided to change the user experience a bit to improve performance, however I doubt our users will ever notice.  When you click the &#8220;Create&#8221; tab inside our application we&#8217;d designed it so that if you had yet to create a message, we would hide the &#8220;Re-use a sent message&#8221; link.  The challenge was that this created a relatively expensive query that demanded a temp table and filesort.  When we went to optimize the query, we realized a few things:</p>
<ol>
<li>The only people who wouldn&#8217;t see the link are people who just created their account.</li>
<li>We incur the cost of checking for this message to load an otherwise static page mainly used for navigation.</li>
<li>The cost to run the query gets more expensive the more messages you send and the less valuable.</li>
</ol>
<p>We decided to make the link show up all the time.  This eliminated the query on one of the most common pages loaded in our application.  It&#8217;s reduced its page generation time by 100s of milliseconds on average.</p>
<p>What are ways you can get creative with your application to alleviate database hotspots?</p>
<ol>
<li>Can data be approximated?</li>
<li>Can you update less frequently, perhaps even probabilistically?</li>
<li>Can you stop showing the data at all?</li>
<li>Can you email the data to the user so you have more time to process it?</li>
</ol>
<p>What other suggestions to you have for changing application logic to create more performant applications?  Any case studies out there?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/62/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=62&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2010/06/30/the-application-%e2%80%93-hunting-for-database-hotspots-part-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>
	</item>
		<item>
		<title>The Query &#8211; Hunting for Database Hotspots, Part 3</title>
		<link>http://icontactlabs.wordpress.com/2010/06/17/the-query-hunting-for-database-hotspots-part-3/</link>
		<comments>http://icontactlabs.wordpress.com/2010/06/17/the-query-hunting-for-database-hotspots-part-3/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 03:22:29 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=43</guid>
		<description><![CDATA[An application&#8217;s performance can often be improved in many ways, but query optimization should always be near the top of your toolkit.  Databases are designed to optimize many cases on their own and yet we know that by asking them questions in different ways and changing the structure of data, performance can vary wildly! The [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=43&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>An application&#8217;s performance can often be improved in many ways, but query optimization should always be near the top of your toolkit.  Databases are designed to optimize many cases on their own and yet we know that by asking them questions in different ways and changing the structure of data, performance can vary wildly!</p>
<p><em>The query itself</em> – Can it be improved?  Can you reduce the  number of joins, return less fields, do less sorting, avoid pagination,  avoid generating temporary tables, make better use of existing indexes?   MySQL’s <a href="http://dev.mysql.com/doc/refman/5.1/en/using-explain.html">EXPLAIN</a> is your friend to help you see what you should improve about your  queries.</p>
<p>Looking at an individual query, SELECTs can be first run through MySQL&#8217;s <a href="http://dev.mysql.com/doc/refman/5.1/en/using-explain.html">EXPLAIN</a>.  The output might look something like:</p>
<pre>*************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: pending
 type: ALL
 possible_keys: mailkey
 key: NULL
 key_len: NULL
 ref: NULL
 rows: 1396998
 Extra: Using where; Using temporary; Using filesort</pre>
<p>Look for your <em>possible_keys</em> and the <em>key</em> that MySQL plans to use for executing your query.  Are there fields you could include in your where clause that might make it quicker to find the row (or rows) that you&#8217;re looking for?</p>
<p>In the query I&#8217;ve referenced, you&#8217;ll notice that no keys are being used (see the <em>key</em> column), and it&#8217;s using a temporary table, and a filesort (both noted in the <em>Extra</em> column).  No matter what anyone tells you, neither of these are intrinsically bad, but if you have too many queries using temporary tables and filesorts across your application, you&#8217;ll quickly need to get more disk I/O bandwidth to handle them or they become a <strong>Hotspot</strong>.</p>
<p>Are you asking the question in the right way?  Can you add an index? Can you eliminate joins?  Can you eliminate subqueries?  Can you delete data to improve performance?</p>
<p>Let&#8217;s walk through an elementary example optimization from start to finish.  We&#8217;ll start with a simple schema:</p>
<pre>CREATE TABLE `test_opt` (
 `id` int(11) NOT NULL auto_increment,
 `owner` int(11) NOT NULL,
 `data` char(40) character set latin1 default NULL,
 PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
<p>This table has three columns and you&#8217;ve been using it to store data for clients.  Each row has an auto-increment <em>id</em>, then a foreign key <em>owner</em> field, finally the data payload in the <em>data</em> field.</p>
<p>We&#8217;ll generate some test data using this small Perl snippet (<strong>test_opt.pl</strong>)</p>
<pre>#!/usr/bin/perl

for ($i = 1; $i&lt;=10000; $i++) {
 print $i%13 . "\t". "payload $i\n";
}</pre>
<p>And the following commands:</p>
<pre>$ perl test_opt.pl &gt; test_opt.tsv
$ mysqlimport -u username -p -c owner,data --local test_opt_db test_opt.tsv</pre>
<p>For more details on <strong>mysqlimport</strong> see the <a href="http://dev.mysql.com/doc/refman/5.1/en/mysqlimport.html">MySQL Manual</a></p>
<p>The primary queries you&#8217;ve been running against this table are single-row SELECTS, and  UPDATES using the PRIMARY KEY <em>id</em>.   Obviously these queries are quite fast.</p>
<pre>mysql&gt; explain select owner,data from test_opt where id=4393\G
*************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: test_opt
 type: const
 possible_keys: PRIMARY
 key: PRIMARY
 key_len: 4
 ref: const
 rows: 1
 Extra:</pre>
<p>The explain for the query shows it&#8217;s using the PRIMARY KEY in the <em>key</em> column.  Since we&#8217;re using InnoDB the <em>rows</em> column is always an estimate, however in this case it knows we&#8217;re using the PRIMARY KEY and so there will be one row.</p>
<p>Even to look up all the rows for a given owner, we start to see a problem.  For example:</p>
<pre>mysql&gt; explain select id, data from test_opt where owner=10\G
*************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: test_opt
 type: ALL
 possible_keys: NULL
 key: NULL
 key_len: NULL
 ref: NULL
 rows: 10269
 Extra: Using where</pre>
<p>You&#8217;ll see MySQL is now showing that <em>possible_keys</em> is <strong>NULL</strong>.  In the <em>Extra</em> field you&#8217;ll see <strong>Using where</strong>.  Since we&#8217;re not using any keys, this is a euphemism for a table scan (hence the 10300 <em>rows</em> estimate)!  If this table had millions of rows, it would scan all of them to show all the entries with the same owner.</p>
<p>In this case, the answer is easy&#8211;add an Index!</p>
<pre>mysql&gt; alter table test_opt add key owner (owner);
Query OK, 10000 rows affected (0.42 sec)
Records: 10000  Duplicates: 0  Warnings: 0</pre>
<p>You&#8217;ll see the explain improve too:</p>
<pre>mysql&gt; explain select id, data from test_opt where owner=10\G
*************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: test_opt
 type: ref
 possible_keys: owner
 key: owner
 key_len: 4
 ref: const
 rows: 768
 Extra:</pre>
<p>Problem solved!</p>
<p>In the real world, problems won&#8217;t always be this simple, but the key is to dig in and see what your options are.  Some challenges you might run into in the real world:</p>
<ol>
<li>There&#8217;s already an index, but the queries are still slow</li>
<li>The table already has a bunch of indexes</li>
<li>The table is too large to add an index without extended downtime</li>
<li>The data isn&#8217;t clean enough for an index to be helpful (particularly when a <strong>UNIQUE</strong> index is appropriate)</li>
</ol>
<p>All of these can be addressed and overcome with creativity and patience.</p>
<p>The keys of optimizing schema boil down to a few questions both when designing schema and evolving it:</p>
<ol>
<li>What data do I need to store?</li>
<li>What questions/queries will be asked of the data &#8212; will it need to be joined, have ownership information, accessed for administrative purposes?</li>
<li>How will the table scale as data grows?</li>
</ol>
<p>I&#8217;m not going to try and cover every trick for getting more out of your database here as that&#8217;s a whole topic in itself.  I will however link to several resources where you can read more about Schema Design, Query Optimization, and Performance Tuning of MySQL feel free to add your own resources in the comments:</p>
<ol>
<li><a href="http://www.joinfu.com/slides/">Jay Pipes</a></li>
<li><a href="http://www.mysqlperformanceblog.com/2008/12/22/goal-driven-performance-optimization/">MySQL Performance Blog</a></li>
</ol>
<p>Making your site faster and more scalable by tuning queries and schema includes art and science so don&#8217;t forget to be persistent and use testing to verify whether your changes are providing the value you expected!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/43/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=43&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2010/06/17/the-query-hunting-for-database-hotspots-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>
	</item>
		<item>
		<title>Do Nothing &#8211; Hunting for Database Hotspots, Part 2</title>
		<link>http://icontactlabs.wordpress.com/2010/06/12/do-nothing-hunting-for-database-hotspots-part-2/</link>
		<comments>http://icontactlabs.wordpress.com/2010/06/12/do-nothing-hunting-for-database-hotspots-part-2/#comments</comments>
		<pubDate>Sat, 12 Jun 2010 02:21:22 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=30</guid>
		<description><![CDATA[This post is part of a series.   Read the Intro if you missed it. As we discussed in the last post, the whole idea of analyzing your database queries is to help speed up your application, reduce database load, and increase your scalability. The easiest decision, is deciding which queries aren&#8217;t worth optimizing. Try commenting [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=30&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is part of a series.   Read the <a href="http://icontactlabs.wordpress.com/2010/05/21/hunting-for-database-hotspots-part-1/">Intro</a> if you missed it.</p>
<p>As we discussed in the last post, the whole idea of analyzing your database queries is to help speed up your application, reduce database load, and increase your scalability.</p>
<p>The easiest decision, is deciding which queries aren&#8217;t worth optimizing.</p>
<p><em>Try commenting the query out</em> &#8211; In a dream world, database queries all take zero time, and cause zero load on the database.  Luckily, in the world of testing we can step into the looking glass!  Try commenting the query out, even put some static data in its place.  This helps you make sure you know how your application would behave if you didn&#8217;t do the query at all.</p>
<p><em>How often is the query run?</em> &#8211; Is the query run often enough to cause enough load for others, or to have an impact on a sizable portion of your users?  If a query takes 10 minutes but is only run 4 times per day, then you&#8217;re really limiting your potential impact of optimization.  Instead of optimizing, can these queries be run in the background and save the results?  Even if you reduce these queries to 1 second each, the overall change in database load is not going to be significant.</p>
<p><em>The query is heavily indexed</em> &#8211; Many of the queries in our application such as loading account data happen many, many times.  However, these queries are also heavily indexed and many of them are in tables that change relatively little.  These queries are very fast, return only a few rows, and run very quickly.  These queries are also typically not doing any sorting or grouping.  These queries are great candidates for caching, but they&#8217;re not likely to affect your database performance.</p>
<p><em>Experiment</em> &#8211; You know your application best, so experiment a bit.  The most important lesson is to check every step along the way that what you thought would help performance is in fact improving.  Even with this warning, large scale applications are complicated and so is their performance.  Sometimes you&#8217;ll spend time optimizing things and find out they didn&#8217;t bear the improvements you wanted.  Make sure you learn from these and consider whether your changes are worth the complexity they&#8217;re introducing or whether you should just roll them back!</p>
<p>Now that we&#8217;ve discussed some quick ways to determine if the queries aren&#8217;t worth optimizing.  Stay tuned for Part 3.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/30/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=30&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2010/06/12/do-nothing-hunting-for-database-hotspots-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>
	</item>
		<item>
		<title>Toolbar for Visibility into Performance</title>
		<link>http://icontactlabs.wordpress.com/2010/06/10/toolbar-for-visibility-into-performance/</link>
		<comments>http://icontactlabs.wordpress.com/2010/06/10/toolbar-for-visibility-into-performance/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 17:17:48 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=35</guid>
		<description><![CDATA[Long ago when I started playing with Symfony I fell in love the with the toolbar that shows up when you&#8217;re running your app in the &#8220;dev&#8221; environment.  The toolbar allows you to see what&#8217;s going on and debug many problems. iContact Labs recently decided to try and bring the toolbar into our home-grown framework [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=35&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Long ago when I started playing with <a href="http://symfony-project.org">Symfony</a> I fell in love the with the toolbar that shows up when you&#8217;re running your app in the &#8220;dev&#8221; environment.  The toolbar allows you to see what&#8217;s going on and debug many problems.</p>
<p>iContact Labs recently decided to try and bring the toolbar into our home-grown framework and codebase so our developers could get similar feedback.  Luckily, we found out someone had done most of the work for us!  Some smart folks have extracted and older version of the Symfony toolbar and packaged it for inclusion in your project &#8212; called <a href="http://phpdebug.sourceforge.net/www/index.html">PHP Debug</a>.</p>
<p>If you&#8217;re starting your own project, I&#8217;d recommend using Symfony or another framework that has a drop-in toolbar available.  There&#8217;s a toolbar plugin for Zend Framework called <a href="http://code.google.com/p/zfdebug/">ZFDebug</a>.</p>
<p>We integrated the toolbar into our existing code for profiling database connections and doing logging (using <a href="http://logging.apache.org/log4php/index.html">Log4PHP</a>).</p>
<p>The information in the toolbar allows the developer to have data right at their fingertips for understanding both the baseline, and changed state for any page they&#8217;re working on or any new page they&#8217;re creating.  Having logging information at their fingertips also improves the quality of that information.</p>
<p>We&#8217;re starting to look at the data shown by the toolbar every time we commit new code.  For example:</p>
<ol>
<li>How long does the page take to generate?</li>
<li>How much memory does it consume?</li>
<li>Are the log messages useful?</li>
<li>How does the page perform on different sized data sets?</li>
<li>How does the page load the second, third&#8230; time.  Does it use caching effectively?</li>
</ol>
<p>Having this information right at our fingertips will be pivotal to continuing to improve the performance, quality, and scalability of everything we write.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/35/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=35&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2010/06/10/toolbar-for-visibility-into-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>
	</item>
		<item>
		<title>Tracking Contacts &#8211; Results</title>
		<link>http://icontactlabs.wordpress.com/2010/05/31/tracking-contacts-results/</link>
		<comments>http://icontactlabs.wordpress.com/2010/05/31/tracking-contacts-results/#comments</comments>
		<pubDate>Mon, 31 May 2010 01:15:26 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=9</guid>
		<description><![CDATA[Sometimes the best way to speed something up is to slow other things down. We&#8217;d been having issues of overloaded database connections due to queries running too slowly on one of our shards/engines.    We discovered that one of the major challenges creating heavy load on our database servers was all the subscribers opening and clicking [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=9&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Sometimes the best way to speed something up is to slow other things down. We&#8217;d been having issues of overloaded database connections due to queries running too slowly on one of our shards/engines.    We discovered that one of the major challenges creating heavy load on our database servers was all the subscribers opening and clicking the messages sent by the users on that shard.  Especially when a large client would send out an email blast, we&#8217;d get a large surge of opens and clicks and struggle to handle them all at the same time.</p>
<p>We worked to change opens and clicks to process in the background using what&#8217;s called a Message Queue in between.  The side effect is that sometimes we&#8217;ll see a slight delay in processing opens and clicks.  We&#8217;ll be monitoring the latency of the opens clicks.</p>
<p>The week after we deployed this change, we started to see the benefit immediately.  <span id="more-9"></span>The load for the databases decreased, and the opens and clicks buffered as designed.  During the first few days we saw as much as 30-45 minute delays in processing during some high traffic periods.  However, we saw no issues in the DB4 cluster which we&#8217;d been seeing consistent issues for weeks.  While these delays aren&#8217;t ideal, the fact that this cluster of opens and clicks didn&#8217;t bring down the database servers was a beautiful new trend.</p>
<p>Here you can see some of the buildup of opens and clicks during the first week, which created some processing delays for customers that weren&#8217;t within our tolerance, but we fixed those the following day by increasing the number of threads we had processing.  These days we see much lower queues, and only during very peak times do we see delays of &gt; 1 minute.</p>
<p><a href="http://icontactlabs.files.wordpress.com/2010/05/beanstalk-job-buildup.png"><img title="beanstalk job buildup" src="http://icontactlabs.files.wordpress.com/2010/05/beanstalk-job-buildup.png?w=300&#038;h=135" alt="" width="300" height="135" /></a></p>
<p>Here&#8217;s the number of connections during the two week period before and after this was released.  You can see a decrease in the active connections and far less spikes in connections for the machine.  This means more responsiveness to customers and no running out of connections!</p>
<p><a href="http://icontactlabs.files.wordpress.com/2010/05/dbconnections-w_-beanstalk.png"><img class="alignnone size-medium wp-image-11" title="dbconnections w_ beanstalk" src="http://icontactlabs.files.wordpress.com/2010/05/dbconnections-w_-beanstalk.png?w=300&#038;h=225" alt="" width="300" height="225" /></a></p>
<p>And a side benefit is that last week when we were experiencing database downtime, due to some corruption.  During this potential disaster, the silver lining was that we were able to build up a queue of 800,000 opens and clicks with delay being the only customer-impact.  In previous instances, we would have had to reap the Apache logs to process these opens and clicks.</p>
<p><a href="http://icontactlabs.files.wordpress.com/2010/05/message-queue-buildup-with-database-issues.png"><img title="message queue buildup  with database issues" src="http://icontactlabs.files.wordpress.com/2010/05/message-queue-buildup-with-database-issues.png?w=300&#038;h=106" alt="" width="300" height="106" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/9/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=9&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2010/05/31/tracking-contacts-results/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>

		<media:content url="http://icontactlabs.files.wordpress.com/2010/05/beanstalk-job-buildup.png?w=300" medium="image">
			<media:title type="html">beanstalk job buildup</media:title>
		</media:content>

		<media:content url="http://icontactlabs.files.wordpress.com/2010/05/dbconnections-w_-beanstalk.png?w=300" medium="image">
			<media:title type="html">dbconnections w_ beanstalk</media:title>
		</media:content>

		<media:content url="http://icontactlabs.files.wordpress.com/2010/05/message-queue-buildup-with-database-issues.png?w=300" medium="image">
			<media:title type="html">message queue buildup  with database issues</media:title>
		</media:content>
	</item>
		<item>
		<title>Hunting for Database Hotspots, Part 1</title>
		<link>http://icontactlabs.wordpress.com/2010/05/21/hunting-for-database-hotspots-part-1/</link>
		<comments>http://icontactlabs.wordpress.com/2010/05/21/hunting-for-database-hotspots-part-1/#comments</comments>
		<pubDate>Fri, 21 May 2010 01:14:42 +0000</pubDate>
		<dc:creator>dcrasch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://icontactlabs.wordpress.com/?p=19</guid>
		<description><![CDATA[When running something like mk-query-digest or our home-grown querysniffer, we like to ask three questions to give us a list of potential database hotspots in our application. Which queries are run the most often? Which queries take the longest when run? Which queries take the most database time overall? There are many results you&#8217;d expect [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=19&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When running something like <strong><a href="http://www.maatkit.org/doc/mk-query-digest.html">mk-query-digest</a></strong> or our home-grown <strong><a href="http://iank.org/querysniffer/">querysniffer</a></strong>, we like to ask three questions to give us a list of potential database hotspots in our application.</p>
<ol>
<li>Which queries are run the most often?</li>
<li>Which queries take the longest when run?</li>
<li>Which queries take the most database time overall?</li>
</ol>
<p>There are many results you&#8217;d expect to see common among many web applications when looking at the list including:</p>
<ul>
<li><strong>sessions</strong> &#8211; figuring out if the given user is logged in, and loading up their session</li>
<li><strong>logins</strong> &#8211; processing a login and assigning a user into a session</li>
<li><strong>permissions</strong> &#8211; should a user be allowed to access a given page</li>
<li><strong>billing checks</strong> &#8211; figuring out if a customer has paid</li>
</ul>
<p>For each of the queries we get on the list, the key is coming up with a plan of attack and prioritized list of improvement areas.</p>
<p><strong>There are several potential attack areas for a given query:<br />
</strong><em>Do nothing, it doesn&#8217;t matter </em>- The query is run often, but doesn&#8217;t really generate much load.  Queries that frequently run on tables that don&#8217;t change much can get cached by the MySQL query cache.  Queries with really low average execution times are often unlikely to yield high-impact optimizations or are already cached by MySQL.<br />
<em> </em></p>
<p><em>The query itself</em> &#8211; Can it be improved?  Can you reduce the number of joins, return less fields, do less sorting, avoid pagination, avoid generating temporary tables, make better use of existing indexes?  MySQL&#8217;s <a href="http://dev.mysql.com/doc/refman/5.1/en/using-explain.html">EXPLAIN</a> is your friend to help you see what you should improve about your queries.</p>
<p><em>The application</em> &#8211; How can the application work with the database to improve performance?  Can you eliminate the query entirely by not providing some data to the user?  Can you show different but easier to calculate data?  Can you reduce the frequency with which it&#8217;s accessed by moving more expensive data into drill-down pages rather than on dashboards?</p>
<p><em>Caching</em> &#8211; This is actually related to your application, but deserves a category of its own.  How often does the data change? Does the user need the most up-to-date version?  Do you know when the data changes and you could invalidate the cache?</p>
<p><em>Writes</em> &#8211; Can you batch them? Can you do them <a href="http://icontactlabs.wordpress.com/2010/05/31/tracking-contacts-results/">later</a>?</p>
<p>In future posts, we&#8217;ll be delving into each of these areas to get more specific.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/icontactlabs.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/icontactlabs.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/icontactlabs.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/icontactlabs.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/icontactlabs.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/icontactlabs.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/icontactlabs.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/icontactlabs.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/icontactlabs.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/icontactlabs.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/icontactlabs.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/icontactlabs.wordpress.com/19/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/icontactlabs.wordpress.com/19/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/icontactlabs.wordpress.com/19/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=icontactlabs.wordpress.com&amp;blog=12399081&amp;post=19&amp;subd=icontactlabs&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://icontactlabs.wordpress.com/2010/05/21/hunting-for-database-hotspots-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c3ca7c8076675d18baa48e3682e23d77?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dcrasch</media:title>
		</media:content>
	</item>
	</channel>
</rss>
