diff --git a/README.txt b/README.txt
index 1b81b28..cff57d7 100644
--- a/README.txt
+++ b/README.txt
@@ -96,6 +96,28 @@ Configuration Variables
     ),
   );
 
+  As of the mongoDB 1.3 php driver slave_ok has been deprecated and instead
+  read preferences should be used when dealing with a replica set. These
+  preferences can be set at a connection or collection level see below for the
+  collection information.
+
+  $conf['mongodb_connections'] = array(
+    // Connection name/alias
+    'slave' => array(
+      'host' => 'slave1',
+      // Database name
+      'db' => 'drupal_default',
+      'read_preference' => array(
+        'preference' => 'secondaryPreferred',
+        'tags' => array(
+          array('dc' => 'east', 'use' => 'reporting'),
+          array('dc' => 'west'),
+        ),
+      ),
+      'connection_options' => array('replicaSet' => 'main'),
+    ),
+  );
+
 #2: mongodb_debug
 
   A variable primarily for developers, mongodb_debug causes a collection
@@ -189,6 +211,22 @@ the hypothetical connection alias 'logginghost'
 EXAMPLE:
 $conf['mongodb_collections'] = array('watchdog' => 'logginghost');
 
+If you are using the 1.3 drivers you can specify the following connection
+options db_connection and read_preference. These options allow to control
+collection level mongo read preferences and whether any tags should be used.
+
+$conf['mongodb_collections'] = array(
+  'watchdog' => array(
+    db_connection => 'logginghost',
+    'read_preference' => array(
+      'preference' => 'secondaryPreferred',
+      'tags' => array(
+        array('dc' => 'east', 'use' => 'reporting'),
+        array('dc' => 'west'),
+      ),
+    ),
+  ),
+);
 
 MODULE-SPECIFIC CONFIGURATION
 ------------
diff --git a/mongodb.drush.inc b/mongodb.drush.inc
index 840d36b..1da24f3 100644
--- a/mongodb.drush.inc
+++ b/mongodb.drush.inc
@@ -113,7 +113,7 @@ function drush_mongodb_query($alias = 'default', $query = '') {
 }
 
 /**
- * Returns the basic shell commando string.
+ * Returns the basic shell command string.
  */
 function _drush_mongodb_connect($alias) {
   $connections = variable_get('mongodb_connections', array());
diff --git a/mongodb.module b/mongodb.module
index 69cf3b1..8fd8ff9 100644
--- a/mongodb.module
+++ b/mongodb.module
@@ -31,9 +31,22 @@ function mongodb($alias = 'default') {
   $db = $connection['db'];
   if (!isset($mongo_objects[$host][$db])) {
     try {
-      $mongo = new Mongo($host, $options);
-      if (!empty($connection['slave_ok'])) {
-        $mongo->setSlaveOkay(TRUE);
+      // Use the 1.3 client if available.
+      if (class_exists('MongoClient')) {
+        $mongo = new MongoClient($host, $options);
+        // Enable read preference and tags if provided. This can also be
+        // controlled on a per query basis at the cursor level if more control
+        // is required.
+        if (!empty($connection['read_preference'])) {
+          $tags = !empty($connection['read_preference']['tags']) ? $connection['read_preference']['tags'] : array();
+          $mongo->setReadPreference($connection['read_preference']['preference'], $tags);
+        }
+      }
+      else {
+        $mongo = new Mongo($host, $options);
+        if (!empty($connection['slave_ok'])) {
+          $mongo->setSlaveOkay(TRUE);
+        }
       }
       $mongo_objects[$host][$db] = $mongo->selectDB($db);
       $mongo_objects[$host][$db]->connection = $mongo;
@@ -61,12 +74,25 @@ function mongodb_collection() {
     $prefixed = mongodb_collection_name($collection_name);
   }
   $collections = variable_get('mongodb_collections', array());
-  $alias = isset($collections[$collection_name]) ? $collections[$collection_name] : 'default';
+  if (isset($collections[$collection_name])) {
+    // We might be dealing with an array or string because of need to preserve
+    // backwards comptability.
+    $alias = !empty($collections[$collection_name]['db_connection']) ? $collections[$collection_name]['db_connection'] : $collections[$collection_name];
+  }
+  else {
+    $alias = 'default';
+  }
   // Prefix the collection name for simpletest. It will be in the same DB as the
   // non-prefixed version so it's enough to prefix after choosing the mongodb
   // object.
   $mongodb_object = mongodb($alias);
   $collection = $mongodb_object->selectCollection(mongodb_collection_name($collection_name));
+  // Enable read preference and tags at a collection level if we have 1.3
+  // client.
+  if (!empty($collections[$alias]['read_preference']) && get_class($mongodb_object->connection) == 'MongoClient') {
+    $tags = !empty($collections[$alias]['read_preference']['tags']) ? $collections[$alias]['read_preference']['tags'] : array();
+    $collection->setReadPreference($collections[$alias]['read_preference']['preference'], $tags);
+  }
   $collection->connection = $mongodb_object->connection;
   return variable_get('mongodb_debug', FALSE) ? new mongoDebugCollection($collection) : $collection;
 }
@@ -158,7 +184,12 @@ function mongodb_test_group_finished() {
  */
 function mongodb_set_active_connection($alias, $connection_name = 'default') {
   // No need to check if the connection is valid as mongodb() does this.
-  $GLOBALS['conf']['mongodb_collections'][$alias] = $connection_name;
+  if (!empty($GLOBALS['conf']['mongodb_collections'][$alias]['db_connection'])) {
+    $GLOBALS['conf']['mongodb_collections'][$alias]['db_connection'] = $connection_name;
+  }
+  else {
+    $GLOBALS['conf']['mongodb_collections'][$alias] = $connection_name;
+  }
 }
 
 /**
diff --git a/mongodb_block/mongodb_block.module b/mongodb_block/mongodb_block.module
index cc38270..25c19ab 100644
--- a/mongodb_block/mongodb_block.module
+++ b/mongodb_block/mongodb_block.module
@@ -300,7 +300,7 @@ function _mongodb_block_rehash($theme) {
       mongodb_block_save_block($collection, $block);
     }
   }
-  $collection->remove(array('_id' => array('$nin' => $ids)));
+  $collection->remove(array('_id' => array('$nin' => $ids)), array('safe' => TRUE));
   return $blocks;
 }
 
@@ -314,7 +314,7 @@ function _mongodb_block_rehash($theme) {
  */
 function mongodb_block_save_block($collection, $block) {
   unset($block['module'], $block['delta'], $block['status']);
-  $collection->save($block);
+  $collection->save($block, array('safe' => TRUE));
 }
 
 /**
diff --git a/mongodb_block_ui/mongodb_block_ui.admin.inc b/mongodb_block_ui/mongodb_block_ui.admin.inc
index b2fc90f..0508a5c 100644
--- a/mongodb_block_ui/mongodb_block_ui.admin.inc
+++ b/mongodb_block_ui/mongodb_block_ui.admin.inc
@@ -144,7 +144,7 @@ function mongodb_block_ui_admin_display_form_submit($form, &$form_state) {
         'weight' => (int) $block['weight'],
         'region' => $block['region'],
       );
-      $collection->update($find, array('$set' => $set), array('upsert' => TRUE));
+      $collection->update($find, array('$set' => $set), array('upsert' => TRUE, 'safe' => TRUE));
     }
   }
   drupal_set_message(t('The block settings have been updated.'));
@@ -366,7 +366,7 @@ function mongodb_block_ui_admin_configure_submit($form, &$form_state) {
     'title' => $form_state['values']['title'],
   );
   // This way region and weight is preserved.
-  $collection->update(array('_id' => $id), array('$set' => $customized), array('upsert' => TRUE));
+  $collection->update(array('_id' => $id), array('$set' => $customized), array('upsert' => TRUE, 'safe' => TRUE));
 
   // Ensure that custom blocks have their settings saved.
   // @todo: this should probably be done via hook_block_configure().
@@ -377,7 +377,7 @@ function mongodb_block_ui_admin_configure_submit($form, &$form_state) {
       'info' => $form_state['values']['info'],
       'title' => $form_state['values']['title'],
     );
-    mongodb_collection('block_custom')->save($block);
+    mongodb_collection('block_custom')->save($block, array('safe' => TRUE));
   }
   module_invoke($form_state['values']['module'], 'block_save', $form_state['values']['delta'], $form_state['values']);
   drupal_set_message(t('The block configuration has been saved.'));
@@ -463,7 +463,7 @@ function mongodb_block_ui_add_block_form_submit($form, &$form_state) {
     'info' => $form_state['values']['info'],
     'title' => $form_state['values']['title'],
   );
-  $collection->insert($block);
+  $collection->insert($block, array('safe' => TRUE));
   drupal_set_message(t('The block has been created.'));
   cache_clear_all();
   $theme = $form['#theme_key'];
@@ -491,14 +491,14 @@ function mongodb_block_ui_custom_block_delete($form, &$form_state, $theme, $modu
  */
 function mongodb_block_ui_custom_block_delete_submit($form, &$form_state) {
   // Remove the custom block.
-  mongodb_collection('block_custom')->remove(array('_id' => $form_state['values']['delta']));
+  mongodb_collection('block_custom')->remove(array('_id' => $form_state['values']['delta']), array('safe' => TRUE));
   // Also remove customization for every theme.
   $id = array(
     'module' => $form_state['values']['module'],
     'delta' => $form_state['values']['delta'],
   );
   foreach (list_themes() as $theme) {
-    mongodb_collection('block_customized', $theme->name)->remove(array('_id' => $id));
+    mongodb_collection('block_customized', $theme->name)->remove(array('_id' => $id), array('safe' => TRUE));
   }
   drupal_set_message(t('The block %name has been removed.', array('%name' => $form_state['values']['info'])));
   cache_clear_all();
diff --git a/mongodb_block_ui/mongodb_block_ui.module b/mongodb_block_ui/mongodb_block_ui.module
index 871050f..a068439 100644
--- a/mongodb_block_ui/mongodb_block_ui.module
+++ b/mongodb_block_ui/mongodb_block_ui.module
@@ -237,12 +237,7 @@ function mongodb_block_ui_custom_block_form($edit = array()) {
  * Implements hook_menu_delete().
  */
 function mongodb_block_ui_menu_delete($menu) {
-  $collection = mongodb_collection('block_custom');
-
-  $collection->remove(array(
-    'module' => 'menu',
-    'delta' => $menu['menu_name'],
-  ));
+  $collection->delete(array('module' => 'menu', 'delta' => $menu['menu_name']), array('safe' => TRUE));
 }
 
 /**
diff --git a/mongodb_cache/mongodb_cache.inc b/mongodb_cache/mongodb_cache.inc
index e137be6..a3b5be8 100644
--- a/mongodb_cache/mongodb_cache.inc
+++ b/mongodb_cache/mongodb_cache.inc
@@ -67,7 +67,7 @@ class DrupalMongoDBCache implements DrupalCacheInterface {
 
 
       $find = array('expire' => array('$lte' => $cache_flush, '$ne' => CACHE_PERMANENT));
-      $collection->remove($find);
+      $collection->remove($find, array('w' => 0));
     }
   }
 
@@ -133,7 +133,7 @@ class DrupalMongoDBCache implements DrupalCacheInterface {
 
     try {
       $collection = mongodb_collection($this->bin);
-      $collection->save($entry);
+      $collection->save($entry, array('w' => 0));
     }
     catch (Exception $e) {
       // The database may not be available, so we'll ignore cache_set requests.
@@ -162,13 +162,13 @@ class DrupalMongoDBCache implements DrupalCacheInterface {
           // Clear the cache for everyone, cache_lifetime seconds have
           // passed since the first request to clear the cache.
 
-          $collection->remove(array('expire' => array('$ne' => CACHE_PERMANENT, '$lte' => REQUEST_TIME)));
+          $collection->remove(array('expire' => array('$ne' => CACHE_PERMANENT, '$lte' => REQUEST_TIME)), array('w' => 0));
           variable_set('cache_flush_' . $this->bin, 0);
         }
       }
       else {
         // No minimum cache lifetime, flush all temporary cache entries now.
-        $collection->remove(array('expire' => array('$ne' => CACHE_PERMANENT, '$lte' => REQUEST_TIME)));
+        $collection->remove(array('expire' => array('$ne' => CACHE_PERMANENT, '$lte' => REQUEST_TIME)), array('w' => 0));
       }
     }
     else {
@@ -177,19 +177,19 @@ class DrupalMongoDBCache implements DrupalCacheInterface {
           $collection->remove();
         }
         else {
-          $collection->remove(array('cid' => new MongoRegex('/' . preg_quote($cid) . '.*/')));
+          $collection->remove(array('cid' => new MongoRegex('/'. preg_quote($cid) .'.*/')), array('w' => 0));
         }
       }
       elseif (is_array($cid)) {
         // Delete in chunks when a large array is passed.
         do {
           $find = array('cid' => array('$in' => array_map('strval', array_splice($cid, 0, 1000))));
-          $collection->remove($find);
+          $collection->remove($find, array('w' => 0));
         }
         while (count($cid));
       }
       else {
-        $collection->remove(array('_id' => (string)$cid));
+        $collection->remove(array('_id' => (string)$cid), array('w' => 0));
       }
     }
   }
diff --git a/mongodb_field_storage/mongodb_field_storage.module b/mongodb_field_storage/mongodb_field_storage.module
index 1be9622..ab6c42b 100644
--- a/mongodb_field_storage/mongodb_field_storage.module
+++ b/mongodb_field_storage/mongodb_field_storage.module
@@ -247,13 +247,9 @@ function _mongodb_field_storage_value($type, $value) {
 function mongodb_field_storage_field_storage_delete($entity_type, $entity, $fields) {
   list($entity_id, $revision_id, $bundle) = entity_extract_ids($entity_type, $entity);
 
-  mongodb_collection('fields_current', $entity_type)->remove(array(
-    '_id' => (int) $entity_id,
-  ));
+  mongodb_collection('fields_current', $entity_type)->remove(array('_id' => (int) $entity_id), array('safe' => TRUE));
   $entity_info = entity_get_info($entity_type);
-  mongodb_collection('fields_revision', $entity_type)->remove(array(
-    $entity_info['entity keys']['id'] => (int) $entity_id,
-  ));
+  mongodb_collection('fields_revision', $entity_type)->remove(array($entity_info['entity keys']['id'] => (int) $entity_id), array('safe' => TRUE));
 }
 
 /**
@@ -263,9 +259,7 @@ function mongodb_field_storage_field_storage_delete($entity_type, $entity, $fiel
  */
 function mongodb_field_storage_field_storage_delete_revision($entity_type, $entity, $fields) {
   list($entity_id, $revision_id, $bundle) = entity_extract_ids($entity_type, $entity);
-  mongodb_collection('fields_revision', $entity_type)->remove(array(
-    '_id' => (int) $revision_id,
-  ));
+  mongodb_collection('fields_revision', $entity_type)->remove(array('_id' => (int) $revision_id), array('safe' => TRUE));
 }
 
 /**
@@ -472,8 +466,8 @@ function _mongodb_field_storage_query_value($value, $operator, $type) {
  * Implements hook_field_attach_rename_bundle().
  */
 function mongodb_field_storage_field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) {
-  mongodb_collection('fields_current', $entity_type)->update(array('_bundle' => $bundle_old), array('_bundle' => $bundle_new), array('multiple' => TRUE));
-  mongodb_collection('fields_revision', $entity_type)->update(array('_bundle' => $bundle_old), array('_bundle' => $bundle_new), array('multiple' => TRUE));
+  mongodb_collection('fields_current', $entity_type)->update(array('_bundle' => $bundle_old), array('_bundle' => $bundle_new), array('multiple' => TRUE), array('safe' => TRUE));
+  mongodb_collection('fields_revision', $entity_type)->update(array('_bundle' => $bundle_old), array('_bundle' => $bundle_new), array('multiple' => TRUE), array('safe' => TRUE));
 }
 
 /**
@@ -495,9 +489,9 @@ function mongodb_field_storage_entity_update($entity, $entity_type) {
  */
 function mongodb_field_storage_field_attach_delete($entity_type, $entity) {
   list($entity_id, $revision_id) = entity_extract_ids($entity_type, $entity);
-  mongodb_collection('fields_current', $entity_type)->remove(array('_id' => (int) $entity_id));
+  mongodb_collection('fields_current', $entity_type)->remove(array('_id' => (int) $entity_id), array('safe' => TRUE));
   if ($revision_id) {
-    mongodb_collection('fields_revision', $entity_type)->remove(array('_id' => (int) $revision_id));
+    mongodb_collection('fields_revision', $entity_type)->remove(array('_id' => (int) $revision_id), array('safe' => TRUE));
   }
 }
 
diff --git a/mongodb_queue/mongodb_queue.inc b/mongodb_queue/mongodb_queue.inc
index 0d8f8c3..a3d728e 100644
--- a/mongodb_queue/mongodb_queue.inc
+++ b/mongodb_queue/mongodb_queue.inc
@@ -35,7 +35,7 @@ class MongoDBQueue implements DrupalQueueInterface {
       'expire' => 0,
     );
     return mongodb_collection($this->collection)
-      ->insert($item);
+      ->insert($item, array('safe' => TRUE));
   }
 
   /**
@@ -85,7 +85,7 @@ class MongoDBQueue implements DrupalQueueInterface {
    */
   public function releaseItem($item) {
     return mongodb_collection($this->collection)
-      ->update(array('_id' => $item->_id), array('$set' => array('expire' => 0)));
+      ->update(array('_id' => $item->_id), array('$set' => array('expire' => 0)), array('safe' => TRUE));
   }
 
   /**
@@ -96,7 +96,7 @@ class MongoDBQueue implements DrupalQueueInterface {
    */
   public function deleteItem($item) {
     mongodb_collection($this->collection)
-      ->remove(array('_id' => $item->_id));
+      ->remove(array('_id' => $item->_id), array('safe' => TRUE));
   }
 
   /**
diff --git a/mongodb_queue/mongodb_queue.module b/mongodb_queue/mongodb_queue.module
index 5bd9f53..520bbf2 100644
--- a/mongodb_queue/mongodb_queue.module
+++ b/mongodb_queue/mongodb_queue.module
@@ -32,7 +32,7 @@ function mongodb_queue_cron() {
       if (strpos($collection_name, '$') === FALSE && substr($collection_name, 0, $n) == "$db.") {
         // Split off the name of the database.
         $db->selectCollection(substr($collection_data['name'], $n))
-          ->update($update_query, array('$set' => array('expire' => 0)), array('multiple' => TRUE));
+          ->update($update_query, array('$set' => array('expire' => 0)), array('multiple' => TRUE, 'safe' => TRUE));
       }
     }
   }
diff --git a/mongodb_session/mongodb_session.inc b/mongodb_session/mongodb_session.inc
index 8ee72ac..b22f481 100644
--- a/mongodb_session/mongodb_session.inc
+++ b/mongodb_session/mongodb_session.inc
@@ -179,7 +179,7 @@ function _drupal_session_write($sid, $value) {
 
   $collection = mongodb_collection(variable_get('mongodb_session', 'session'));
   $collection
-    ->update($key, $key + $fields, array('upsert' => TRUE));
+    ->update($key, $key + $fields, array('upsert' => TRUE, 'w' => 0));
 
   // Last access time is updated no more frequently than once every 180 seconds.
   // This reduces contention in the users table.
@@ -193,7 +193,7 @@ function _drupal_session_write($sid, $value) {
       ->condition('uid', $user->uid)
       ->execute();
     // Update MongoDB because we prefer that.
-    mongodb_collection('fields_current', 'user')->update(array('_id' => (int) $user->uid), array('$set' => $fields));
+    mongodb_collection('fields_current', 'user')->update(array('_id' => (int) $user->uid), array('$set' => $fields), array('w' => 0));
     // Throw a bone to entitycache, too.
     if (variable_get('entitycache_enabled', FALSE)) {
       cache_clear_all($user->uid, 'cache_entity_user');
@@ -349,7 +349,7 @@ function drupal_session_regenerate() {
   if (isset($old_session_id)) {
     $field = $is_https ? 'ssid' : 'sid';
     mongodb_collection(variable_get('mongodb_session', 'session'))
-      ->update(array('sid' => $old_session_id), array('$set' => array($field => session_id())));
+      ->update(array('sid' => $old_session_id), array('$set' => array($field => session_id())), array('w' => 0));
   }
 }
 
@@ -366,7 +366,7 @@ function _drupal_session_destroy($sid) {
 
   $field = $is_https ? 'ssid' : 'sid';
   mongodb_collection(variable_get('mongodb_session', 'session'))
-    ->remove(array($field => $sid));
+    ->remove(array($field => $sid), array('w' => 0));
 
   // Reset $_SESSION and $user to prevent a new session from being started
   // in drupal_session_commit().
@@ -411,7 +411,7 @@ function _drupal_session_delete_cookie($name, $secure = NULL) {
  */
 function drupal_session_destroy_uid($uid) {
   mongodb_collection(variable_get('mongodb_session', 'session'))
-    ->remove(array('uid' => $uid));
+    ->remove(array('uid' => $uid), array('w' => 0));
 }
 
 /**
@@ -430,7 +430,7 @@ function _drupal_session_garbage_collection($lifetime) {
   // to '1814400'. At that value, only after a user doesn't log in after
   // three weeks (1814400 seconds) will his/her session be removed.
   mongodb_collection(variable_get('mongodb_session', 'session'))
-    ->remove(array('timestamp' => array('$lt' => REQUEST_TIME - $lifetime)));
+    ->remove(array('timestamp' => array('$lt' => REQUEST_TIME - $lifetime)), array('w' => 0));
   return TRUE;
 }
 
diff --git a/mongodb_watchdog/mongodb_watchdog.module b/mongodb_watchdog/mongodb_watchdog.module
index 1e61bda..b7045cf 100644
--- a/mongodb_watchdog/mongodb_watchdog.module
+++ b/mongodb_watchdog/mongodb_watchdog.module
@@ -111,7 +111,7 @@ function mongodb_watchdog_watchdog(array $log_entry) {
   );
   $collection = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'));
   $id = md5($log_entry['function'] . ':' . $log_entry['line'] . ':' . $log_entry['severity'] . ':' . $log_entry['type'] . ':' . $log_entry['message']);
-  $collection->update(array('_id' => $id), $newobj, array('upsert' => TRUE));
+  $collection->update(array('_id' => $id), $newobj, array('upsert' => TRUE, 'safe' => TRUE));
   $result = $collection->db->command(array('getlasterror' => 1));
   $collection = $collection->db->selectCollection('watchdog_event_' . $id);
   if (empty($result['updatedExisting'])) {
@@ -119,7 +119,7 @@ function mongodb_watchdog_watchdog(array $log_entry) {
     $command = array('create' => $collection->getName(), 'capped' => TRUE, 'size' => $max * 1000, "max" => $max);
     $collection->db->command($command);
   }
-  $collection->insert($event);
+  $collection->insert($event, 'safe' => TRUE);
 }
 
 /**
