diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c
index 8f540cf6be5dcaf9f5b83caa5d6086e11224cd74..c070e7dbcebd041e798ad9c7b36129a12aadbac7 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -317,14 +317,6 @@ int ast_sip_location_update_contact(struct ast_sip_contact *contact)
 
 int ast_sip_location_delete_contact(struct ast_sip_contact *contact)
 {
-	void *contact_status_obj;
-
-	contact_status_obj = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact));
-	if (contact_status_obj) {
-		ast_sorcery_delete(ast_sip_get_sorcery(), contact_status_obj);
-		ao2_ref(contact_status_obj, -1);
-	}
-
 	return ast_sorcery_delete(ast_sip_get_sorcery(), contact);
 }
 
@@ -389,7 +381,7 @@ static int permanent_uri_handler(const struct aco_option *opt, struct ast_variab
 		struct ast_sip_contact *contact;
 		struct ast_sip_contact_status *status;
 		char hash[33];
-		char contact_id[strlen(aor_id) + sizeof(hash) + 2 + 1];
+		char contact_id[strlen(aor_id) + sizeof(hash) + 2];
 
 		if (!aor->permanent_contacts) {
 			aor->permanent_contacts = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
@@ -406,6 +398,8 @@ static int permanent_uri_handler(const struct aco_option *opt, struct ast_variab
 			return -1;
 		}
 
+		ast_string_field_set(contact, uri, contact_uri);
+
 		status = ast_res_pjsip_find_or_create_contact_status(contact);
 		if (!status) {
 			ao2_ref(contact, -1);
@@ -413,7 +407,6 @@ static int permanent_uri_handler(const struct aco_option *opt, struct ast_variab
 		}
 		ao2_ref(status, -1);
 
-		ast_string_field_set(contact, uri, contact_uri);
 		ao2_link(aor->permanent_contacts, contact);
 		ao2_ref(contact, -1);
 	}
@@ -1031,7 +1024,7 @@ int ast_sip_initialize_sorcery_location(void)
 	 * Note that this must done here, as contacts will create the contact_status
 	 * object before PJSIP options handling is initialized.
 	 */
-	for (i = 0; i < REMOVED; i++) {
+	for (i = 0; i <= REMOVED; i++) {
 		ast_statsd_log_full_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE, 0, 1.0, ast_sip_get_contact_status_label(i));
 	}
 
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 30e56749bffb74cbfacdf339e77059f08661ea3f..3bb086945172c52af7b3b4278d07593b6166f16a 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -20,6 +20,7 @@
 #include "asterisk/sorcery.h"
 #include "asterisk/callerid.h"
 #include "asterisk/test.h"
+#include "asterisk/statsd.h"
 
 /*! \brief Number of buckets for persistent endpoint information */
 #define PERSISTENT_BUCKETS 53
@@ -161,20 +162,21 @@ static void persistent_endpoint_contact_deleted_observer(const void *object)
 	const struct ast_sip_contact *contact = object;
 	struct ast_sip_contact_status *contact_status;
 
-	contact_status = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
-		ast_sorcery_object_get_id(contact));
+	contact_status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact));
 	if (!contact_status) {
 		ast_log(LOG_ERROR, "Unable to create ast_sip_contact_status for contact %s/%s\n",
 			contact->aor, contact->uri);
 		return;
 	}
-	ast_string_field_set(contact_status, uri, contact->uri);
-
-	contact_status->status = REMOVED;
 
 	ast_verb(1, "Contact %s/%s has been deleted\n", contact->aor, contact->uri);
+	ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
+		"-1", 1.0, ast_sip_get_contact_status_label(contact_status->status));
+	ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
+		"+1", 1.0, ast_sip_get_contact_status_label(REMOVED));
 
 	ao2_callback(persistent_endpoints, OBJ_NODATA, persistent_endpoint_update_state, contact_status);
+	ast_sorcery_delete(ast_sip_get_sorcery(), contact_status);
 	ao2_cleanup(contact_status);
 }
 
@@ -194,24 +196,31 @@ static void persistent_endpoint_contact_status_observer(const void *object)
 		return;
 	}
 
-	if (contact_status->status == contact_status->last_status) {
-		ast_debug(3, "Contact %s/%s status didn't change: %s, RTT: %.3f msec\n",
-			contact_status->aor, contact_status->uri, ast_sip_get_contact_status_label(contact_status->status),
-			contact_status->rtt / 1000.0);
-		return;
-	} else {
+	if (contact_status->status != contact_status->last_status) {
 		ast_verb(1, "Contact %s/%s is now %s.  RTT: %.3f msec\n", contact_status->aor, contact_status->uri,
 			ast_sip_get_contact_status_label(contact_status->status),
 			contact_status->rtt / 1000.0);
-	}
 
-	ast_test_suite_event_notify("AOR_CONTACT_UPDATE",
-		"Contact: %s\r\n"
-			"Status: %s",
-		ast_sorcery_object_get_id(contact_status),
-		ast_sip_get_contact_status_label(contact_status->status));
+		ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
+			"-1", 1.0, ast_sip_get_contact_status_label(contact_status->last_status));
+		ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
+			"+1", 1.0, ast_sip_get_contact_status_label(contact_status->status));
 
-	ao2_callback(persistent_endpoints, OBJ_NODATA, persistent_endpoint_update_state, contact_status);
+		ast_test_suite_event_notify("AOR_CONTACT_UPDATE",
+			"Contact: %s\r\n"
+				"Status: %s",
+			ast_sorcery_object_get_id(contact_status),
+			ast_sip_get_contact_status_label(contact_status->status));
+
+		ao2_callback(persistent_endpoints, OBJ_NODATA, persistent_endpoint_update_state, contact_status);
+	} else {
+		ast_debug(3, "Contact %s/%s status didn't change: %s, RTT: %.3f msec\n",
+			contact_status->aor, contact_status->uri, ast_sip_get_contact_status_label(contact_status->status),
+			contact_status->rtt / 1000.0);
+	}
+
+	ast_statsd_log_full_va("PJSIP.contacts.%s.rtt", AST_STATSD_TIMER,
+		contact_status->status != AVAILABLE ? -1 : contact_status->rtt / 1000, 1.0, ast_sorcery_object_get_id(contact_status));
 }
 
 /*! \brief Observer for contacts so state can be updated on respective endpoints */
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 6762b754e4a91fed935a19cfefcf30b5647564a9..089703b2690e33c6cd2fc881e13ed3562fed6876 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -174,22 +174,13 @@ static void update_contact_status(const struct ast_sip_contact *contact,
 	ast_string_field_set(update, uri, contact->uri);
 	update->last_status = status->status;
 	update->status = value;
-	if (update->last_status != update->status) {
-		ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
-			"-1", 1.0, ast_sip_get_contact_status_label(update->last_status));
-		ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
-			"+1", 1.0, ast_sip_get_contact_status_label(update->status));
-	}
 
 	/* if the contact is available calculate the rtt as
 	   the diff between the last start time and "now" */
 	update->rtt = update->status == AVAILABLE && status->rtt_start.tv_sec > 0 ?
 		ast_tvdiff_us(ast_tvnow(), status->rtt_start) : 0;
-
 	update->rtt_start = ast_tv(0, 0);
 
-	ast_statsd_log_full_va("PJSIP.contacts.%s.rtt", AST_STATSD_TIMER,
-		update->rtt / 1000, 1.0, ast_sorcery_object_get_id(update));
 	ast_test_suite_event_notify("AOR_CONTACT_QUALIFY_RESULT",
 		"Contact: %s\r\n"
 		"Status: %s\r\n"