Index: wp-includes/query.php
===================================================================
--- wp-includes/query.php	(revision 24340)
+++ wp-includes/query.php	(working copy)
@@ -2742,21 +2742,30 @@
 
 		// Put sticky posts at the top of the posts array
 		$sticky_posts = get_option('sticky_posts');
-		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
-			$num_posts = count($this->posts);
+		
+		// Base sticky posts limit on Posts per Page setting
+		$posts_per_page = (int) get_option( 'posts_per_page' );
+		if ( empty( $posts_per_page ) || $posts_per_page < 1 )
+			$posts_per_page = 20;
+		
+		if ( $this->is_home && $page <= 1 && is_array( $sticky_posts ) && ! empty( $sticky_posts ) && ! $q['ignore_sticky_posts'] ) {
+			
+			$sticky_posts = array_slice( $sticky_posts, 0, apply_filters( 'sticky_posts_home_query_limit', 10 * $posts_per_page ) ); // sanity limit
+			$num_posts = count( $this->posts );
 			$sticky_offset = 0;
+			
 			// Loop over posts and relocate stickies to the front.
 			for ( $i = 0; $i < $num_posts; $i++ ) {
-				if ( in_array($this->posts[$i]->ID, $sticky_posts) ) {
+				if ( in_array( $this->posts[$i]->ID, $sticky_posts ) ) {
 					$sticky_post = $this->posts[$i];
 					// Remove sticky from current position
-					array_splice($this->posts, $i, 1);
+					array_splice( $this->posts, $i, 1 );
 					// Move to front, after other stickies
-					array_splice($this->posts, $sticky_offset, 0, array($sticky_post));
+					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
 					// Increment the sticky offset. The next sticky will be placed at this offset.
 					$sticky_offset++;
 					// Remove post from sticky posts array
-					$offset = array_search($sticky_post->ID, $sticky_posts);
+					$offset = array_search( $sticky_post->ID, $sticky_posts );
 					unset( $sticky_posts[$offset] );
 				}
 			}
