The following code can be used to have separate value of posts per page for various archive pages (category, tag, date, author, etc.)
add_filter('pre_option_posts_per_page', 'posts_per_page_filter');
function posts_per_page_filter() {
if ( is_archive() ) {
// date,tag
if (is_date() || is_tag() ) {
return 30;
}
if (is_category() ) {
return 20;
}
}
return 10; // default
}