diff --git a/i18n_string/i18n_string.inc b/i18n_string/i18n_string.inc
index 3136aad..691b439 100644
--- a/i18n_string/i18n_string.inc
+++ b/i18n_string/i18n_string.inc
@@ -28,7 +28,7 @@ class i18n_string_object {
   // Properties from metadata
   public $title;
   // Array of translations to multiple languages
-  public $translations;
+  public $translations = array();
   // Textgroup object
   protected $_textgroup;
 
@@ -39,7 +39,54 @@ class i18n_string_object {
     if ($data) {
       $this->set_properties($data);
     }
+    $this->rebuild_from_cache($data);
   }
+
+  /**
+   * Rebuild the object data based on the persistent cache.
+   */
+  protected function rebuild_from_cache($data = NULL) {
+    // Check if we've the required information to repopulate the cache and do so
+    // if possible.
+    $meta_data_exist = isset($this->textgroup) && isset($this->type) && isset($this->objectid) && isset($this->property);
+    if ($meta_data_exist && ($cache = cache_get($this->get_cid())) && !empty($cache->data)) {
+      // Re-spawn the cached data.
+      // @TODO do we need a array_diff to ensure we don't overwrite the data
+      // provided by the $data parameter?
+      $this->set_properties($cache->data);
+    }
+  }
+
+  /**
+   * Class destructor.
+   *
+   * Updates the persistent cache.
+   */
+  public function __destruct() {
+    // Store only the public visible data into the persistent cache.
+    cache_set($this->get_cid(), call_user_func('get_object_vars', $this), 'cache', CACHE_TEMPORARY);
+  }
+
+  /**
+   * Reset cache, needed for tests.
+   */
+  public function cache_reset() {
+    $this->translations = array();
+
+    // Reset the persistent translations cache of this object.
+    cache_clear_all($this->get_cid(), 'cache', TRUE);
+  }
+
+  /**
+   * Returns the caching id for this object.
+   *
+   * @return string
+   *   The caching id.
+   */
+  public function get_cid() {
+    return 'i18n:string:obj:' . $this->get_name();
+  }
+
   /**
    * Get message parameters from context and string.
    */
@@ -63,6 +110,10 @@ class i18n_string_object {
     $this->objectkey = (int)$this->objectid;
     // Remaining elements glued again with ':'
     $this->property = $parts ? implode(':', $parts) : '';
+
+    // Ensure persistent cached data are set.
+    $this->rebuild_from_cache();
+
     return $this;
   }
   /**
@@ -279,9 +330,9 @@ class i18n_string_textgroup_default {
   // Debug flag, set to true to print out more information.
   public $debug;
   // Cached or preloaded string objects
-  public $strings;
+  public $strings = array();
   // Multiple translations search map
-  protected $cache_multiple;
+  protected $cache_multiple = array();
 
   /**
    * Class constructor.
@@ -293,7 +344,43 @@ class i18n_string_textgroup_default {
   public function __construct($textgroup) {
     $this->textgroup = $textgroup;
     $this->debug = variable_get('i18n_string_debug', FALSE) || variable_get('i18n_string_debug_' . $textgroup, FALSE);
+
+    // Fetch persistent caches, the persistent caches contain only metadata.
+    // Those metadata are processed by the related cache_get() methods.
+    foreach (array('cache_multiple', 'strings') as $caches_type) {
+      if (($cache = cache_get('i18n:string:tgroup:' . $caches_type . ':' . $this->textgroup)) && !empty($cache->data)) {
+        $this->{$caches_type} = $cache->data;
+      }
+    }
+  }
+
+  /**
+   * Class destructor.
+   *
+   * Updates the persistent caches for the next usage.
+   */
+  public function __destruct() {
+    // Reduce size to cache by removing NULL values.
+    $this->strings = array_filter($this->strings);
+
+    // Store the persistent caches. We just store the metadata the translations
+    // are stored by the string object itself. However storing the metadata
+    // reduces the number of DB queries executed during runtime.
+    $cache_data = array();
+    foreach ($this->strings as $context => $i18n_string_object) {
+      $cache_data[$context] = $context;
+    }
+    cache_set('i18n:string:tgroup:strings:' . $this->textgroup, $cache_data, 'cache', CACHE_TEMPORARY);
+
+    $cache_data = array();
+    foreach ($this->cache_multiple as $pattern => $strings) {
+      foreach ($this->strings as $context => $i18n_string_object) {
+        $cache_data[$pattern][$context] = $context;
+      }
+    }
+    cache_set('i18n:string:tgroup:cache_multiple:' . $this->textgroup, $cache_data, 'cache', CACHE_TEMPORARY);
   }
+
   /**
    * Build string object
    *
@@ -455,6 +542,9 @@ class i18n_string_textgroup_default {
    *   SAVED_DELETED | FALSE (If the operation failed because no source)
    */
   public function string_remove($i18nstring, $options = array()) {
+    // Flush cache right away.
+    cache_clear_all($i18nstring->get_cid(), 'cache', TRUE);
+
     $options += array('watchdog' => TRUE, 'messages' => $this->debug);
     if ($source = $i18nstring->get_source()) {
       db_delete('locales_target')->condition('lid', $source->lid)->execute();
@@ -510,6 +600,10 @@ class i18n_string_textgroup_default {
    *   SAVED_UPDATED | SAVED_NEW | SAVED_DELETED | FALSE (If the string is to be removed but has no source)
    */
   public function string_update($i18nstring, $options = array()) {
+
+    // Flush cache right away.
+    cache_clear_all($i18nstring->get_cid(), 'cache', TRUE);
+
     $options += array('watchdog' => TRUE, 'messages' => $this->debug, 'check' => TRUE);
     if ((!$options['check'] || $this->string_check($i18nstring, $options)) && $i18nstring->get_string()) {
       // String is ok, has a value so we store it into the database.
@@ -557,7 +651,16 @@ class i18n_string_textgroup_default {
    * Get translation from cache
    */
   protected function cache_get($context) {
-    return isset($this->strings[$context]) ? $this->strings[$context] : NULL;
+    if (isset($this->strings[$context])) {
+      // If the cache contains a string re-build i18n_string_object.
+      if (is_string($this->strings[$context])) {
+        $i8n_string_object = new i18n_string_object(array('textgroup' => $this->textgroup));
+        $i8n_string_object->set_context($context);
+        $this->strings[$context] = $i8n_string_object;
+      }
+      return $this->strings[$context];
+    }
+    return NULL;
   }
 
   /**
@@ -566,7 +669,14 @@ class i18n_string_textgroup_default {
   public function cache_reset() {
     $this->strings = array();
     $this->string_format = array();
-    $this->translations = array();
+
+    // Reset the persistent caches.
+    foreach (array('strings', 'cache_multiple') as $caches_type) {
+      cache_clear_all('i18n:string:tgroup:' . $caches_type . ':' . $this->textgroup, 'cache', TRUE);
+    }
+    // Reset the complete string object cache too.
+    cache_clear_all('i18n:string:obj:', 'cache', TRUE);
+
   }
 
   /**
@@ -613,7 +723,7 @@ class i18n_string_textgroup_default {
   public static function load_translation($i18nstring, $langcode) {
     // Search the database using lid if we've got it or textgroup, context otherwise
     if (!empty($i18nstring->lid)) {
-      // We've alreay got lid, we just need translation data
+      // We've already got lid, we just need translation data
       $query = db_select('locales_target', 't');
       $query->condition('t.lid', $i18nstring->lid);
     }
@@ -930,6 +1040,14 @@ class i18n_string_textgroup_default {
   protected function multiple_cache_get($context) {
     $cache_key = implode(':', $context);
     if (isset($this->cache_multiple[$cache_key])) {
+      // Ensure the values from the persistent cache are properly re-build
+      foreach ($this->cache_multiple[$cache_key] as $context) {
+        if (is_string($context)) {
+          $i8n_string_object = new i18n_string_object(array('textgroup' => $this->textgroup));
+          $i8n_string_object->set_context($context);
+          $this->cache_multiple[$cache_key][$context] = $i8n_string_object;
+        }
+      }
       return $this->cache_multiple[$cache_key];
     }
     else {
diff --git a/i18n_string/i18n_string.pages.inc b/i18n_string/i18n_string.pages.inc
index 28005d6..eb4d8b6 100644
--- a/i18n_string/i18n_string.pages.inc
+++ b/i18n_string/i18n_string.pages.inc
@@ -398,6 +398,8 @@ function i18n_string_locale_translate_edit_form_submit($form, &$form_state) {
   // Invoke locale submission.
   locale_translate_edit_form_submit($form, $form_state);
   $lid = $form_state['values']['lid'];
+  $i18n_string_object = i18n_string_get_by_lid($lid);
+  $i18n_string_object->cache_reset();
   foreach ($form_state['values']['translations'] as $key => $value) {
     if (!empty($value)) {
       // An update has been made, so we assume the translation is now current.
