diff --git a/channels/nickname.go b/channels/nickname.go
index a7dfb45215111396617944ca19fc233aa7246c0e..71523d87e0df4933c41289ab3d306ed109fb8725 100644
--- a/channels/nickname.go
+++ b/channels/nickname.go
@@ -35,12 +35,13 @@ func loadOrNewNicknameManager(kv *versioned.KV) *nicknameManager {
 		jww.FATAL.Panicf("Failed to load nicknameManager: %+v", err)
 	}
 
-	return nm, nil
+	return nm
 
 }
 
 // GetNickname returns the nickname for the given channel if it exists
-func (nm *nicknameManager) GetNickname(ch *id.ID) (nickname string, exists bool) {
+func (nm *nicknameManager) GetNickname(ch *id.ID) (
+	nickname string, exists bool) {
 	nm.mux.RLock()
 	defer nm.mux.RUnlock()
 
@@ -59,21 +60,39 @@ func (nm *nicknameManager) SetNickname(newNick string, ch *id.ID) error {
 	}
 
 	nm.byChannel[*ch] = newNick
-	return nil
+	return nm.save()
 }
 
 // DeleteNickname removes the nickname for a given channel, using the codename
 // for that channel instead
-func (nm *nicknameManager) DeleteNickname(ch *id.ID) {
+func (nm *nicknameManager) DeleteNickname(ch *id.ID) error {
 	nm.mux.Lock()
 	defer nm.mux.Unlock()
 
 	delete(nm.byChannel, *ch)
+
+	return nm.save()
+}
+
+// channelIDToNickname is a serialization structure. This is used by the save
+// and load functions to serialize the nicknameManager's byChannel map.
+type channelIDToNickname struct {
+	channelId id.ID
+	nickname  string
 }
 
-// save stores the nickname manager to disk. It must occur under the mux.
+// save stores the nickname manager to disk. The caller of this must
+// hold the mux.
 func (nm *nicknameManager) save() error {
-	data, err := json.Marshal(&nm.byChannel)
+	list := make([]channelIDToNickname, 0)
+	for chId, nickname := range nm.byChannel {
+		list = append(list, channelIDToNickname{
+			channelId: chId,
+			nickname:  nickname,
+		})
+	}
+
+	data, err := json.Marshal(list)
 	if err != nil {
 		return err
 	}
@@ -92,7 +111,19 @@ func (nm *nicknameManager) load() error {
 	if err != nil {
 		return err
 	}
-	return json.Unmarshal(obj.Data, &nm.byChannel)
+
+	list := make([]channelIDToNickname, 0)
+	err = json.Unmarshal(obj.Data, &list)
+	if err != nil {
+		return err
+	}
+
+	for i := range list {
+		current := list[i]
+		nm.byChannel[current.channelId] = current.nickname
+	}
+
+	return nil
 }
 
 // IsNicknameValid checks if a nickname is valid
@@ -104,4 +135,6 @@ func IsNicknameValid(nm string) error {
 	if len([]rune(nm)) > 24 {
 		return errors.New("nicknames must be 24 characters in length or less")
 	}
+
+	return nil
 }
diff --git a/channels/nickname_test.go b/channels/nickname_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..dc0cad8f05fd5a24d2e033160f308a23bab68e08
--- /dev/null
+++ b/channels/nickname_test.go
@@ -0,0 +1,79 @@
+package channels
+
+import (
+	"gitlab.com/elixxir/client/storage/versioned"
+	"gitlab.com/elixxir/ekv"
+	"gitlab.com/xx_network/primitives/id"
+	"strconv"
+	"testing"
+)
+
+// Unit test. Tests that once you set a nickname with SetNickname, you can
+// retrieve the nickname using GetNickname.
+func TestNicknameManager_SetGetNickname(t *testing.T) {
+	kv := versioned.NewKV(ekv.MakeMemstore())
+	nm := loadOrNewNicknameManager(kv)
+
+	for i := 0; i < numTests; i++ {
+		chId := id.NewIdFromUInt(uint64(i), id.User, t)
+		nickname := "nickname#" + strconv.Itoa(i)
+		err := nm.SetNickname(nickname, chId)
+		if err != nil {
+			t.Fatalf("SetNickname error when setting %s: %+v", nickname, err)
+		}
+
+		received, _ := nm.GetNickname(chId)
+		if received != nickname {
+			t.Fatalf("GetNickname did not return expected values."+
+				"\nExpected: %s"+
+				"\nReceived: %s", nickname, received)
+		}
+	}
+
+}
+
+// Error case: Tests that nicknameManager.GetNickname returns a false boolean
+// if no nickname has been set with the channel ID.
+func TestNicknameManager_GetNickname_Error(t *testing.T) {
+	kv := versioned.NewKV(ekv.MakeMemstore())
+	nm := loadOrNewNicknameManager(kv)
+
+	for i := 0; i < numTests; i++ {
+		chId := id.NewIdFromUInt(uint64(i), id.User, t)
+		_, exists := nm.GetNickname(chId)
+		if exists {
+			t.Fatalf("GetNickname expected error case: " +
+				"This should not retrieve nicknames for channel IDs " +
+				"that are not set.")
+		}
+	}
+}
+
+// Unit test. Check that once you SetNickname and DeleteNickname,
+// GetNickname returns a false boolean.
+func TestNicknameManager_DeleteNickname(t *testing.T) {
+	kv := versioned.NewKV(ekv.MakeMemstore())
+	nm := loadOrNewNicknameManager(kv)
+
+	for i := 0; i < numTests; i++ {
+		chId := id.NewIdFromUInt(uint64(i), id.User, t)
+		nickname := "nickname#" + strconv.Itoa(i)
+		err := nm.SetNickname(nickname, chId)
+		if err != nil {
+			t.Fatalf("SetNickname error when setting %s: %+v", nickname, err)
+		}
+
+		err = nm.DeleteNickname(chId)
+		if err != nil {
+			t.Fatalf("DeleteNickname error: %+v", err)
+		}
+
+		_, exists := nm.GetNickname(chId)
+		if exists {
+			t.Fatalf("GetNickname expected error case: " +
+				"This should not retrieve nicknames for channel IDs " +
+				"that are not set.")
+		}
+	}
+
+}