I've written a plugin which retrieves an xml file, parses and creates a series of short posts from the content.

Although each post is very short (sometimes just a single sentence, never more than a few sentences), there are around 1000 posts to create from the file.

Using wp_insert_post takes enough time for this job to timeout giving a 500 status.

I also encounter similar problems when deactivating the plugin and trying to move the same content.

Are there any quicker ways of populating (or removing) posts?

2 Answers 2


You can access the database with an INSERT statement and add multiple rows at once.

Something like this pseudo-code:

INSERT INTO $wpdb->posts (
    ( $user_id, $current_date,$current_date_gmt, $content1 ),
    ( $user_id, $current_date,$current_date_gmt, $content2 ),
    ( $user_id, $current_date,$current_date_gmt, $content3 )

Make sure to fill all the values that are set to NOT NULL and have no default value in the post table schema.
From wp-admin/includes/schema.php:

CREATE TABLE $wpdb->posts (
  ID bigint(20) unsigned NOT NULL auto_increment,
  post_author bigint(20) unsigned NOT NULL default '0',
  post_date datetime NOT NULL default '0000-00-00 00:00:00',
  post_date_gmt datetime NOT NULL default '0000-00-00 00:00:00',
  post_content longtext NOT NULL,
  post_title text NOT NULL,
  post_excerpt text NOT NULL,
  post_status varchar(20) NOT NULL default 'publish',
  comment_status varchar(20) NOT NULL default 'open',
  ping_status varchar(20) NOT NULL default 'open',
  post_password varchar(20) NOT NULL default '',
  post_name varchar(200) NOT NULL default '',
  to_ping text NOT NULL,
  pinged text NOT NULL,
  post_modified datetime NOT NULL default '0000-00-00 00:00:00',
  post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00',
  post_content_filtered longtext NOT NULL,
  post_parent bigint(20) unsigned NOT NULL default '0',
  guid varchar(255) NOT NULL default '',
  menu_order int(11) NOT NULL default '0',
  post_type varchar(20) NOT NULL default 'post',
  post_mime_type varchar(100) NOT NULL default '',
  comment_count bigint(20) NOT NULL default '0',
  KEY post_name (post_name),
  KEY type_status_date (post_type,post_status,post_date,ID),
  KEY post_parent (post_parent),
  KEY post_author (post_author)
) $charset_collate;\n";

Also, regular posts need a default category. Not sure what happens if you omit that.

  • Thanks - any gotchas I should look out for with this approach? (i.e. what is it that wp_insert_post is protecting me from mucking up?) Dec 11, 2012 at 10:38
  • @OwenStephens See my update.
    – fuxia
    Dec 11, 2012 at 11:10
  • It's just $wpdb->posts, not $wpdb->prefix.posts. +1 anyway.
    – kaiser
    Dec 11, 2012 at 11:16
  • Another thing: Normally there's a callback incrementing the count for posts for a tag or a category. You'll have to also add that manually, when looping through.
    – kaiser
    Dec 11, 2012 at 11:17

Not using the API might save you a minute now but cost you hours later. I have done similiar things and run into timeouts but not 500, you should realy check the php and appache logs first to try and find the cuase.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.